From f73a002f0f321be4cbf522cd0cf2e3f08606485e Mon Sep 17 00:00:00 2001 From: 86156 <823267011@qq.com> Date: Mon, 20 Apr 2026 14:14:08 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9F=8E=E5=B8=82=E7=AE=A1?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../hrm/controller/HrmFlowTaskController.java | 10 ++ .../com/ruoyi/hrm/domain/HrmFlowAction.java | 3 +- .../domain/vo/HrmFlowActionTimelineVo.java | 28 ++++ .../hrm/domain/vo/HrmFlowTaskDetailVo.java | 32 +++++ .../hrm/service/IHrmFlowTaskService.java | 7 +- .../impl/HrmFlowInstanceServiceImpl.java | 2 + .../service/impl/HrmFlowTaskServiceImpl.java | 134 ++++++++++++++++-- .../ruoyi/oa/controller/OaCityController.java | 62 ++++++++ .../main/java/com/ruoyi/oa/domain/OaCity.java | 37 +++++ .../java/com/ruoyi/oa/domain/bo/OaCityBo.java | 28 ++++ .../java/com/ruoyi/oa/domain/vo/OaCityVo.java | 23 +++ .../com/ruoyi/oa/mapper/OaCityMapper.java | 11 ++ .../com/ruoyi/oa/service/IOaCityService.java | 24 ++++ .../oa/service/impl/OaCityServiceImpl.java | 73 ++++++++++ sql/oa_city.sql | 24 ++++ 15 files changed, 483 insertions(+), 15 deletions(-) create mode 100644 fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowActionTimelineVo.java create mode 100644 fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowTaskDetailVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaCityController.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaCity.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaCityBo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaCityVo.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaCityMapper.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaCityService.java create mode 100644 ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaCityServiceImpl.java create mode 100644 sql/oa_city.sql diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/controller/HrmFlowTaskController.java b/fad-hrm/src/main/java/com/ruoyi/hrm/controller/HrmFlowTaskController.java index 07c299a..7f3633c 100644 --- a/fad-hrm/src/main/java/com/ruoyi/hrm/controller/HrmFlowTaskController.java +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/controller/HrmFlowTaskController.java @@ -56,6 +56,16 @@ public class HrmFlowTaskController extends BaseController { } + /** + * 详情页使用:按 bizType + bizId 查询审批概要、当前待办和历史记录 + */ + @GetMapping("/detailByBiz") + public R detailByBiz(@RequestParam @NotNull String bizType, + @RequestParam @NotNull Long bizId, + @RequestParam(required = false) Long assigneeUserId) { + return R.ok(service.queryDetailByBiz(bizType, bizId, assigneeUserId)); + } + @GetMapping("/{taskId}") public R getInfo(@PathVariable @NotNull Long taskId) { return R.ok(service.queryById(taskId)); diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/domain/HrmFlowAction.java b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/HrmFlowAction.java index c7cef2e..785ee4b 100644 --- a/fad-hrm/src/main/java/com/ruoyi/hrm/domain/HrmFlowAction.java +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/HrmFlowAction.java @@ -7,12 +7,11 @@ import com.ruoyi.common.core.domain.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; -import java.io.Serializable; @Data @EqualsAndHashCode(callSuper = true) @TableName("hrm_flow_action") -public class HrmFlowAction extends BaseEntity implements Serializable { +public class HrmFlowAction extends BaseEntity { private static final long serialVersionUID = 1L; @TableId diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowActionTimelineVo.java b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowActionTimelineVo.java new file mode 100644 index 0000000..d6dad9a --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowActionTimelineVo.java @@ -0,0 +1,28 @@ +package com.ruoyi.hrm.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +public class HrmFlowActionTimelineVo implements Serializable { + private static final long serialVersionUID = 1L; + + private Long actionId; + private Long taskId; + private Long instId; + private Long actionUserId; + private String actionUserName; + private Long assigneeUserId; + private String assigneeUserName; + private String action; + private String actionText; + private String remark; + private String bizType; + private Long bizId; + private Long nodeId; + private String nodeName; + private String taskStatus; + private Date createTime; +} diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowTaskDetailVo.java b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowTaskDetailVo.java new file mode 100644 index 0000000..eb67b1e --- /dev/null +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/domain/vo/HrmFlowTaskDetailVo.java @@ -0,0 +1,32 @@ +package com.ruoyi.hrm.domain.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +@Data +public class HrmFlowTaskDetailVo implements Serializable { + private static final long serialVersionUID = 1L; + + /** 当前业务对应的待办任务 */ + private HrmFlowTaskVo currentTask; + + /** 当前业务对应的全部任务历史 */ + private List taskHistory; + + /** 当前流程实例状态 */ + private String flowStatus; + + /** 当前节点ID */ + private Long currentNodeId; + + /** 当前节点名称 */ + private String currentNodeName; + + /** 审批是否通过 */ + private Boolean approved; + + /** 流程动作历史(更细粒度) */ + private List actionTimeline; +} diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/service/IHrmFlowTaskService.java b/fad-hrm/src/main/java/com/ruoyi/hrm/service/IHrmFlowTaskService.java index d2c5f60..7cb017b 100644 --- a/fad-hrm/src/main/java/com/ruoyi/hrm/service/IHrmFlowTaskService.java +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/service/IHrmFlowTaskService.java @@ -2,8 +2,8 @@ package com.ruoyi.hrm.service; import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.page.TableDataInfo; -import com.ruoyi.hrm.domain.HrmFlowTask; import com.ruoyi.hrm.domain.bo.HrmFlowTaskBo; +import com.ruoyi.hrm.domain.vo.HrmFlowTaskDetailVo; import com.ruoyi.hrm.domain.vo.HrmFlowTaskVo; import java.util.Collection; @@ -51,4 +51,9 @@ public interface IHrmFlowTaskService { * 根据业务类型 + 业务ID 查询当前待办任务(pending),用于详情页自动带出 currentTaskId */ HrmFlowTaskVo queryTodoByBiz(String bizType, Long bizId, Long assigneeUserId); + + /** + * 按业务查询详情:当前待办、状态和历史审批记录 + */ + HrmFlowTaskDetailVo queryDetailByBiz(String bizType, Long bizId, Long assigneeUserId); } diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowInstanceServiceImpl.java b/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowInstanceServiceImpl.java index b51256e..a19d8e3 100644 --- a/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowInstanceServiceImpl.java +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowInstanceServiceImpl.java @@ -75,6 +75,7 @@ public class HrmFlowInstanceServiceImpl implements IHrmFlowInstanceService { task.setNodeId(0L); task.setAssigneeUserId(bo.getManualAssigneeUserId()); task.setStatus("pending"); + task.setRemark("自选审批人一次性审批"); // 关键:写入业务关联字段,便于审批中心联查业务数据 task.setBizType(bo.getBizType()); task.setBizId(bo.getBizId()); @@ -121,6 +122,7 @@ public class HrmFlowInstanceServiceImpl implements IHrmFlowInstanceService { task.setNodeId(firstNode.getNodeId()); task.setAssigneeUserId(assignees.get(0)); task.setStatus("pending"); + task.setRemark(firstNode.getRemark()); // 关键:写入业务关联字段,便于审批中心联查业务数据 task.setBizType(bo.getBizType()); task.setBizId(bo.getBizId()); diff --git a/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowTaskServiceImpl.java b/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowTaskServiceImpl.java index f2a945d..9083a74 100644 --- a/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowTaskServiceImpl.java +++ b/fad-hrm/src/main/java/com/ruoyi/hrm/service/impl/HrmFlowTaskServiceImpl.java @@ -12,6 +12,8 @@ import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.hrm.domain.*; import com.ruoyi.hrm.domain.bo.HrmFlowTaskBo; import com.ruoyi.hrm.domain.bo.HrmSealStampBo; +import com.ruoyi.hrm.domain.vo.HrmFlowActionTimelineVo; +import com.ruoyi.hrm.domain.vo.HrmFlowTaskDetailVo; import com.ruoyi.hrm.domain.vo.HrmFlowTaskVo; import com.ruoyi.hrm.domain.vo.HrmEmployeeVo; import com.ruoyi.hrm.mapper.*; @@ -40,7 +42,6 @@ public class HrmFlowTaskServiceImpl implements IHrmFlowTaskService { private final FlowAssigneeHelper assigneeHelper; private final BizStatusSyncHelper bizStatusSyncHelper; - private final HrmFlowTaskMapper hrmFlowTaskMapper; // 注入五个业务Mapper private final HrmLeaveReqMapper leaveReqMapper; private final HrmTravelReqMapper travelReqMapper; @@ -185,12 +186,13 @@ private void fillBizData(List tasks) { if (inst == null) { return false; } + Long operatorUserId = actionUserId != null ? actionUserId : LoginHelper.getUserId(); // 无模板一次性审批(tplId=0 或 nodeId=0):直接结束流程 if (inst.getTplId() != null && inst.getTplId() == 0L) { // 记录动作 - saveAction(taskId, inst.getInstId(), "approve", remark, actionUserId,task.getBizType(), task.getBizId()); + saveAction(taskId, inst.getInstId(), task.getBizType(), task.getBizId(), task.getAssigneeUserId(), "approve", remark, operatorUserId); if (stampBo != null) { - saveAction(taskId, inst.getInstId(), "stamp", "盖章", actionUserId,task.getBizType(), task.getBizId()); + saveAction(taskId, inst.getInstId(), task.getBizType(), task.getBizId(), task.getAssigneeUserId(), "stamp", "盖章", operatorUserId); } task.setStatus("approved"); baseMapper.updateById(task); @@ -202,7 +204,7 @@ private void fillBizData(List tasks) { sealReqService.updateStatus(inst.getBizId(), "approved"); if (stampBo != null) { // 盖章动作也写入流转历史 - saveAction(taskId, inst.getInstId(), "stamp", "盖章", actionUserId,task.getBizType(), task.getBizId()); + saveAction(taskId, inst.getInstId(), task.getBizType(), task.getBizId(), task.getAssigneeUserId(), "stamp", "盖章", operatorUserId); sealReqService.stampWithJava(inst.getBizId(), stampBo); } } @@ -215,7 +217,7 @@ private void fillBizData(List tasks) { return false; } // 记录动作 - saveAction(taskId, inst.getInstId(), "approve", remark, actionUserId,task.getBizType(),task.getBizId()); + saveAction(taskId, inst.getInstId(), task.getBizType(), task.getBizId(), task.getAssigneeUserId(), "approve", remark, operatorUserId); // 完成当前任务 task.setStatus("approved"); baseMapper.updateById(task); @@ -299,7 +301,8 @@ private void fillBizData(List tasks) { if (inst == null) { return false; } - saveAction(taskId, inst.getInstId(), "reject", remark, actionUserId,task.getBizType(),task.getBizId()); + Long operatorUserId = actionUserId != null ? actionUserId : LoginHelper.getUserId(); + saveAction(taskId, inst.getInstId(), task.getBizType(), task.getBizId(), task.getAssigneeUserId(), "reject", remark, operatorUserId); task.setStatus("rejected"); baseMapper.updateById(task); inst.setStatus("rejected"); @@ -323,7 +326,8 @@ private void fillBizData(List tasks) { if (inst == null) { return false; } - saveAction(taskId, inst.getInstId(), "withdraw", remark, actionUserId, task.getBizType(), task.getBizId()); + Long operatorUserId = actionUserId != null ? actionUserId : LoginHelper.getUserId(); + saveAction(taskId, inst.getInstId(), task.getBizType(), task.getBizId(), task.getAssigneeUserId(), "withdraw", remark, operatorUserId); task.setStatus("withdraw"); baseMapper.updateById(task); // 无模板一次性审批:撤回后业务回到 pending,并重新生成一个待办(仍然只允许一次审批) @@ -360,13 +364,13 @@ private void fillBizData(List tasks) { return true; } - private void saveAction(Long taskId, Long instId, String action, String remark, Long userId, String bizType, Long bizId) { + private void saveAction(Long taskId, Long instId, String bizType, Long bizId, Long assigneeUserId, String action, String remark, Long actionUserId) { HrmFlowAction log = new HrmFlowAction(); log.setTaskId(taskId); log.setInstId(instId); log.setAction(action); log.setRemark(remark); - log.setActionUserId(userId); + log.setActionUserId(actionUserId); log.setCreateTime(new Date()); log.setBizType(bizType); log.setBizId(bizId); @@ -388,7 +392,8 @@ private void fillBizData(List tasks) { return false; } // 记录动作 - saveAction(taskId, inst.getInstId(), "transfer", remark, actionUserId, task.getBizType(), task.getBizId()); + Long operatorUserId = actionUserId != null ? actionUserId : LoginHelper.getUserId(); + saveAction(taskId, inst.getInstId(), task.getBizType(), task.getBizId(), newAssigneeUserId, "transfer", remark, operatorUserId); // 更新办理人 HrmFlowTask u = new HrmFlowTask(); @@ -399,7 +404,6 @@ private void fillBizData(List tasks) { @Override public HrmFlowTaskVo queryTodoByBiz(String bizType, Long bizId, Long assigneeUserId) { - // 只取"待办 pending"的一条(理论上同一 biz 同一时刻最多一条待办) LambdaQueryWrapper lqw = Wrappers.lambdaQuery() .eq(bizType != null, HrmFlowTask::getBizType, bizType) .eq(bizId != null, HrmFlowTask::getBizId, bizId) @@ -408,12 +412,118 @@ private void fillBizData(List tasks) { .orderByDesc(HrmFlowTask::getTaskId) .last("limit 1"); HrmFlowTaskVo hrmFlowTaskVo = baseMapper.selectVoOne(lqw); - if (hrmFlowTaskVo != null) { + if (hrmFlowTaskVo != null && hrmFlowTaskVo.getAssigneeUserId() != null) { hrmFlowTaskVo.setAssigneeNickName(userService.selectNickNameById(hrmFlowTaskVo.getAssigneeUserId())); } return hrmFlowTaskVo; } + @Override + public HrmFlowTaskDetailVo queryDetailByBiz(String bizType, Long bizId, Long assigneeUserId) { + HrmFlowTaskDetailVo result = new HrmFlowTaskDetailVo(); + HrmFlowTaskVo currentTask = queryTodoByBiz(bizType, bizId, assigneeUserId); + result.setCurrentTask(currentTask); + + LambdaQueryWrapper historyQ = Wrappers.lambdaQuery() + .eq(bizType != null, HrmFlowTask::getBizType, bizType) + .eq(bizId != null, HrmFlowTask::getBizId, bizId) + .orderByAsc(HrmFlowTask::getCreateTime); + List histories = baseMapper.selectVoList(historyQ); + if (histories != null) { + histories.forEach(task -> { + if (task.getAssigneeUserId() != null) { + task.setAssigneeNickName(userService.selectNickNameById(task.getAssigneeUserId())); + } + }); + } + result.setTaskHistory(histories == null ? Collections.emptyList() : histories); + + HrmFlowInstance inst = instanceMapper.selectOne(Wrappers.lambdaQuery() + .eq(bizType != null, HrmFlowInstance::getBizType, bizType) + .eq(bizId != null, HrmFlowInstance::getBizId, bizId) + .orderByDesc(HrmFlowInstance::getInstId) + .last("limit 1")); + if (inst != null) { + result.setFlowStatus(inst.getStatus()); + result.setCurrentNodeId(inst.getCurrentNodeId()); + HrmFlowNode node = inst.getCurrentNodeId() == null ? null : nodeMapper.selectById(inst.getCurrentNodeId()); + if (node != null) { + result.setCurrentNodeName(node.getRemark()); + } + result.setApproved(Boolean.valueOf("approved".equalsIgnoreCase(inst.getStatus()))); + } + + result.setActionTimeline(buildActionTimeline(bizType, bizId)); + return result; + } + + private List buildActionTimeline(String bizType, Long bizId) { + LambdaQueryWrapper actionQ = Wrappers.lambdaQuery() + .eq(bizType != null, HrmFlowAction::getBizType, bizType) + .eq(bizId != null, HrmFlowAction::getBizId, bizId) + .orderByAsc(HrmFlowAction::getCreateTime); + List actions = actionMapper.selectList(actionQ); + if (actions == null || actions.isEmpty()) { + return Collections.emptyList(); + } + + Map taskMap = new HashMap<>(); + List taskIds = actions.stream().map(HrmFlowAction::getTaskId).filter(Objects::nonNull).distinct().collect(Collectors.toList()); + if (!taskIds.isEmpty()) { + baseMapper.selectBatchIds(taskIds).forEach(task -> taskMap.put(task.getTaskId(), task)); + } + + List timelines = new ArrayList(); + for (HrmFlowAction action : actions) { + HrmFlowActionTimelineVo vo = new HrmFlowActionTimelineVo(); + vo.setActionId(action.getActionId()); + vo.setTaskId(action.getTaskId()); + vo.setInstId(action.getInstId()); + vo.setActionUserId(action.getActionUserId()); + vo.setActionUserName(action.getActionUserId() == null ? null : userService.selectNickNameById(action.getActionUserId())); + vo.setAction(action.getAction()); + vo.setActionText(actionText(action.getAction())); + vo.setRemark(action.getRemark()); + vo.setBizType(action.getBizType()); + vo.setBizId(action.getBizId()); + HrmFlowTask task = taskMap.get(action.getTaskId()); + if (task != null) { + vo.setNodeId(task.getNodeId()); + vo.setTaskStatus(task.getStatus()); + HrmFlowNode node = task.getNodeId() == null ? null : nodeMapper.selectById(task.getNodeId()); + if (node != null) { + vo.setNodeName(node.getRemark()); + } + } + vo.setCreateTime(action.getCreateTime()); + timelines.add(vo); + } + return timelines; + } + + private String actionText(String action) { + if (action == null) { + return "-"; + } + String lower = action.toLowerCase(); + if ("approve".equals(lower)) { + return "通过"; + } + if ("reject".equals(lower)) { + return "驳回"; + } + if ("withdraw".equals(lower)) { + return "撤回"; + } + if ("transfer".equals(lower)) { + return "转办"; + } + if ("stamp".equals(lower)) { + return "盖章"; + } + return action; + } + private LambdaQueryWrapper buildQueryWrapper(HrmFlowTaskBo bo) { LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); lqw.eq(bo.getTaskId() != null, HrmFlowTask::getTaskId, bo.getTaskId()); diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaCityController.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaCityController.java new file mode 100644 index 0000000..ba17bfb --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/controller/OaCityController.java @@ -0,0 +1,62 @@ +package com.ruoyi.oa.controller; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.annotation.RepeatSubmit; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.domain.R; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.core.validate.AddGroup; +import com.ruoyi.common.core.validate.EditGroup; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.oa.domain.bo.OaCityBo; +import com.ruoyi.oa.domain.vo.OaCityVo; +import com.ruoyi.oa.service.IOaCityService; +import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.Arrays; +import java.util.List; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/oa/city") +@Validated +public class OaCityController extends BaseController { + + private final IOaCityService cityService; + + @GetMapping("/list") + public TableDataInfo list(OaCityBo bo, PageQuery pageQuery) { + return cityService.queryPageList(bo, pageQuery); + } + + @GetMapping("/{cityId}") + public R getInfo(@NotNull(message = "主键不能为空") @PathVariable Long cityId) { + return R.ok(cityService.queryById(cityId)); + } + + @Log(title = "城市管理", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping + public R add(@Validated(AddGroup.class) @RequestBody OaCityBo bo) { + return toAjax(cityService.insertByBo(bo)); + } + + @Log(title = "城市管理", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping + public R edit(@Validated(EditGroup.class) @RequestBody OaCityBo bo) { + return toAjax(cityService.updateByBo(bo)); + } + + @Log(title = "城市管理", businessType = BusinessType.DELETE) + @DeleteMapping("/{cityIds}") + public R remove(@NotEmpty(message = "主键不能为空") @PathVariable Long[] cityIds) { + return toAjax(cityService.deleteWithValidByIds(Arrays.asList(cityIds), true)); + } +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaCity.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaCity.java new file mode 100644 index 0000000..77e92dc --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/OaCity.java @@ -0,0 +1,37 @@ +package com.ruoyi.oa.domain; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 城市管理对象 oa_city + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("oa_city") +public class OaCity extends BaseEntity { + + private static final long serialVersionUID = 1L; + + @TableId(value = "city_id") + private Long cityId; + + /** 国家 */ + private String countryName; + + /** 城市 */ + private String cityName; + + /** 状态 1正常 0禁用 */ + private Long status; + + /** 备注 */ + private String remark; + + @TableLogic + private Integer delFlag; +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaCityBo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaCityBo.java new file mode 100644 index 0000000..e6d26ad --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/bo/OaCityBo.java @@ -0,0 +1,28 @@ +package com.ruoyi.oa.domain.bo; + +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; + +/** + * 城市管理业务对象 oa_city + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class OaCityBo extends BaseEntity { + + private Long cityId; + + @NotBlank(message = "国家不能为空") + private String countryName; + + @NotBlank(message = "城市不能为空") + private String cityName; + + private Long status; + + private String remark; +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaCityVo.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaCityVo.java new file mode 100644 index 0000000..a6c85b7 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/domain/vo/OaCityVo.java @@ -0,0 +1,23 @@ +package com.ruoyi.oa.domain.vo; + +import com.ruoyi.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 城市管理视图对象 oa_city + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class OaCityVo extends BaseEntity { + + private Long cityId; + + private String countryName; + + private String cityName; + + private Long status; + + private String remark; +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaCityMapper.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaCityMapper.java new file mode 100644 index 0000000..29229e2 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/mapper/OaCityMapper.java @@ -0,0 +1,11 @@ +package com.ruoyi.oa.mapper; + +import com.ruoyi.common.core.mapper.BaseMapperPlus; +import com.ruoyi.oa.domain.OaCity; +import com.ruoyi.oa.domain.vo.OaCityVo; + +/** + * 城市管理 Mapper + */ +public interface OaCityMapper extends BaseMapperPlus { +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaCityService.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaCityService.java new file mode 100644 index 0000000..cd76cc7 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/IOaCityService.java @@ -0,0 +1,24 @@ +package com.ruoyi.oa.service; + +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.oa.domain.bo.OaCityBo; +import com.ruoyi.oa.domain.vo.OaCityVo; + +import java.util.Collection; +import java.util.List; + +public interface IOaCityService { + + OaCityVo queryById(Long cityId); + + TableDataInfo queryPageList(OaCityBo bo, PageQuery pageQuery); + + List queryList(OaCityBo bo); + + Boolean insertByBo(OaCityBo bo); + + Boolean updateByBo(OaCityBo bo); + + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaCityServiceImpl.java b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaCityServiceImpl.java new file mode 100644 index 0000000..04c7dc7 --- /dev/null +++ b/ruoyi-oa/src/main/java/com/ruoyi/oa/service/impl/OaCityServiceImpl.java @@ -0,0 +1,73 @@ +package com.ruoyi.oa.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.ruoyi.common.core.domain.PageQuery; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.oa.domain.OaCity; +import com.ruoyi.oa.domain.bo.OaCityBo; +import com.ruoyi.oa.domain.vo.OaCityVo; +import com.ruoyi.oa.mapper.OaCityMapper; +import com.ruoyi.oa.service.IOaCityService; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Collection; +import java.util.List; + +@RequiredArgsConstructor +@Service +public class OaCityServiceImpl implements IOaCityService { + + private final OaCityMapper baseMapper; + + @Override + public OaCityVo queryById(Long cityId) { + return baseMapper.selectVoById(cityId); + } + + @Override + public TableDataInfo queryPageList(OaCityBo bo, PageQuery pageQuery) { + IPage page = baseMapper.selectVoPage(pageQuery.build(), buildQueryWrapper(bo)); + TableDataInfo tableDataInfo = new TableDataInfo<>(page.getRecords(), page.getTotal()); + return tableDataInfo; + } + + @Override + public List queryList(OaCityBo bo) { + return baseMapper.selectVoList(buildQueryWrapper(bo)); + } + + @Override + public Boolean insertByBo(OaCityBo bo) { + OaCity add = BeanUtil.toBean(bo, OaCity.class); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setCityId(add.getCityId()); + } + return flag; + } + + @Override + public Boolean updateByBo(OaCityBo bo) { + OaCity update = BeanUtil.toBean(bo, OaCity.class); + return baseMapper.updateById(update) > 0; + } + + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + return baseMapper.deleteBatchIds(ids) > 0; + } + + private LambdaQueryWrapper buildQueryWrapper(OaCityBo bo) { + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.like(StringUtils.isNotBlank(bo.getCountryName()), OaCity::getCountryName, bo.getCountryName()); + lqw.like(StringUtils.isNotBlank(bo.getCityName()), OaCity::getCityName, bo.getCityName()); + lqw.eq(bo.getStatus() != null, OaCity::getStatus, bo.getStatus()); + lqw.orderByDesc(OaCity::getCreateTime); + return lqw; + } +} diff --git a/sql/oa_city.sql b/sql/oa_city.sql new file mode 100644 index 0000000..65ac053 --- /dev/null +++ b/sql/oa_city.sql @@ -0,0 +1,24 @@ +-- 城市管理表 oa_city +DROP TABLE IF EXISTS oa_city; +CREATE TABLE oa_city ( + city_id BIGINT NOT NULL AUTO_INCREMENT COMMENT '城市主键ID', + country_name VARCHAR(64) NOT NULL COMMENT '国家', + city_name VARCHAR(64) NOT NULL COMMENT '城市', + status BIGINT DEFAULT 1 COMMENT '状态 1正常 0禁用', + remark VARCHAR(500) DEFAULT NULL COMMENT '备注', + del_flag TINYINT DEFAULT 0 COMMENT '删除标志:0=正常,1=已删除', + create_by VARCHAR(64) DEFAULT '' COMMENT '创建者', + create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + update_by VARCHAR(64) DEFAULT '' COMMENT '更新者', + update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (city_id), + KEY idx_country_name (country_name), + KEY idx_city_name (city_name) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='城市管理表'; + +INSERT INTO oa_city (country_name, city_name, status, remark) VALUES +('中国', '北京', 1, '默认城市'), +('中国', '上海', 1, '默认城市'), +('中国', '广州', 1, '默认城市'), +('中国', '深圳', 1, '默认城市'), +('中国', '杭州', 1, '默认城市');