feat: 新增数据管理模块(区域管理)及修复前端已知问题

后端(bms-back):
- 新增区域管理完整后端:Domain/Mapper/Service/Controller + MyBatis XML
- 新增 RestTemplateConfig 配置类,用于第三方API调用
- 新增 countries.json 本地国家数据源(105个国家)
- RuoYiApplication 加 @EnableAsync 支持异步任务
- application-druid.yml 修复 Druid 连接池字符集配置(SET NAMES utf8mb4)
- logback.xml 日志路径改为 ${user.dir}/logs 避免沙箱写入受限
- pom.xml 增加 JVM 编码参数(-Dfile.encoding=UTF-8)
- 新增 sql/bms_region.sql 建表脚本+菜单权限

前端(bms-front):
- 新增区域管理页面(列表/编辑/状态切换/同步国家数据/导出)
- 新增同步日志功能(内嵌为区域管理弹窗,移除独立菜单)
- 新增 API 层: region.js / region-log.js
- 修复 BasicForm/index.vue 缺失 import FormControl 导致搜索栏控件不渲染
- 修复 user/role/region 三个页面 el-switch 初始化时弹 undefined 提示
This commit is contained in:
wuweihua
2026-08-31 11:01:25 +08:00
parent b003b73b77
commit 44d2b690de
28 changed files with 2318 additions and 1105 deletions
@@ -0,0 +1,270 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 国家/区域 bms_region
*
* @author ruoyi
*/
public class BmsRegion extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 区域ID */
@Excel(name = "区域ID")
private Long regionId;
/** 中文名 */
@Excel(name = "中文名")
private String countryNameCn;
/** 英文名 */
@Excel(name = "英文名")
private String countryNameEn;
/** ISO两位码 */
@Excel(name = "国家代码")
private String countryCode2;
/** ISO三位码 */
@Excel(name = "ISO三位码")
private String countryCode3;
/** 洲/大区 */
@Excel(name = "洲/大区")
private String continent;
/** 子区域 */
@Excel(name = "子区域")
private String subRegion;
/** 货币代码 */
@Excel(name = "货币代码")
private String currencyCode;
/** 货币名称 */
@Excel(name = "货币名称")
private String currencyName;
/** 货币符号 */
private String currencySymbol;
/** 电话前缀 */
@Excel(name = "电话前缀")
private String phonePrefix;
/** 国旗emoji */
private String flagEmoji;
/** 国旗图片URL */
private String flagUrl;
/** 是否独立(1是 0否) */
@Excel(name = "是否独立", readConverterExp = "1=是,0=否")
private String isIndependent;
/** 是否欧盟成员(1是 0否) */
@Excel(name = "是否欧盟", readConverterExp = "1=是,0=否")
private String isEu;
/** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0存在 2删除) */
private String delFlag;
public Long getRegionId()
{
return regionId;
}
public void setRegionId(Long regionId)
{
this.regionId = regionId;
}
public String getCountryNameCn()
{
return countryNameCn;
}
public void setCountryNameCn(String countryNameCn)
{
this.countryNameCn = countryNameCn;
}
public String getCountryNameEn()
{
return countryNameEn;
}
public void setCountryNameEn(String countryNameEn)
{
this.countryNameEn = countryNameEn;
}
public String getCountryCode2()
{
return countryCode2;
}
public void setCountryCode2(String countryCode2)
{
this.countryCode2 = countryCode2;
}
public String getCountryCode3()
{
return countryCode3;
}
public void setCountryCode3(String countryCode3)
{
this.countryCode3 = countryCode3;
}
public String getContinent()
{
return continent;
}
public void setContinent(String continent)
{
this.continent = continent;
}
public String getSubRegion()
{
return subRegion;
}
public void setSubRegion(String subRegion)
{
this.subRegion = subRegion;
}
public String getCurrencyCode()
{
return currencyCode;
}
public void setCurrencyCode(String currencyCode)
{
this.currencyCode = currencyCode;
}
public String getCurrencyName()
{
return currencyName;
}
public void setCurrencyName(String currencyName)
{
this.currencyName = currencyName;
}
public String getCurrencySymbol()
{
return currencySymbol;
}
public void setCurrencySymbol(String currencySymbol)
{
this.currencySymbol = currencySymbol;
}
public String getPhonePrefix()
{
return phonePrefix;
}
public void setPhonePrefix(String phonePrefix)
{
this.phonePrefix = phonePrefix;
}
public String getFlagEmoji()
{
return flagEmoji;
}
public void setFlagEmoji(String flagEmoji)
{
this.flagEmoji = flagEmoji;
}
public String getFlagUrl()
{
return flagUrl;
}
public void setFlagUrl(String flagUrl)
{
this.flagUrl = flagUrl;
}
public String getIsIndependent()
{
return isIndependent;
}
public void setIsIndependent(String isIndependent)
{
this.isIndependent = isIndependent;
}
public String getIsEu()
{
return isEu;
}
public void setIsEu(String isEu)
{
this.isEu = isEu;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public String getDelFlag()
{
return delFlag;
}
public void setDelFlag(String delFlag)
{
this.delFlag = delFlag;
}
@Override
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("regionId", getRegionId())
.append("countryNameCn", getCountryNameCn())
.append("countryNameEn", getCountryNameEn())
.append("countryCode2", getCountryCode2())
.append("countryCode3", getCountryCode3())
.append("continent", getContinent())
.append("subRegion", getSubRegion())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
@@ -0,0 +1,160 @@
package com.ruoyi.system.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;
/**
* 区域数据同步日志 bms_region_sync_log
*
* @author ruoyi
*/
public class BmsRegionSyncLog extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 日志ID */
@Excel(name = "日志ID")
private Long logId;
/** 同步类型 */
@Excel(name = "同步类型")
private String syncType;
/** 状态 */
@Excel(name = "状态", readConverterExp = "PENDING=待处理,PROCESSING=处理中,SUCCESS=成功,FAILED=失败")
private String status;
/** API返回总数 */
@Excel(name = "总数")
private Integer totalCount;
/** 新增数 */
@Excel(name = "新增数")
private Integer insertCount;
/** 更新数 */
@Excel(name = "更新数")
private Integer updateCount;
/** 失败数 */
@Excel(name = "失败数")
private Integer failCount;
/** 耗时(毫秒) */
@Excel(name = "耗时(ms)")
private Long durationMs;
/** 错误信息 */
private String errorMsg;
public Long getLogId()
{
return logId;
}
public void setLogId(Long logId)
{
this.logId = logId;
}
public String getSyncType()
{
return syncType;
}
public void setSyncType(String syncType)
{
this.syncType = syncType;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
public Integer getTotalCount()
{
return totalCount;
}
public void setTotalCount(Integer totalCount)
{
this.totalCount = totalCount;
}
public Integer getInsertCount()
{
return insertCount;
}
public void setInsertCount(Integer insertCount)
{
this.insertCount = insertCount;
}
public Integer getUpdateCount()
{
return updateCount;
}
public void setUpdateCount(Integer updateCount)
{
this.updateCount = updateCount;
}
public Integer getFailCount()
{
return failCount;
}
public void setFailCount(Integer failCount)
{
this.failCount = failCount;
}
public Long getDurationMs()
{
return durationMs;
}
public void setDurationMs(Long durationMs)
{
this.durationMs = durationMs;
}
public String getErrorMsg()
{
return errorMsg;
}
public void setErrorMsg(String errorMsg)
{
this.errorMsg = errorMsg;
}
@Override
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE)
.append("logId", getLogId())
.append("syncType", getSyncType())
.append("status", getStatus())
.append("totalCount", getTotalCount())
.append("insertCount", getInsertCount())
.append("updateCount", getUpdateCount())
.append("failCount", getFailCount())
.append("durationMs", getDurationMs())
.append("errorMsg", getErrorMsg())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateTime", getUpdateTime())
.toString();
}
}
@@ -0,0 +1,68 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.BmsRegion;
/**
* 国家/区域 数据层
*
* @author ruoyi
*/
public interface BmsRegionMapper
{
/**
* 查询区域信息
*
* @param regionId 区域ID
* @return 区域信息
*/
public BmsRegion selectRegionById(Long regionId);
/**
* 查询区域列表
*
* @param region 区域信息
* @return 区域集合
*/
public List<BmsRegion> selectRegionList(BmsRegion region);
/**
* 根据ISO两位码查询区域
*
* @param countryCode2 ISO两位码
* @return 区域信息
*/
public BmsRegion selectRegionByCode2(String countryCode2);
/**
* 新增区域
*
* @param region 区域信息
* @return 结果
*/
public int insertRegion(BmsRegion region);
/**
* 修改区域
*
* @param region 区域信息
* @return 结果
*/
public int updateRegion(BmsRegion region);
/**
* 批量删除区域
*
* @param regionIds 需要删除的区域ID
* @return 结果
*/
public int deleteRegionByIds(Long[] regionIds);
/**
* 根据ISO两位码做upsert(存在则更新,不存在则新增)
*
* @param region 区域信息
* @return 结果
*/
public int upsertByCode2(BmsRegion region);
}
@@ -0,0 +1,52 @@
package com.ruoyi.system.mapper;
import java.util.List;
import com.ruoyi.system.domain.BmsRegionSyncLog;
/**
* 区域数据同步日志 数据层
*
* @author ruoyi
*/
public interface BmsRegionSyncLogMapper
{
/**
* 查询同步日志
*
* @param logId 日志ID
* @return 同步日志
*/
public BmsRegionSyncLog selectSyncLogById(Long logId);
/**
* 查询同步日志列表
*
* @param syncLog 同步日志
* @return 同步日志集合
*/
public List<BmsRegionSyncLog> selectSyncLogList(BmsRegionSyncLog syncLog);
/**
* 新增同步日志
*
* @param syncLog 同步日志
* @return 结果
*/
public int insertSyncLog(BmsRegionSyncLog syncLog);
/**
* 修改同步日志
*
* @param syncLog 同步日志
* @return 结果
*/
public int updateSyncLog(BmsRegionSyncLog syncLog);
/**
* 批量删除同步日志
*
* @param logIds 需要删除的日志ID
* @return 结果
*/
public int deleteSyncLogByIds(Long[] logIds);
}
@@ -0,0 +1,60 @@
package com.ruoyi.system.service;
import java.util.List;
import com.ruoyi.system.domain.BmsRegion;
/**
* 国家/区域 服务层
*
* @author ruoyi
*/
public interface IBmsRegionService
{
/**
* 查询区域信息
*
* @param regionId 区域ID
* @return 区域信息
*/
public BmsRegion selectRegionById(Long regionId);
/**
* 查询区域列表
*
* @param region 区域信息
* @return 区域集合
*/
public List<BmsRegion> selectRegionList(BmsRegion region);
/**
* 新增区域
*
* @param region 区域信息
* @return 结果
*/
public int insertRegion(BmsRegion region);
/**
* 修改区域
*
* @param region 区域信息
* @return 结果
*/
public int updateRegion(BmsRegion region);
/**
* 批量删除区域
*
* @param regionIds 需要删除的区域ID
* @return 结果
*/
public int deleteRegionByIds(Long[] regionIds);
/**
* 修改区域状态
*
* @param region 区域信息
* @return 结果
*/
public int updateRegionStatus(BmsRegion region);
}
@@ -0,0 +1,16 @@
package com.ruoyi.system.service;
/**
* 区域数据同步 服务层
*
* @author ruoyi
*/
public interface IBmsRegionSyncService
{
/**
* 触发同步国家数据(异步)
*
* @return 日志ID
*/
public Long syncRegion();
}
@@ -0,0 +1,93 @@
package com.ruoyi.system.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.BmsRegion;
import com.ruoyi.system.mapper.BmsRegionMapper;
import com.ruoyi.system.service.IBmsRegionService;
/**
* 国家/区域 服务层实现
*
* @author ruoyi
*/
@Service
public class BmsRegionServiceImpl implements IBmsRegionService
{
@Autowired
private BmsRegionMapper regionMapper;
/**
* 查询区域信息
*
* @param regionId 区域ID
* @return 区域信息
*/
@Override
public BmsRegion selectRegionById(Long regionId)
{
return regionMapper.selectRegionById(regionId);
}
/**
* 查询区域列表
*
* @param region 区域信息
* @return 区域集合
*/
@Override
public List<BmsRegion> selectRegionList(BmsRegion region)
{
return regionMapper.selectRegionList(region);
}
/**
* 新增区域
*
* @param region 区域信息
* @return 结果
*/
@Override
public int insertRegion(BmsRegion region)
{
return regionMapper.insertRegion(region);
}
/**
* 修改区域
*
* @param region 区域信息
* @return 结果
*/
@Override
public int updateRegion(BmsRegion region)
{
return regionMapper.updateRegion(region);
}
/**
* 批量删除区域
*
* @param regionIds 需要删除的区域ID
* @return 结果
*/
@Override
public int deleteRegionByIds(Long[] regionIds)
{
return regionMapper.deleteRegionByIds(regionIds);
}
/**
* 修改区域状态
*
* @param region 区域信息
* @return 结果
*/
@Override
public int updateRegionStatus(BmsRegion region)
{
return regionMapper.updateRegion(region);
}
}
@@ -0,0 +1,249 @@
package com.ruoyi.system.service.impl;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.BmsRegion;
import com.ruoyi.system.domain.BmsRegionSyncLog;
import com.ruoyi.system.mapper.BmsRegionMapper;
import com.ruoyi.system.mapper.BmsRegionSyncLogMapper;
import com.ruoyi.system.service.IBmsRegionSyncService;
/**
* 区域数据同步 服务层实现
* 从本地 countries.json 文件加载国家数据
*
* @author ruoyi
*/
@Service
public class BmsRegionSyncServiceImpl implements IBmsRegionSyncService
{
private static final Logger log = LoggerFactory.getLogger(BmsRegionSyncServiceImpl.class);
private static final String DATA_FILE = "countries.json";
@Autowired
private BmsRegionMapper regionMapper;
@Autowired
private BmsRegionSyncLogMapper syncLogMapper;
/**
* 触发同步国家数据(异步)
*
* @return 日志ID
*/
@Override
public Long syncRegion()
{
// 创建同步日志记录
BmsRegionSyncLog syncLog = new BmsRegionSyncLog();
syncLog.setSyncType("ALL");
syncLog.setStatus("PROCESSING");
syncLog.setTotalCount(0);
syncLog.setInsertCount(0);
syncLog.setUpdateCount(0);
syncLog.setFailCount(0);
syncLog.setDurationMs(0L);
syncLogMapper.insertSyncLog(syncLog);
// 异步执行同步
asyncSync(syncLog.getLogId());
return syncLog.getLogId();
}
/**
* 异步同步国家数据
*
* @param logId 日志ID
*/
@Async("threadPoolTaskExecutor")
@Transactional(rollbackFor = Exception.class)
public void asyncSync(Long logId)
{
long startTime = System.currentTimeMillis();
BmsRegionSyncLog syncLog = syncLogMapper.selectSyncLogById(logId);
try
{
log.info("开始同步国家数据,读取本地文件: {}", DATA_FILE);
// 从classpath读取国家数据文件
ClassPathResource resource = new ClassPathResource(DATA_FILE);
InputStream inputStream = resource.getInputStream();
byte[] bytes = inputStream.readAllBytes();
inputStream.close();
String jsonData = new String(bytes, StandardCharsets.UTF_8);
if (StringUtils.isEmpty(jsonData))
{
throw new RuntimeException("国家数据文件为空");
}
// 解析JSON
ObjectMapper objectMapper = new ObjectMapper();
List<Object> countryList = objectMapper.readValue(jsonData, List.class);
int insertCount = 0;
int updateCount = 0;
int failCount = 0;
for (Object obj : countryList)
{
try
{
@SuppressWarnings("unchecked")
Map<String, Object> country = (Map<String, Object>) obj;
BmsRegion region = parseCountry(country);
if (region == null || StringUtils.isEmpty(region.getCountryCode2()))
{
failCount++;
continue;
}
// 检查是否已存在
BmsRegion existing = regionMapper.selectRegionByCode2(region.getCountryCode2());
if (existing != null)
{
region.setRegionId(existing.getRegionId());
regionMapper.updateRegion(region);
updateCount++;
}
else
{
regionMapper.insertRegion(region);
insertCount++;
}
}
catch (Exception e)
{
failCount++;
log.warn("解析国家数据失败: {}", e.getMessage());
}
}
// 更新同步日志
long duration = System.currentTimeMillis() - startTime;
syncLog.setStatus("SUCCESS");
syncLog.setTotalCount(countryList.size());
syncLog.setInsertCount(insertCount);
syncLog.setUpdateCount(updateCount);
syncLog.setFailCount(failCount);
syncLog.setDurationMs(duration);
syncLogMapper.updateSyncLog(syncLog);
log.info("同步国家数据完成: 总数={}, 新增={}, 更新={}, 失败={}, 耗时={}ms",
countryList.size(), insertCount, updateCount, failCount, duration);
}
catch (Exception e)
{
long duration = System.currentTimeMillis() - startTime;
syncLog.setStatus("FAILED");
syncLog.setDurationMs(duration);
syncLog.setErrorMsg(StringUtils.substring(e.getMessage(), 0, 2000));
syncLogMapper.updateSyncLog(syncLog);
log.error("同步国家数据失败: {}", e.getMessage(), e);
}
}
/**
* 解析国家数据
*
* @param country 国家Map
* @return 区域实体
*/
@SuppressWarnings("unchecked")
private BmsRegion parseCountry(Map<String, Object> country)
{
BmsRegion region = new BmsRegion();
region.setStatus("0");
region.setIsIndependent("1");
region.setIsEu("0");
// 英文名 name.common
Map<String, Object> name = (Map<String, Object>) country.get("name");
if (name != null)
{
region.setCountryNameEn((String) name.get("common"));
}
// 中文名 translations.cmn.common,如无则用英文名
Map<String, Object> translations = (Map<String, Object>) country.get("translations");
if (translations != null)
{
Map<String, Object> cmn = (Map<String, Object>) translations.get("cmn");
if (cmn != null)
{
region.setCountryNameCn((String) cmn.get("common"));
}
}
if (StringUtils.isEmpty(region.getCountryNameCn()))
{
region.setCountryNameCn(region.getCountryNameEn());
}
// ISO代码
region.setCountryCode2((String) country.get("cca2"));
region.setCountryCode3((String) country.get("cca3"));
// 大洲/子区域
region.setContinent((String) country.get("region"));
region.setSubRegion((String) country.get("subregion"));
// 货币
Map<String, Object> currencies = (Map<String, Object>) country.get("currencies");
if (currencies != null && !currencies.isEmpty())
{
Map.Entry<String, Object> entry = currencies.entrySet().iterator().next();
region.setCurrencyCode(entry.getKey());
Map<String, Object> currency = (Map<String, Object>) entry.getValue();
if (currency != null)
{
region.setCurrencyName((String) currency.get("name"));
region.setCurrencySymbol((String) currency.get("symbol"));
}
}
// 电话前缀 idd.root + idd.suffixes
Map<String, Object> idd = (Map<String, Object>) country.get("idd");
if (idd != null)
{
String root = (String) idd.get("root");
List<String> suffixes = (List<String>) idd.get("suffixes");
if (StringUtils.isNotEmpty(root) && suffixes != null && !suffixes.isEmpty())
{
region.setPhonePrefix(root + suffixes.get(0));
}
}
// 国旗
region.setFlagEmoji((String) country.get("flag"));
Map<String, Object> flags = (Map<String, Object>) country.get("flags");
if (flags != null)
{
region.setFlagUrl((String) flags.get("png"));
}
// 是否独立
Boolean independent = (Boolean) country.get("independent");
if (independent != null)
{
region.setIsIndependent(independent ? "1" : "0");
}
return region;
}
}
@@ -0,0 +1,179 @@
<?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.ruoyi.system.mapper.BmsRegionMapper">
<resultMap type="BmsRegion" id="BmsRegionResult">
<id property="regionId" column="region_id" />
<result property="countryNameCn" column="country_name_cn" />
<result property="countryNameEn" column="country_name_en" />
<result property="countryCode2" column="country_code_2" />
<result property="countryCode3" column="country_code_3" />
<result property="continent" column="continent" />
<result property="subRegion" column="sub_region" />
<result property="currencyCode" column="currency_code" />
<result property="currencyName" column="currency_name" />
<result property="currencySymbol" column="currency_symbol" />
<result property="phonePrefix" column="phone_prefix" />
<result property="flagEmoji" column="flag_emoji" />
<result property="flagUrl" column="flag_url" />
<result property="isIndependent" column="is_independent" />
<result property="isEu" column="is_eu" />
<result property="status" column="status" />
<result property="delFlag" column="del_flag" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectRegionVo">
select region_id, country_name_cn, country_name_en, country_code_2, country_code_3,
continent, sub_region, currency_code, currency_name, currency_symbol,
phone_prefix, flag_emoji, flag_url, is_independent, is_eu,
status, del_flag, create_by, create_time, update_by, update_time, remark
from bms_region
</sql>
<select id="selectRegionById" parameterType="Long" resultMap="BmsRegionResult">
<include refid="selectRegionVo"/>
where region_id = #{regionId}
</select>
<select id="selectRegionByCode2" parameterType="String" resultMap="BmsRegionResult">
<include refid="selectRegionVo"/>
where country_code_2 = #{countryCode2} limit 1
</select>
<select id="selectRegionList" parameterType="BmsRegion" resultMap="BmsRegionResult">
<include refid="selectRegionVo"/>
<where>
del_flag = '0'
<if test="countryNameCn != null and countryNameCn != ''">
AND country_name_cn like concat('%', #{countryNameCn}, '%')
</if>
<if test="countryNameEn != null and countryNameEn != ''">
AND country_name_en like concat('%', #{countryNameEn}, '%')
</if>
<if test="countryCode2 != null and countryCode2 != ''">
AND country_code_2 like concat('%', #{countryCode2}, '%')
</if>
<if test="continent != null and continent != ''">
AND continent = #{continent}
</if>
<if test="status != null and status != ''">
AND status = #{status}
</if>
</where>
order by region_id
</select>
<insert id="insertRegion" parameterType="BmsRegion" useGeneratedKeys="true" keyProperty="regionId">
insert into bms_region (
<if test="countryNameCn != null">country_name_cn,</if>
<if test="countryNameEn != null and countryNameEn != ''">country_name_en,</if>
<if test="countryCode2 != null and countryCode2 != ''">country_code_2,</if>
<if test="countryCode3 != null">country_code_3,</if>
<if test="continent != null">continent,</if>
<if test="subRegion != null">sub_region,</if>
<if test="currencyCode != null">currency_code,</if>
<if test="currencyName != null">currency_name,</if>
<if test="currencySymbol != null">currency_symbol,</if>
<if test="phonePrefix != null">phone_prefix,</if>
<if test="flagEmoji != null">flag_emoji,</if>
<if test="flagUrl != null">flag_url,</if>
<if test="isIndependent != null and isIndependent != ''">is_independent,</if>
<if test="isEu != null and isEu != ''">is_eu,</if>
<if test="status != null and status != ''">status,</if>
<if test="delFlag != null and delFlag != ''">del_flag,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
<if test="remark != null">remark,</if>
create_time
) values (
<if test="countryNameCn != null">#{countryNameCn},</if>
<if test="countryNameEn != null and countryNameEn != ''">#{countryNameEn},</if>
<if test="countryCode2 != null and countryCode2 != ''">#{countryCode2},</if>
<if test="countryCode3 != null">#{countryCode3},</if>
<if test="continent != null">#{continent},</if>
<if test="subRegion != null">#{subRegion},</if>
<if test="currencyCode != null">#{currencyCode},</if>
<if test="currencyName != null">#{currencyName},</if>
<if test="currencySymbol != null">#{currencySymbol},</if>
<if test="phonePrefix != null">#{phonePrefix},</if>
<if test="flagEmoji != null">#{flagEmoji},</if>
<if test="flagUrl != null">#{flagUrl},</if>
<if test="isIndependent != null and isIndependent != ''">#{isIndependent},</if>
<if test="isEu != null and isEu != ''">#{isEu},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="delFlag != null and delFlag != ''">#{delFlag},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
<if test="remark != null">#{remark},</if>
sysdate()
)
</insert>
<update id="updateRegion" parameterType="BmsRegion">
update bms_region
<set>
<if test="countryNameCn != null">country_name_cn = #{countryNameCn},</if>
<if test="countryNameEn != null and countryNameEn != ''">country_name_en = #{countryNameEn},</if>
<if test="countryCode2 != null and countryCode2 != ''">country_code_2 = #{countryCode2},</if>
<if test="countryCode3 != null">country_code_3 = #{countryCode3},</if>
<if test="continent != null">continent = #{continent},</if>
<if test="subRegion != null">sub_region = #{subRegion},</if>
<if test="currencyCode != null">currency_code = #{currencyCode},</if>
<if test="currencyName != null">currency_name = #{currencyName},</if>
<if test="currencySymbol != null">currency_symbol = #{currencySymbol},</if>
<if test="phonePrefix != null">phone_prefix = #{phonePrefix},</if>
<if test="flagEmoji != null">flag_emoji = #{flagEmoji},</if>
<if test="flagUrl != null">flag_url = #{flagUrl},</if>
<if test="isIndependent != null and isIndependent != ''">is_independent = #{isIndependent},</if>
<if test="isEu != null and isEu != ''">is_eu = #{isEu},</if>
<if test="status != null and status != ''">status = #{status},</if>
<if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
<if test="remark != null">remark = #{remark},</if>
update_time = sysdate()
</set>
where region_id = #{regionId}
</update>
<delete id="deleteRegionByIds" parameterType="Long">
delete from bms_region where region_id in
<foreach item="regionId" collection="array" open="(" separator="," close=")">
#{regionId}
</foreach>
</delete>
<insert id="upsertByCode2" parameterType="BmsRegion">
insert into bms_region (
country_name_cn, country_name_en, country_code_2, country_code_3,
continent, sub_region, currency_code, currency_name, currency_symbol,
phone_prefix, flag_emoji, flag_url, is_independent, is_eu,
status, del_flag, create_by, create_time
) values (
#{countryNameCn}, #{countryNameEn}, #{countryCode2}, #{countryCode3},
#{continent}, #{subRegion}, #{currencyCode}, #{currencyName}, #{currencySymbol},
#{phonePrefix}, #{flagEmoji}, #{flagUrl}, #{isIndependent}, #{isEu},
#{status}, '0', #{createBy}, sysdate()
)
on duplicate key update
country_name_cn = values(country_name_cn),
country_name_en = values(country_name_en),
country_code_3 = values(country_code_3),
continent = values(continent),
sub_region = values(sub_region),
currency_code = values(currency_code),
currency_name = values(currency_name),
currency_symbol = values(currency_symbol),
phone_prefix = values(phone_prefix),
flag_emoji = values(flag_emoji),
flag_url = values(flag_url),
is_independent = values(is_independent),
is_eu = values(is_eu),
update_by = #{updateBy},
update_time = sysdate()
</insert>
</mapper>
@@ -0,0 +1,101 @@
<?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.ruoyi.system.mapper.BmsRegionSyncLogMapper">
<resultMap type="BmsRegionSyncLog" id="BmsRegionSyncLogResult">
<id property="logId" column="log_id" />
<result property="syncType" column="sync_type" />
<result property="status" column="status" />
<result property="totalCount" column="total_count" />
<result property="insertCount" column="insert_count" />
<result property="updateCount" column="update_count" />
<result property="failCount" column="fail_count" />
<result property="durationMs" column="duration_ms" />
<result property="errorMsg" column="error_msg" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectSyncLogVo">
select log_id, sync_type, status, total_count, insert_count, update_count,
fail_count, duration_ms, error_msg, create_by, create_time, update_by, update_time
from bms_region_sync_log
</sql>
<select id="selectSyncLogById" parameterType="Long" resultMap="BmsRegionSyncLogResult">
<include refid="selectSyncLogVo"/>
where log_id = #{logId}
</select>
<select id="selectSyncLogList" parameterType="BmsRegionSyncLog" resultMap="BmsRegionSyncLogResult">
<include refid="selectSyncLogVo"/>
<where>
<if test="syncType != null and syncType != ''">
AND sync_type = #{syncType}
</if>
<if test="status != null and status != ''">
AND status = #{status}
</if>
<if test="params.beginTime != null and params.beginTime != ''">
and date_format(create_time,'%Y%m%d') &gt;= date_format(#{params.beginTime},'%Y%m%d')
</if>
<if test="params.endTime != null and params.endTime != ''">
and date_format(create_time,'%Y%m%d') &lt;= date_format(#{params.endTime},'%Y%m%d')
</if>
</where>
order by log_id desc
</select>
<insert id="insertSyncLog" parameterType="BmsRegionSyncLog" useGeneratedKeys="true" keyProperty="logId">
insert into bms_region_sync_log (
<if test="syncType != null and syncType != ''">sync_type,</if>
<if test="status != null and status != ''">status,</if>
<if test="totalCount != null">total_count,</if>
<if test="insertCount != null">insert_count,</if>
<if test="updateCount != null">update_count,</if>
<if test="failCount != null">fail_count,</if>
<if test="durationMs != null">duration_ms,</if>
<if test="errorMsg != null">error_msg,</if>
<if test="createBy != null and createBy != ''">create_by,</if>
create_time
) values (
<if test="syncType != null and syncType != ''">#{syncType},</if>
<if test="status != null and status != ''">#{status},</if>
<if test="totalCount != null">#{totalCount},</if>
<if test="insertCount != null">#{insertCount},</if>
<if test="updateCount != null">#{updateCount},</if>
<if test="failCount != null">#{failCount},</if>
<if test="durationMs != null">#{durationMs},</if>
<if test="errorMsg != null">#{errorMsg},</if>
<if test="createBy != null and createBy != ''">#{createBy},</if>
sysdate()
)
</insert>
<update id="updateSyncLog" parameterType="BmsRegionSyncLog">
update bms_region_sync_log
<set>
<if test="status != null and status != ''">status = #{status},</if>
<if test="totalCount != null">total_count = #{totalCount},</if>
<if test="insertCount != null">insert_count = #{insertCount},</if>
<if test="updateCount != null">update_count = #{updateCount},</if>
<if test="failCount != null">fail_count = #{failCount},</if>
<if test="durationMs != null">duration_ms = #{durationMs},</if>
<if test="errorMsg != null">error_msg = #{errorMsg},</if>
update_time = sysdate()
</set>
where log_id = #{logId}
</update>
<delete id="deleteSyncLogByIds" parameterType="Long">
delete from bms_region_sync_log where log_id in
<foreach item="logId" collection="array" open="(" separator="," close=")">
#{logId}
</foreach>
</delete>
</mapper>