修正查看特权
This commit is contained in:
@@ -8,6 +8,8 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
@@ -16,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@@ -26,6 +29,30 @@ public class LbPurchaseApplyController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ILbPurchaseApplyService lbPurchaseApplyService;
|
private ILbPurchaseApplyService lbPurchaseApplyService;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Schema(description = "按用户ID批量开通或关闭 hxrd 用户特权请求体")
|
||||||
|
public static class UpdateHxrAdminUserVipRequest {
|
||||||
|
@Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotBlank(message = "租户id不能为空")
|
||||||
|
private String tenantId;
|
||||||
|
|
||||||
|
@Schema(description = "hxrd 后台用户 ID 列表", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotEmpty(message = "用户id列表不能为空")
|
||||||
|
private List<Long> userIds;
|
||||||
|
|
||||||
|
@Schema(description = "是否会员:1 开通特权,0 关闭特权", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "isVip不能为空")
|
||||||
|
private Integer isVip;
|
||||||
|
|
||||||
|
@Schema(description = "特权结束时间,格式 yyyy-MM-dd HH:mm:ss;开通时必填")
|
||||||
|
private String vipTime;
|
||||||
|
|
||||||
|
@Schema(description = "最大订单数 max_order;传 0 时不向第三方提交该字段,保持原值",
|
||||||
|
requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@NotNull(message = "maxOrder不能为空")
|
||||||
|
private Integer maxOrder;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "大模型解析订货信息请求体")
|
@Schema(description = "大模型解析订货信息请求体")
|
||||||
public static class ParseOrderInfoRequest {
|
public static class ParseOrderInfoRequest {
|
||||||
@@ -131,6 +158,24 @@ public class LbPurchaseApplyController {
|
|||||||
return ResponseEntity.badRequest().body(result);
|
return ResponseEntity.badRequest().body(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/updateHxrAdminUserVipByUserIds")
|
||||||
|
@Operation(summary = "按用户ID列表批量开通或关闭 hxrd 用户特权",
|
||||||
|
description = "根据入参 userIds 逐条调用 POST /app/admin/user/update,"
|
||||||
|
+ "不计算 viptime,直接使用请求体中的 vipTime、maxOrder、isVip(1 开通,0 关闭);"
|
||||||
|
+ "maxOrder 为 0 时不传 max_order,不修改第三方该字段。"
|
||||||
|
+ "需配置 hxr.admin.cookie 或 hxr.admin.phpsid。")
|
||||||
|
public ResponseEntity<Map<String, Object>> updateHxrAdminUserVipByUserIds(
|
||||||
|
@Parameter(description = "租户、用户列表及特权参数", required = true)
|
||||||
|
@Valid @RequestBody UpdateHxrAdminUserVipRequest body) {
|
||||||
|
Map<String, Object> result = lbPurchaseApplyService.updateHxrAdminUserVipByUserIds(
|
||||||
|
body.getTenantId(), body.getUserIds(), body.getIsVip(), body.getVipTime(), body.getMaxOrder());
|
||||||
|
Boolean success = (Boolean) result.get("success");
|
||||||
|
if (success != null && success) {
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
return ResponseEntity.badRequest().body(result);
|
||||||
|
}
|
||||||
|
|
||||||
@GetMapping("/syncHxrAdminColleagueVip")
|
@GetMapping("/syncHxrAdminColleagueVip")
|
||||||
@Operation(summary = "按申请日期与租户同步同事 hxrd 用户 VIP",
|
@Operation(summary = "按申请日期与租户同步同事 hxrd 用户 VIP",
|
||||||
description = "根据 lb_purchase_apply 的申请日期区间与 tenant_id 逐条处理,"
|
description = "根据 lb_purchase_apply 的申请日期区间与 tenant_id 逐条处理,"
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ public class HxrAdminUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页拉取用户列表,{@code data} 解析为 {@link LbUser}(与 lb_user 字段对应)。
|
* 分页拉取用户列表,{@code data} 解析为 {@link }(与 lb_user 字段对应)。
|
||||||
*
|
*
|
||||||
* @param page 页码,从 1 开始
|
* @param page 页码,从 1 开始
|
||||||
*/
|
*/
|
||||||
@@ -225,13 +225,25 @@ public class HxrAdminUserService {
|
|||||||
* @return 接口 {@code code==0} 时为 true
|
* @return 接口 {@code code==0} 时为 true
|
||||||
*/
|
*/
|
||||||
public boolean updateUserVipFields(long userId, int maxOrder, String viptimeFormatted) throws Exception {
|
public boolean updateUserVipFields(long userId, int maxOrder, String viptimeFormatted) throws Exception {
|
||||||
|
return updateUserVipFields(userId, maxOrder, viptimeFormatted, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户 VIP 相关字段({@code application/x-www-form-urlencoded})。
|
||||||
|
*
|
||||||
|
* @param maxOrder 为 null 时不传 max_order,第三方保持原值
|
||||||
|
* @param isVip 1 开通特权,0 关闭特权
|
||||||
|
* @return 接口 {@code code==0} 时为 true
|
||||||
|
*/
|
||||||
|
public boolean updateUserVipFields(long userId, Integer maxOrder, String viptimeFormatted, int isVip)
|
||||||
|
throws Exception {
|
||||||
String cookieHeader = properties.resolveCookieHeader();
|
String cookieHeader = properties.resolveCookieHeader();
|
||||||
if (cookieHeader == null || cookieHeader.isBlank()) {
|
if (cookieHeader == null || cookieHeader.isBlank()) {
|
||||||
log.warn("hxr.admin 未配置 cookie 或 phpsid,跳过 user/update");
|
log.warn("hxr.admin 未配置 cookie 或 phpsid,跳过 user/update");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String form = buildUpdateFormBody(userId, maxOrder, viptimeFormatted);
|
String form = buildUpdateFormBody(userId, maxOrder, viptimeFormatted, isVip);
|
||||||
|
|
||||||
HttpClient client = HttpClient.newBuilder()
|
HttpClient client = HttpClient.newBuilder()
|
||||||
.connectTimeout(java.time.Duration.ofSeconds(35))
|
.connectTimeout(java.time.Duration.ofSeconds(35))
|
||||||
@@ -275,13 +287,19 @@ public class HxrAdminUserService {
|
|||||||
return t.format(VIP_TIME_FORMAT);
|
return t.format(VIP_TIME_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String buildUpdateFormBody(long userId, int maxOrder, String viptimeFormatted) {
|
private static String buildUpdateFormBody(long userId, Integer maxOrder, String viptimeFormatted, int isVip) {
|
||||||
return "id=" + userId
|
int vipFlag = isVip == 1 ? 1 : 0;
|
||||||
+ "&max_order=" + maxOrder
|
String viptime = viptimeFormatted != null ? viptimeFormatted : "";
|
||||||
+ "&is_vip=1"
|
StringBuilder form = new StringBuilder();
|
||||||
+ "&is_resell=1"
|
form.append("id=").append(userId);
|
||||||
+ "&status=1"
|
if (maxOrder != null) {
|
||||||
+ "&viptime=" + URLEncoder.encode(viptimeFormatted, StandardCharsets.UTF_8);
|
form.append("&max_order=").append(maxOrder);
|
||||||
|
}
|
||||||
|
form.append("&is_vip=").append(vipFlag)
|
||||||
|
.append("&is_resell=1")
|
||||||
|
.append("&status=1")
|
||||||
|
.append("&viptime=").append(URLEncoder.encode(viptime, StandardCharsets.UTF_8));
|
||||||
|
return form.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String abbreviate(String s, int maxLen) {
|
private static String abbreviate(String s, int maxLen) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.rj.entity.LbPurchaseApply;
|
|||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface ILbPurchaseApplyService extends IService<LbPurchaseApply> {
|
public interface ILbPurchaseApplyService extends IService<LbPurchaseApply> {
|
||||||
@@ -34,6 +35,12 @@ public interface ILbPurchaseApplyService extends IService<LbPurchaseApply> {
|
|||||||
Map<String, Object> syncHxrAdminUserVipByApplyDateRange(
|
Map<String, Object> syncHxrAdminUserVipByApplyDateRange(
|
||||||
LocalDate applyDateStart, LocalDate applyDateEnd, String tenantId, Integer maxOrder);
|
LocalDate applyDateStart, LocalDate applyDateEnd, String tenantId, Integer maxOrder);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按用户 ID 列表批量调用 hxrd 用户更新接口,开通或关闭特权(不计算 viptime,使用入参)。
|
||||||
|
*/
|
||||||
|
Map<String, Object> updateHxrAdminUserVipByUserIds(
|
||||||
|
String tenantId, List<Long> userIds, Integer isVip, String vipTime, Integer maxOrder);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按申请日期区间与租户筛选进货申请,对每条记录的 {@code colleague_phone} 调用 hxrd 用户查询与更新,
|
* 按申请日期区间与租户筛选进货申请,对每条记录的 {@code colleague_phone} 调用 hxrd 用户查询与更新,
|
||||||
* 仅当 {@code colleague_name} 能在 {@code lb_daily_user_trade}(同租户、按 nickname)中查到时才开通;
|
* 仅当 {@code colleague_name} 能在 {@code lb_daily_user_trade}(同租户、按 nickname)中查到时才开通;
|
||||||
|
|||||||
@@ -464,7 +464,7 @@ public class LbPurchaseApplyServiceImpl
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 按租户 + 手机号关联 {@link LbUser}:申请人 {@code applyPhone}、推荐人 {@code colleaguePhone} 分别对应
|
* 按租户 + 手机号关联 {@link LbUser}:申请人 {@code applyPhone}、推荐人 {@code colleaguePhone} 分别对应
|
||||||
* {@link LbPurchaseApply#applicantUser}、{@link LbPurchaseApply#referrerUser}(仅返回脱敏后的用户字段)。
|
* {@link LbPurchaseApply#}、{@link LbPurchaseApply#}(仅返回脱敏后的用户字段)。
|
||||||
*/
|
*/
|
||||||
private void fillLinkedLbUsers(List<LbPurchaseApply> records) {
|
private void fillLinkedLbUsers(List<LbPurchaseApply> records) {
|
||||||
if (records == null || records.isEmpty()) {
|
if (records == null || records.isEmpty()) {
|
||||||
@@ -521,6 +521,7 @@ public class LbPurchaseApplyServiceImpl
|
|||||||
view.setTodayBuyTotal(source.getTodayBuyTotal());
|
view.setTodayBuyTotal(source.getTodayBuyTotal());
|
||||||
view.setTodaySellTotal(source.getTodaySellTotal());
|
view.setTodaySellTotal(source.getTodaySellTotal());
|
||||||
view.setJoinTime(source.getJoinTime());
|
view.setJoinTime(source.getJoinTime());
|
||||||
|
view.setMaxOrder(source.getMaxOrder());
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -733,6 +734,93 @@ public class LbPurchaseApplyServiceImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> updateHxrAdminUserVipByUserIds(
|
||||||
|
String tenantId, List<Long> userIds, Integer isVip, String vipTime, Integer maxOrder) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
try {
|
||||||
|
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "租户id不能为空");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (userIds == null || userIds.isEmpty()) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "用户id列表不能为空");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (isVip == null || (isVip != 0 && isVip != 1)) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "isVip 必须为 0 或 1");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
if (maxOrder == null) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "maxOrder不能为空");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
String vipTimeStr = vipTime != null ? vipTime.trim() : "";
|
||||||
|
if (isVip == 1 && vipTimeStr.isEmpty()) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "开通特权时 vipTime 不能为空");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> details = new ArrayList<>();
|
||||||
|
int ok = 0;
|
||||||
|
int fail = 0;
|
||||||
|
for (Long userId : userIds) {
|
||||||
|
Map<String, Object> one = new HashMap<>();
|
||||||
|
one.put("userId", userId);
|
||||||
|
one.put("isVip", isVip);
|
||||||
|
one.put("viptime", vipTimeStr);
|
||||||
|
one.put("maxOrder", maxOrder);
|
||||||
|
if (userId == null) {
|
||||||
|
one.put("success", false);
|
||||||
|
one.put("message", "用户id为空,跳过");
|
||||||
|
fail++;
|
||||||
|
details.add(one);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Integer maxOrderForApi = maxOrder == 0 ? null : maxOrder;
|
||||||
|
boolean updated =
|
||||||
|
hxrAdminUserService.updateUserVipFields(userId, maxOrderForApi, vipTimeStr, isVip);
|
||||||
|
if (updated) {
|
||||||
|
one.put("success", true);
|
||||||
|
one.put("message", "user/update 成功");
|
||||||
|
ok++;
|
||||||
|
} else {
|
||||||
|
one.put("success", false);
|
||||||
|
one.put("message", "user/update 失败");
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
one.put("success", false);
|
||||||
|
one.put("message", "调用异常:" + ex.getMessage());
|
||||||
|
fail++;
|
||||||
|
}
|
||||||
|
details.add(one);
|
||||||
|
}
|
||||||
|
|
||||||
|
result.put("success", fail == 0);
|
||||||
|
result.put("message", fail == 0 ? "全部处理成功" : "部分或全部失败,见 details");
|
||||||
|
result.put("totalRecords", userIds.size());
|
||||||
|
result.put("successCount", ok);
|
||||||
|
result.put("failCount", fail);
|
||||||
|
result.put("isVip", isVip);
|
||||||
|
result.put("vipTime", vipTimeStr);
|
||||||
|
result.put("maxOrder", maxOrder);
|
||||||
|
result.put("details", details);
|
||||||
|
result.put("tenantId", tenantId.trim());
|
||||||
|
return result;
|
||||||
|
} catch (Exception e) {
|
||||||
|
result.put("success", false);
|
||||||
|
result.put("message", "处理异常:" + e.getMessage());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> syncHxrAdminColleagueVipByApplyDateRange(
|
public Map<String, Object> syncHxrAdminColleagueVipByApplyDateRange(
|
||||||
LocalDate applyDateStart, LocalDate applyDateEnd, String tenantId) {
|
LocalDate applyDateStart, LocalDate applyDateEnd, String tenantId) {
|
||||||
|
|||||||
Reference in New Issue
Block a user