用户同步
This commit is contained in:
@@ -53,7 +53,7 @@ public class HxrAdminProperties {
|
||||
* 用户列表接口 URL(可含默认查询串);实际请求会覆盖 {@code mobile} 等参数。
|
||||
*/
|
||||
private String userSelectUrl =
|
||||
"https://hxrdhoutai.hxrdsm.cn/app/admin/user/select?page=1&limit=20";
|
||||
"https://hxrdhoutai.hxrdsm.cn/app/admin/user/select?page=1&limit=90";
|
||||
|
||||
/**
|
||||
* 用户更新接口 URL。
|
||||
|
||||
@@ -60,7 +60,6 @@ public class MybatisPlusConfig {
|
||||
ignoreTables.add("industry_tags"); // 行业标签(示例:如认为是公共字典)
|
||||
ignoreTables.add("menu"); // 菜单表(不需要租户隔离)
|
||||
ignoreTables.add("ai_prompts"); // AI 提示词全局配置,表无 tenant_id 字段
|
||||
ignoreTables.add("lb_user"); // LB 用户表,表无 tenant_id 字段
|
||||
|
||||
return new TenantLineHandler() {
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ public class LbUserController {
|
||||
public ResponseEntity<Map<String, Object>> list(
|
||||
@RequestParam(defaultValue = "1") Integer current,
|
||||
@RequestParam(defaultValue = "10") Integer size,
|
||||
@RequestParam(required = false) String tenantId,
|
||||
@RequestParam(required = false) Long pid,
|
||||
@RequestParam(required = false) String username,
|
||||
@RequestParam(required = false) String nickname,
|
||||
@@ -94,6 +95,7 @@ public class LbUserController {
|
||||
lbUserService.pageQuery(
|
||||
current,
|
||||
size,
|
||||
tenantId,
|
||||
pid,
|
||||
username,
|
||||
nickname,
|
||||
@@ -117,4 +119,20 @@ public class LbUserController {
|
||||
}
|
||||
return ResponseEntity.internalServerError().body(result);
|
||||
}
|
||||
|
||||
@PostMapping("/sync-from-hxr")
|
||||
@Operation(
|
||||
summary = "从 hxrd 后台同步用户",
|
||||
description =
|
||||
"分页调用 /app/admin/user/select(每页 limit=90),将 data 解析为 LbUser 后立即 upsert 到 lb_user;"
|
||||
+ "需配置 hxr.admin.cookie 或 phpsid")
|
||||
public ResponseEntity<Map<String, Object>> syncFromHxr(
|
||||
@Parameter(description = "租户 id", required = true) @RequestParam String tenantId) {
|
||||
Map<String, Object> result = lbUserService.syncFromHxrAdmin(tenantId);
|
||||
Boolean success = (Boolean) result.get("success");
|
||||
if (success != null && success) {
|
||||
return ResponseEntity.ok(result);
|
||||
}
|
||||
return ResponseEntity.badRequest().body(result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.rj.dto.hxr;
|
||||
|
||||
import com.rj.entity.LbUser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** hxrd 后台 {@code /app/admin/user/select} 顶层 JSON,{@code data} 解析为 {@link LbUser}。 */
|
||||
public record HxrLbUserSelectResponse(int code, String msg, int count, List<LbUser> data) {}
|
||||
@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
@@ -17,6 +19,7 @@ import java.time.LocalDateTime;
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableName("lb_user")
|
||||
@Schema(description = "LB 用户表")
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class LbUser implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -25,6 +28,10 @@ public class LbUser implements Serializable {
|
||||
@Schema(description = "用户ID(外部系统主键)")
|
||||
private Long id;
|
||||
|
||||
@TableField("tenant_id")
|
||||
@Schema(description = "租户ID")
|
||||
private String tenantId;
|
||||
|
||||
@TableField("pid")
|
||||
@Schema(description = "上级用户ID")
|
||||
private Long pid;
|
||||
@@ -67,6 +74,7 @@ public class LbUser implements Serializable {
|
||||
|
||||
@TableField("birthday")
|
||||
@Schema(description = "生日")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private LocalDate birthday;
|
||||
|
||||
@TableField("money")
|
||||
@@ -91,6 +99,7 @@ public class LbUser implements Serializable {
|
||||
|
||||
@TableField("last_time")
|
||||
@Schema(description = "最后登录时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime lastTime;
|
||||
|
||||
@TableField("last_ip")
|
||||
@@ -99,6 +108,7 @@ public class LbUser implements Serializable {
|
||||
|
||||
@TableField("join_time")
|
||||
@Schema(description = "注册时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime joinTime;
|
||||
|
||||
@TableField("join_ip")
|
||||
@@ -111,10 +121,12 @@ public class LbUser implements Serializable {
|
||||
|
||||
@TableField("created_at")
|
||||
@Schema(description = "创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
@TableField("updated_at")
|
||||
@Schema(description = "更新时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
@TableField("status")
|
||||
@@ -123,6 +135,7 @@ public class LbUser implements Serializable {
|
||||
|
||||
@TableField("viptime")
|
||||
@Schema(description = "VIP到期时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime viptime;
|
||||
|
||||
@TableField("is_vip")
|
||||
|
||||
@@ -3,7 +3,15 @@ package com.rj.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.rj.entity.LbUser;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface LbUserMapper extends BaseMapper<LbUser> {
|
||||
|
||||
/**
|
||||
* 按用户 id 批量 upsert(同步外部用户数据)。
|
||||
*/
|
||||
int upsertBatch(@Param("list") List<LbUser> list);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package com.rj.service;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.rj.config.HxrAdminProperties;
|
||||
import com.rj.dto.hxr.HxrLbUserSelectResponse;
|
||||
import com.rj.dto.hxr.HxrSimpleApiResponse;
|
||||
import com.rj.dto.hxr.HxrUserRow;
|
||||
import com.rj.dto.hxr.HxrUserSelectResponse;
|
||||
@@ -33,10 +36,19 @@ import java.util.Optional;
|
||||
@RequiredArgsConstructor
|
||||
public class HxrAdminUserService {
|
||||
|
||||
/** 与后台 user/select 默认 limit 一致,用于判断是否还有下一页 */
|
||||
public static final int USER_SELECT_PAGE_SIZE = 90;
|
||||
|
||||
private static final ObjectMapper JSON = new ObjectMapper()
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
|
||||
private static final ObjectMapper USER_JSON = new ObjectMapper()
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.registerModule(new JavaTimeModule())
|
||||
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
|
||||
private static final DateTimeFormatter VIP_TIME_FORMAT =
|
||||
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@@ -89,6 +101,61 @@ public class HxrAdminUserService {
|
||||
return LocalDateTime.of(applyDate.plusDays(calendarDays), now.toLocalTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页拉取用户列表,{@code data} 解析为 {@link LbUser}(与 lb_user 字段对应)。
|
||||
*
|
||||
* @param page 页码,从 1 开始
|
||||
*/
|
||||
public Optional<HxrLbUserSelectResponse> fetchUserSelectPage(int page) throws Exception {
|
||||
String cookieHeader = properties.resolveCookieHeader();
|
||||
if (cookieHeader == null || cookieHeader.isBlank()) {
|
||||
log.warn("hxr.admin 未配置 cookie 或 phpsid,跳过 user/select");
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
String uri = UriComponentsBuilder.fromUriString(properties.getUserSelectUrl())
|
||||
.replaceQueryParam("page", Math.max(1, page))
|
||||
.replaceQueryParam("limit", USER_SELECT_PAGE_SIZE)
|
||||
.replaceQueryParam("mobile", "")
|
||||
.replaceQueryParam("id", "")
|
||||
.replaceQueryParam("pid", "")
|
||||
.build()
|
||||
.encode()
|
||||
.toUriString();
|
||||
|
||||
HttpClient client = HttpClient.newBuilder()
|
||||
.connectTimeout(java.time.Duration.ofSeconds(35))
|
||||
.followRedirects(HttpClient.Redirect.NORMAL)
|
||||
.build();
|
||||
|
||||
HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(URI.create(uri))
|
||||
.timeout(java.time.Duration.ofSeconds(120))
|
||||
.header("Accept", "application/json, text/javascript, */*; q=0.01")
|
||||
.header("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
|
||||
.header("Cookie", cookieHeader)
|
||||
.header("Priority", "u=1, i")
|
||||
.header("Referer", "https://hxrdhoutai.hxrdsm.cn/app/admin/user/index")
|
||||
.header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36 Edg/148.0.0.0")
|
||||
.GET()
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
int status = response.statusCode();
|
||||
if (status < 200 || status >= 300) {
|
||||
log.warn("hxr admin user/select HTTP {} page={} bodyPrefix={}",
|
||||
status, page, abbreviate(response.body(), 400));
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
HxrLbUserSelectResponse body = USER_JSON.readValue(response.body(), HxrLbUserSelectResponse.class);
|
||||
if (body.code() != 0) {
|
||||
log.warn("hxr admin user/select api code={} msg={} page={}", body.code(), body.msg(), page);
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用第三方接口
|
||||
* 按手机号查询用户列表,返回第一条。
|
||||
|
||||
@@ -16,6 +16,7 @@ public interface ILbUserService extends IService<LbUser> {
|
||||
Map<String, Object> pageQuery(
|
||||
Integer current,
|
||||
Integer size,
|
||||
String tenantId,
|
||||
Long pid,
|
||||
String username,
|
||||
String nickname,
|
||||
@@ -30,4 +31,9 @@ public interface ILbUserService extends IService<LbUser> {
|
||||
String joinTimeEnd,
|
||||
String updatedAtStart,
|
||||
String updatedAtEnd);
|
||||
|
||||
/**
|
||||
* 从 hxrd 后台 user/select 分页拉取全部用户并写入 lb_user(每页拉取后立即 upsert)。
|
||||
*/
|
||||
Map<String, Object> syncFromHxrAdmin(String tenantId);
|
||||
}
|
||||
|
||||
@@ -3,23 +3,37 @@ package com.rj.service.impl;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.rj.dto.hxr.HxrLbUserSelectResponse;
|
||||
import com.rj.entity.LbUser;
|
||||
import com.rj.mapper.LbUserMapper;
|
||||
import com.rj.service.HxrAdminUserService;
|
||||
import com.rj.service.ILbUserService;
|
||||
import com.rj.tenant.TenantContextHolder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.DateTimeParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class LbUserServiceImpl extends ServiceImpl<LbUserMapper, LbUser> implements ILbUserService {
|
||||
|
||||
private static final DateTimeFormatter DATETIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Autowired
|
||||
private HxrAdminUserService hxrAdminUserService;
|
||||
|
||||
@Override
|
||||
public Map<String, Object> add(LbUser entity) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
@@ -29,6 +43,12 @@ public class LbUserServiceImpl extends ServiceImpl<LbUserMapper, LbUser> impleme
|
||||
result.put("message", "id不能为空");
|
||||
return result;
|
||||
}
|
||||
if (entity.getTenantId() == null || entity.getTenantId().trim().isEmpty()) {
|
||||
result.put("success", false);
|
||||
result.put("message", "tenantId不能为空");
|
||||
return result;
|
||||
}
|
||||
entity.setTenantId(entity.getTenantId().trim());
|
||||
if (this.getById(entity.getId()) != null) {
|
||||
result.put("success", false);
|
||||
result.put("message", "该用户 id 已存在");
|
||||
@@ -107,6 +127,7 @@ public class LbUserServiceImpl extends ServiceImpl<LbUserMapper, LbUser> impleme
|
||||
public Map<String, Object> pageQuery(
|
||||
Integer current,
|
||||
Integer size,
|
||||
String tenantId,
|
||||
Long pid,
|
||||
String username,
|
||||
String nickname,
|
||||
@@ -131,6 +152,9 @@ public class LbUserServiceImpl extends ServiceImpl<LbUserMapper, LbUser> impleme
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<LbUser> w = new LambdaQueryWrapper<>();
|
||||
if (tenantId != null && !tenantId.trim().isEmpty()) {
|
||||
w.eq(LbUser::getTenantId, tenantId.trim());
|
||||
}
|
||||
if (pid != null) {
|
||||
w.eq(LbUser::getPid, pid);
|
||||
}
|
||||
@@ -276,4 +300,127 @@ public class LbUserServiceImpl extends ServiceImpl<LbUserMapper, LbUser> impleme
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Map<String, Object> syncFromHxrAdmin(String tenantId) {
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
try {
|
||||
if (tenantId == null || tenantId.trim().isEmpty()) {
|
||||
result.put("success", false);
|
||||
result.put("message", "tenantId不能为空");
|
||||
return result;
|
||||
}
|
||||
|
||||
String tid = tenantId.trim();
|
||||
String previousTenantId = TenantContextHolder.getTenantId();
|
||||
TenantContextHolder.setTenantId(tid);
|
||||
try {
|
||||
HxrLbUserSelectResponse firstBody = null;
|
||||
int page = 1;
|
||||
int totalSynced = 0;
|
||||
while (true) {
|
||||
Optional<HxrLbUserSelectResponse> opt = hxrAdminUserService.fetchUserSelectPage(page);
|
||||
if (opt.isEmpty()) {
|
||||
if (page == 1) {
|
||||
result.put("success", false);
|
||||
result.put("message", "未拉取到用户(请检查 hxr.admin cookie/phpsid、网络或后台返回)");
|
||||
result.put("synced", 0);
|
||||
return result;
|
||||
}
|
||||
result.put("success", false);
|
||||
result.put("message", "第 " + page + " 页拉取失败,已成功同步前 "
|
||||
+ (page - 1) + " 页共 " + totalSynced + " 条");
|
||||
result.put("synced", totalSynced);
|
||||
if (firstBody != null) {
|
||||
result.put("remoteCount", firstBody.count());
|
||||
}
|
||||
result.put("pages", page - 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
HxrLbUserSelectResponse body = opt.get();
|
||||
if (firstBody == null) {
|
||||
firstBody = body;
|
||||
}
|
||||
List<LbUser> rows = body.data();
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
List<LbUser> entities = new ArrayList<>(rows.size());
|
||||
for (LbUser row : rows) {
|
||||
if (row.getId() == null) {
|
||||
continue;
|
||||
}
|
||||
row.setTenantId(tid);
|
||||
applyDefaults(row);
|
||||
entities.add(row);
|
||||
}
|
||||
|
||||
int upserted = upsertBatch(entities);
|
||||
if (upserted < 0) {
|
||||
result.put("success", false);
|
||||
result.put("message", "第 " + page + " 页保存失败,已成功同步前 "
|
||||
+ (page - 1) + " 页共 " + totalSynced + " 条");
|
||||
result.put("synced", totalSynced);
|
||||
result.put("remoteCount", firstBody.count());
|
||||
result.put("pages", page - 1);
|
||||
return result;
|
||||
}
|
||||
totalSynced += upserted;
|
||||
|
||||
if (rows.size() < HxrAdminUserService.USER_SELECT_PAGE_SIZE) {
|
||||
break;
|
||||
}
|
||||
page++;
|
||||
}
|
||||
|
||||
result.put("success", true);
|
||||
result.put("message", totalSynced == 0 ? "接口成功,无用户数据" : "同步完成");
|
||||
result.put("synced", totalSynced);
|
||||
result.put("remoteCount", firstBody != null ? firstBody.count() : 0);
|
||||
result.put("pages", page);
|
||||
return result;
|
||||
} finally {
|
||||
if (previousTenantId != null) {
|
||||
TenantContextHolder.setTenantId(previousTenantId);
|
||||
} else {
|
||||
TenantContextHolder.clear();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
result.put("success", false);
|
||||
result.put("message", "同步异常:" + e.getMessage());
|
||||
result.put("synced", 0);
|
||||
log.error("syncFromHxrAdmin failed", e);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 实际 upsert 条数;无有效 id 时返回 0;失败返回 -1
|
||||
*/
|
||||
private int upsertBatch(List<LbUser> entities) {
|
||||
if (entities == null || entities.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
Map<Long, LbUser> deduped = new LinkedHashMap<>();
|
||||
for (LbUser entity : entities) {
|
||||
if (entity.getId() != null) {
|
||||
deduped.put(entity.getId(), entity);
|
||||
}
|
||||
}
|
||||
if (deduped.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
List<LbUser> rows = new ArrayList<>(deduped.values());
|
||||
try {
|
||||
baseMapper.upsertBatch(rows);
|
||||
return rows.size();
|
||||
} catch (Exception e) {
|
||||
log.error("lb_user upsertBatch failed, size={}", rows.size(), e);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
66
src/main/resources/mapper/LbUserMapper.xml
Normal file
66
src/main/resources/mapper/LbUserMapper.xml
Normal file
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.rj.mapper.LbUserMapper">
|
||||
|
||||
<insert id="upsertBatch">
|
||||
INSERT INTO lb_user (
|
||||
id, tenant_id, pid, username, nickname, mobile, password, salt, sex, avatar,
|
||||
invite, level, birthday, money, coupon, self_bonus, share_bonus, score,
|
||||
last_time, last_ip, join_time, join_ip, token, created_at, updated_at,
|
||||
status, viptime, is_vip, contract, max_order, is_resell,
|
||||
yesterday_sell_count, today_buy_count, today_buy_total, today_sell_total,
|
||||
poor, pname
|
||||
) VALUES
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(
|
||||
#{item.id}, #{item.tenantId}, #{item.pid}, #{item.username}, #{item.nickname},
|
||||
#{item.mobile}, #{item.password}, #{item.salt}, #{item.sex}, #{item.avatar},
|
||||
#{item.invite}, #{item.level}, #{item.birthday}, #{item.money}, #{item.coupon},
|
||||
#{item.selfBonus}, #{item.shareBonus}, #{item.score},
|
||||
#{item.lastTime}, #{item.lastIp}, #{item.joinTime}, #{item.joinIp}, #{item.token},
|
||||
#{item.createdAt}, #{item.updatedAt},
|
||||
#{item.status}, #{item.viptime}, #{item.isVip}, #{item.contract}, #{item.maxOrder},
|
||||
#{item.isResell}, #{item.yesterdaySellCount}, #{item.todayBuyCount},
|
||||
#{item.todayBuyTotal}, #{item.todaySellTotal}, #{item.poor}, #{item.pname}
|
||||
)
|
||||
</foreach>
|
||||
ON DUPLICATE KEY UPDATE
|
||||
tenant_id = VALUES(tenant_id),
|
||||
pid = VALUES(pid),
|
||||
username = VALUES(username),
|
||||
nickname = VALUES(nickname),
|
||||
mobile = VALUES(mobile),
|
||||
password = VALUES(password),
|
||||
salt = VALUES(salt),
|
||||
sex = VALUES(sex),
|
||||
avatar = VALUES(avatar),
|
||||
invite = VALUES(invite),
|
||||
level = VALUES(level),
|
||||
birthday = VALUES(birthday),
|
||||
money = VALUES(money),
|
||||
coupon = VALUES(coupon),
|
||||
self_bonus = VALUES(self_bonus),
|
||||
share_bonus = VALUES(share_bonus),
|
||||
score = VALUES(score),
|
||||
last_time = VALUES(last_time),
|
||||
last_ip = VALUES(last_ip),
|
||||
join_time = VALUES(join_time),
|
||||
join_ip = VALUES(join_ip),
|
||||
token = VALUES(token),
|
||||
created_at = VALUES(created_at),
|
||||
updated_at = VALUES(updated_at),
|
||||
status = VALUES(status),
|
||||
viptime = VALUES(viptime),
|
||||
is_vip = VALUES(is_vip),
|
||||
contract = VALUES(contract),
|
||||
max_order = VALUES(max_order),
|
||||
is_resell = VALUES(is_resell),
|
||||
yesterday_sell_count = VALUES(yesterday_sell_count),
|
||||
today_buy_count = VALUES(today_buy_count),
|
||||
today_buy_total = VALUES(today_buy_total),
|
||||
today_sell_total = VALUES(today_sell_total),
|
||||
poor = VALUES(poor),
|
||||
pname = VALUES(pname)
|
||||
</insert>
|
||||
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user