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
@@ -3,12 +3,14 @@ package com.ruoyi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableAsync;
/**
* 启动程序
*
*
* @author ruoyi
*/
@EnableAsync
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication
{
@@ -0,0 +1,124 @@
package com.ruoyi.web.controller.data;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.BmsRegion;
import com.ruoyi.system.service.IBmsRegionService;
import com.ruoyi.system.service.IBmsRegionSyncService;
/**
* 区域管理 信息操作处理
*
* @author ruoyi
*/
@RestController
@RequestMapping("/data/region")
public class BmsRegionController extends BaseController
{
@Autowired
private IBmsRegionService regionService;
@Autowired
private IBmsRegionSyncService syncService;
/**
* 获取区域列表
*/
@PreAuthorize("@ss.hasPermi('data:region:list')")
@GetMapping("/list")
public TableDataInfo list(BmsRegion region)
{
startPage();
List<BmsRegion> list = regionService.selectRegionList(region);
return getDataTable(list);
}
/**
* 导出区域列表
*/
@PreAuthorize("@ss.hasPermi('data:region:list')")
@Log(title = "区域管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, BmsRegion region)
{
List<BmsRegion> list = regionService.selectRegionList(region);
ExcelUtil<BmsRegion> util = new ExcelUtil<BmsRegion>(BmsRegion.class);
util.exportExcel(response, list, "区域数据");
}
/**
* 获取区域详细信息
*/
@PreAuthorize("@ss.hasPermi('data:region:query')")
@GetMapping(value = "/{regionId}")
public AjaxResult getInfo(@PathVariable Long regionId)
{
return success(regionService.selectRegionById(regionId));
}
/**
* 修改区域
*/
@PreAuthorize("@ss.hasPermi('data:region:edit')")
@Log(title = "区域管理", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@Validated @RequestBody BmsRegion region)
{
region.setUpdateBy(getUsername());
return toAjax(regionService.updateRegion(region));
}
/**
* 删除区域
*/
@PreAuthorize("@ss.hasPermi('data:region:remove')")
@Log(title = "区域管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{regionIds}")
public AjaxResult remove(@PathVariable Long[] regionIds)
{
return toAjax(regionService.deleteRegionByIds(regionIds));
}
/**
* 修改区域状态(启用/停用)
*/
@PreAuthorize("@ss.hasPermi('data:region:edit')")
@Log(title = "区域管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody BmsRegion region)
{
region.setUpdateBy(getUsername());
return toAjax(regionService.updateRegionStatus(region));
}
/**
* 同步国家数据(异步)
*/
@PreAuthorize("@ss.hasPermi('data:region:sync')")
@Log(title = "区域管理", businessType = BusinessType.OTHER)
@PostMapping("/sync")
public AjaxResult sync()
{
Long logId = syncService.syncRegion();
AjaxResult ajax = AjaxResult.success("同步任务已创建,正在后台执行");
ajax.put("logId", logId);
return ajax;
}
}
@@ -0,0 +1,63 @@
package com.ruoyi.web.controller.data;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.BmsRegionSyncLog;
import com.ruoyi.system.mapper.BmsRegionSyncLogMapper;
/**
* 区域同步日志 信息操作处理
*
* @author ruoyi
*/
@RestController
@RequestMapping("/data/region/log")
public class BmsRegionSyncLogController extends BaseController
{
@Autowired
private BmsRegionSyncLogMapper syncLogMapper;
/**
* 获取同步日志列表
*/
@PreAuthorize("@ss.hasPermi('data:region:log:list')")
@GetMapping("/list")
public TableDataInfo list(BmsRegionSyncLog syncLog)
{
startPage();
List<BmsRegionSyncLog> list = syncLogMapper.selectSyncLogList(syncLog);
return getDataTable(list);
}
/**
* 获取同步日志详细信息
*/
@PreAuthorize("@ss.hasPermi('data:region:log:list')")
@GetMapping(value = "/{logId}")
public AjaxResult getInfo(@PathVariable Long logId)
{
return success(syncLogMapper.selectSyncLogById(logId));
}
/**
* 删除同步日志
*/
@PreAuthorize("@ss.hasPermi('data:region:log:remove')")
@Log(title = "同步日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{logIds}")
public AjaxResult remove(@PathVariable Long[] logIds)
{
return toAjax(syncLogMapper.deleteSyncLogByIds(logIds));
}
}