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,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>