This commit is contained in:
2025-09-15 12:42:57 +08:00
parent 310b80fac3
commit 9c3e11fa50
15 changed files with 263 additions and 61 deletions

View File

@@ -206,22 +206,31 @@ public class BizModuleController extends BaseController {
if (!"0".equals(current.getStatus())) { if (!"0".equals(current.getStatus())) {
return AjaxResult.error("仅可指派待接取的模块"); return AjaxResult.error("仅可指派待接取的模块");
} }
// 前端传递的是用户名需要转换为用户ID // 仅使用用户ID。优先使用前端传来的 designatedUser
if (bizModule.getAssignee() != null && !bizModule.getAssignee().isEmpty()) { // 如为兼容历史,若未提供 designatedUser 而提供了 assignee则尝试解析/转换为ID。
Long targetUserId = bizModule.getDesignatedUser();
if (targetUserId == null) {
String assigneeRaw = bizModule.getAssignee();
if (assigneeRaw != null && !assigneeRaw.isEmpty()) {
try { try {
// 先尝试解析为数字用户ID targetUserId = Long.parseLong(assigneeRaw);
Long userId = Long.parseLong(bizModule.getAssignee());
bizModule.setDesignatedUser(userId);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
// 如果不是数字说明是用户名需要查询用户ID SysUser user = userService.selectUserByUserName(assigneeRaw);
SysUser user = userService.selectUserByUserName(bizModule.getAssignee());
if (user != null) { if (user != null) {
bizModule.setDesignatedUser(user.getUserId()); targetUserId = user.getUserId();
} else { }
}
}
}
if (targetUserId == null) {
return AjaxResult.error("请选择要指派的用户");
}
// 校验用户是否存在
SysUser designated = userService.selectUserById(targetUserId);
if (designated == null) {
return AjaxResult.error("用户不存在"); return AjaxResult.error("用户不存在");
} }
} bizModule.setDesignatedUser(targetUserId);
}
return toAjax(bizModuleService.assignModule(bizModule)); return toAjax(bizModuleService.assignModule(bizModule));
} }

View File

@@ -24,6 +24,8 @@ import com.ruoyi.models.domain.BizModule;
import com.ruoyi.models.service.IBizSubModuleService; import com.ruoyi.models.service.IBizSubModuleService;
import com.ruoyi.models.service.IBizModuleService; import com.ruoyi.models.service.IBizModuleService;
import com.ruoyi.project.service.IBizProjectService; import com.ruoyi.project.service.IBizProjectService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.common.core.domain.entity.SysUser;
/** /**
* 子模块Controller * 子模块Controller
@@ -41,6 +43,9 @@ public class BizSubModuleController extends BaseController
@Autowired @Autowired
private IBizProjectService projectService; private IBizProjectService projectService;
@Autowired
private ISysUserService userService;
/** /**
* 查询子模块列表(按条件) * 查询子模块列表(按条件)
*/ */
@@ -91,14 +96,24 @@ public class BizSubModuleController extends BaseController
// 仅模块接取人可新增子模块兼容历史assignee 可能存为 用户ID/用户名/昵称) // 仅模块接取人可新增子模块兼容历史assignee 可能存为 用户ID/用户名/昵称)
Long currentUserId = getUserId(); Long currentUserId = getUserId();
boolean isAssignee = false; boolean isAssignee = false;
if (module.getAssignee() != null) // 1) 优先使用标准 assigneeId 判断
{ if (module.getAssigneeId() != null && module.getAssigneeId().equals(currentUserId)) {
isAssignee = true;
} else if (module.getAssignee() != null) {
// 2) 历史兼容assignee 可能保存为 用户ID/用户名/昵称
if (String.valueOf(currentUserId).equals(module.getAssignee())) { if (String.valueOf(currentUserId).equals(module.getAssignee())) {
isAssignee = true; isAssignee = true;
} else { } else {
String username = getUsername(); String username = getUsername();
if (username != null && username.equals(module.getAssignee())) { if (username != null && username.equals(module.getAssignee())) {
isAssignee = true; isAssignee = true;
} else {
try {
SysUser u = userService.selectUserById(currentUserId);
if (u != null && u.getNickName() != null && u.getNickName().equals(module.getAssignee())) {
isAssignee = true;
}
} catch (Exception ignored) {}
} }
} }
} }
@@ -131,12 +146,22 @@ public class BizSubModuleController extends BaseController
Long currentUserId = getUserId(); Long currentUserId = getUserId();
String username = getUsername(); String username = getUsername();
boolean isAssignee = false; boolean isAssignee = false;
if (module != null && module.getAssignee() != null) if (module != null) {
{ if (module.getAssigneeId() != null && module.getAssigneeId().equals(currentUserId)) {
isAssignee = true;
} else if (module.getAssignee() != null) {
if (String.valueOf(currentUserId).equals(module.getAssignee())) { if (String.valueOf(currentUserId).equals(module.getAssignee())) {
isAssignee = true; isAssignee = true;
} else if (username != null && username.equals(module.getAssignee())) { } else if (username != null && username.equals(module.getAssignee())) {
isAssignee = true; isAssignee = true;
} else {
try {
SysUser u = userService.selectUserById(currentUserId);
if (u != null && u.getNickName() != null && u.getNickName().equals(module.getAssignee())) {
isAssignee = true;
}
} catch (Exception ignored) {}
}
} }
} }
if (!isAssignee) if (!isAssignee)
@@ -163,12 +188,22 @@ public class BizSubModuleController extends BaseController
Long currentUserId = getUserId(); Long currentUserId = getUserId();
String username = getUsername(); String username = getUsername();
boolean isAssignee = false; boolean isAssignee = false;
if (module != null && module.getAssignee() != null) if (module != null) {
{ if (module.getAssigneeId() != null && module.getAssigneeId().equals(currentUserId)) {
isAssignee = true;
} else if (module.getAssignee() != null) {
if (String.valueOf(currentUserId).equals(module.getAssignee())) { if (String.valueOf(currentUserId).equals(module.getAssignee())) {
isAssignee = true; isAssignee = true;
} else if (username != null && username.equals(module.getAssignee())) { } else if (username != null && username.equals(module.getAssignee())) {
isAssignee = true; isAssignee = true;
} else {
try {
SysUser u = userService.selectUserById(currentUserId);
if (u != null && u.getNickName() != null && u.getNickName().equals(module.getAssignee())) {
isAssignee = true;
}
} catch (Exception ignored) {}
}
} }
} }
if (!isAssignee) if (!isAssignee)

View File

@@ -36,6 +36,9 @@ public class BizModule extends BaseEntity
@Excel(name = "接取人") @Excel(name = "接取人")
private String assignee; private String assignee;
/** 接取人用户ID仅用于前端判定不导出 */
private Long assigneeId;
/** 接取时间 */ /** 接取时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "接取时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss") @Excel(name = "接取时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
@@ -58,6 +61,9 @@ public class BizModule extends BaseEntity
/** 项目名称 */ /** 项目名称 */
private String projectName; private String projectName;
/** 模块备注/描述 */
private String remark;
public void setModuleId(Long moduleId) public void setModuleId(Long moduleId)
{ {
this.moduleId = moduleId; this.moduleId = moduleId;
@@ -108,6 +114,16 @@ public class BizModule extends BaseEntity
return assignee; return assignee;
} }
public Long getAssigneeId()
{
return assigneeId;
}
public void setAssigneeId(Long assigneeId)
{
this.assigneeId = assigneeId;
}
public void setAssignTime(Date assignTime) public void setAssignTime(Date assignTime)
{ {
this.assignTime = assignTime; this.assignTime = assignTime;
@@ -168,6 +184,14 @@ public class BizModule extends BaseEntity
return projectName; return projectName;
} }
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -177,6 +201,7 @@ public class BizModule extends BaseEntity
.append("moduleName", getModuleName()) .append("moduleName", getModuleName())
.append("status", getStatus()) .append("status", getStatus())
.append("assignee", getAssignee()) .append("assignee", getAssignee())
.append("assigneeId", getAssigneeId())
.append("assignTime", getAssignTime()) .append("assignTime", getAssignTime())
.append("finishTime", getFinishTime()) .append("finishTime", getFinishTime())
.append("designatedUser", getDesignatedUser()) .append("designatedUser", getDesignatedUser())
@@ -184,6 +209,7 @@ public class BizModule extends BaseEntity
.append("delFlag", getDelFlag()) .append("delFlag", getDelFlag())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("remark", getRemark())
.toString(); .toString();
} }
} }

View File

@@ -57,10 +57,19 @@ public class BizModuleServiceImpl implements IBizModuleService {
public List<BizModule> selectBizModuleList(BizModule bizModule) { public List<BizModule> selectBizModuleList(BizModule bizModule) {
Long userId = SecurityUtils.getUserId(); Long userId = SecurityUtils.getUserId();
boolean isAdmin = SecurityUtils.isAdmin(userId); boolean isAdmin = SecurityUtils.isAdmin(userId);
boolean isPlatformAdmin = false;
try {
com.ruoyi.common.core.domain.entity.SysUser u = com.ruoyi.common.utils.SecurityUtils.getLoginUser().getUser();
if (u != null && u.getRoles() != null) {
for (com.ruoyi.common.core.domain.entity.SysRole r : u.getRoles()) {
if (r != null && "platform_admin".equals(r.getRoleKey())) { isPlatformAdmin = true; break; }
}
}
} catch (Exception ignored) {}
// 设置查询参数,用于权限控制 // 设置查询参数,用于权限控制(平台管理员或超管看全部)
bizModule.getParams().put("currentUserId", userId); bizModule.getParams().put("currentUserId", userId);
bizModule.getParams().put("isAdmin", isAdmin); bizModule.getParams().put("isAdmin", isAdmin || isPlatformAdmin);
return bizModuleMapper.selectBizModuleList(bizModule); return bizModuleMapper.selectBizModuleList(bizModule);
} }
@@ -150,17 +159,8 @@ public class BizModuleServiceImpl implements IBizModuleService {
} }
module.setStatus("1"); // 进行中 module.setStatus("1"); // 进行中
// 设置接取人为用户名非ID // 统一用用户ID字符串保存避免用户改名导致前端判断与展示异常
try {
SysUser u = sysUserService.selectUserById(userId);
if (u != null && u.getUserName() != null) {
module.setAssignee(u.getUserName());
} else {
module.setAssignee(String.valueOf(userId)); module.setAssignee(String.valueOf(userId));
}
} catch (Exception ex) {
module.setAssignee(String.valueOf(userId));
}
module.setAssignTime(DateUtils.getNowDate()); module.setAssignTime(DateUtils.getNowDate());
// 避免重复接取:若已有相同 moduleId 的进行中记录,这里只更新而不新增 // 避免重复接取:若已有相同 moduleId 的进行中记录,这里只更新而不新增
return updateBizModule(module); return updateBizModule(module);

View File

@@ -11,6 +11,8 @@ import com.ruoyi.models.mapper.BizModuleMapper;
import com.ruoyi.models.domain.BizSubModule; import com.ruoyi.models.domain.BizSubModule;
import com.ruoyi.models.domain.BizModule; import com.ruoyi.models.domain.BizModule;
import com.ruoyi.models.service.IBizSubModuleService; import com.ruoyi.models.service.IBizSubModuleService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.common.core.domain.entity.SysUser;
/** /**
* 子模块Service业务层处理 * 子模块Service业务层处理
@@ -24,6 +26,9 @@ public class BizSubModuleServiceImpl implements IBizSubModuleService
@Autowired @Autowired
private BizModuleMapper moduleMapper; private BizModuleMapper moduleMapper;
@Autowired
private ISysUserService sysUserService;
@Override @Override
public BizSubModule selectBizSubModuleBySubId(Long subId) public BizSubModule selectBizSubModuleBySubId(Long subId)
{ {
@@ -84,9 +89,24 @@ public class BizSubModuleServiceImpl implements IBizSubModuleService
throw new RuntimeException("父模块不存在"); throw new RuntimeException("父模块不存在");
} }
String currentUsername = SecurityUtils.getUsername(); String currentUsername = SecurityUtils.getUsername();
if (!(String.valueOf(userId).equals(module.getAssignee()) boolean allowed = false;
|| (module.getAssignee() != null && module.getAssignee().equals(currentUsername)))) if (module.getAssigneeId() != null && module.getAssigneeId().equals(userId)) {
{ allowed = true;
} else if (module.getAssignee() != null) {
if (String.valueOf(userId).equals(module.getAssignee())) {
allowed = true;
} else if (module.getAssignee().equals(currentUsername)) {
allowed = true;
} else {
try {
SysUser u = sysUserService.selectUserById(userId);
if (u != null && u.getNickName() != null && u.getNickName().equals(module.getAssignee())) {
allowed = true;
}
} catch (Exception ignored) {}
}
}
if (!allowed) {
throw new RuntimeException("仅父模块接取人可接取子模块"); throw new RuntimeException("仅父模块接取人可接取子模块");
} }
@@ -111,9 +131,24 @@ public class BizSubModuleServiceImpl implements IBizSubModuleService
throw new RuntimeException("父模块不存在"); throw new RuntimeException("父模块不存在");
} }
String currentUsername2 = SecurityUtils.getUsername(); String currentUsername2 = SecurityUtils.getUsername();
if (!(String.valueOf(userId).equals(module.getAssignee()) boolean allowed2 = false;
|| (module.getAssignee() != null && module.getAssignee().equals(currentUsername2)))) if (module.getAssigneeId() != null && module.getAssigneeId().equals(userId)) {
{ allowed2 = true;
} else if (module.getAssignee() != null) {
if (String.valueOf(userId).equals(module.getAssignee())) {
allowed2 = true;
} else if (module.getAssignee().equals(currentUsername2)) {
allowed2 = true;
} else {
try {
SysUser u = sysUserService.selectUserById(userId);
if (u != null && u.getNickName() != null && u.getNickName().equals(module.getAssignee())) {
allowed2 = true;
}
} catch (Exception ignored) {}
}
}
if (!allowed2) {
throw new RuntimeException("仅父模块接取人可完成子模块"); throw new RuntimeException("仅父模块接取人可完成子模块");
} }

View File

@@ -62,6 +62,23 @@ public class BizDocController extends BaseController
public TableDataInfo list(BizDoc bizDoc) public TableDataInfo list(BizDoc bizDoc)
{ {
startPage(); startPage();
// 平台管理员查看所有项目/模块文档
try {
com.ruoyi.common.core.domain.entity.SysUser u = com.ruoyi.common.utils.SecurityUtils.getLoginUser().getUser();
boolean platformAdmin = false;
if (u != null && u.getRoles() != null) {
for (com.ruoyi.common.core.domain.entity.SysRole r : u.getRoles()) {
if (r != null && "platform_admin".equals(r.getRoleKey())) { platformAdmin = true; break; }
}
}
if (platformAdmin) {
// 放宽权限过滤:清空 currentUserId/username 参数,使服务层不过滤
if (bizDoc.getParams() != null) {
bizDoc.getParams().remove("currentUserId");
bizDoc.getParams().remove("currentUsername");
}
}
} catch (Exception ignored) {}
List<BizDoc> list = bizDocService.selectBizDocList(bizDoc); List<BizDoc> list = bizDocService.selectBizDocList(bizDoc);
return getDataTable(list); return getDataTable(list);
} }

View File

@@ -47,6 +47,9 @@ public class BizDoc extends BaseEntity
/** 项目名称(展示用) */ /** 项目名称(展示用) */
private String projectName; private String projectName;
/** 模块名称(展示用,模块文档时有值) */
private String moduleName;
public void setDocId(Long docId) public void setDocId(Long docId)
{ {
this.docId = docId; this.docId = docId;
@@ -149,6 +152,16 @@ public class BizDoc extends BaseEntity
this.projectName = projectName; this.projectName = projectName;
} }
public String getModuleName()
{
return moduleName;
}
public void setModuleName(String moduleName)
{
this.moduleName = moduleName;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -163,6 +176,7 @@ public class BizDoc extends BaseEntity
.append("docContent", getDocContent() == null ? null : (getDocContent().length + " bytes")) .append("docContent", getDocContent() == null ? null : (getDocContent().length + " bytes"))
.append("delFlag", getDelFlag()) .append("delFlag", getDelFlag())
.append("projectName", getProjectName()) .append("projectName", getProjectName())
.append("moduleName", getModuleName())
.toString(); .toString();
} }
} }

View File

@@ -54,6 +54,9 @@ public class BizProject extends BaseEntity
@Excel(name = "项目标签") @Excel(name = "项目标签")
private String projectLabel; private String projectLabel;
/** 备注/项目描述 */
private String remark;
/** 项目管理员名称 */ /** 项目管理员名称 */
@Excel(name = "项目管理员") @Excel(name = "项目管理员")
private String ownerName; private String ownerName;
@@ -184,6 +187,14 @@ public class BizProject extends BaseEntity
return completedModuleCount; return completedModuleCount;
} }
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -201,6 +212,7 @@ public class BizProject extends BaseEntity
.append("deadline", getDeadline()) .append("deadline", getDeadline())
.append("startTime", getStartTime()) .append("startTime", getStartTime())
.append("projectLabel", getProjectLabel()) .append("projectLabel", getProjectLabel())
.append("remark", getRemark())
.append("moduleCount", getModuleCount()) .append("moduleCount", getModuleCount())
.append("completedModuleCount", getCompletedModuleCount()) .append("completedModuleCount", getCompletedModuleCount())
.toString(); .toString();

View File

@@ -46,7 +46,18 @@ public class BizProjectServiceImpl implements IBizProjectService
public List<BizProject> selectBizProjectList(BizProject bizProject) public List<BizProject> selectBizProjectList(BizProject bizProject)
{ {
Long userId = SecurityUtils.getUserId(); Long userId = SecurityUtils.getUserId();
if (!SecurityUtils.isAdmin(userId)) { boolean superAdmin = SecurityUtils.isAdmin(userId);
boolean platformAdmin = false;
try {
com.ruoyi.common.core.domain.entity.SysUser u = com.ruoyi.common.utils.SecurityUtils.getLoginUser().getUser();
if (u != null && u.getRoles() != null) {
for (com.ruoyi.common.core.domain.entity.SysRole r : u.getRoles()) {
if (r != null && "platform_admin".equals(r.getRoleKey())) { platformAdmin = true; break; }
}
}
} catch (Exception ignored) {}
if (!superAdmin && !platformAdmin) {
// 设置查询参数,用于权限控制 // 设置查询参数,用于权限控制
bizProject.getParams().put("currentUserId", userId); bizProject.getParams().put("currentUserId", userId);
} }

View File

@@ -6,7 +6,7 @@ spring:
druid: druid:
# 主库数据源 # 主库数据源
master: master:
url: jdbc:mysql://127.0.0.1:13306/managersystem?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 url: jdbc:mysql://127.0.0.1:3306/managersystem?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root username: root
password: Wxit11335577 password: Wxit11335577
# 从库数据源 # 从库数据源

View File

@@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="moduleName" column="module_name" /> <result property="moduleName" column="module_name" />
<result property="status" column="status" /> <result property="status" column="status" />
<result property="assignee" column="assignee" /> <result property="assignee" column="assignee" />
<result property="assigneeId" column="assignee_id" />
<result property="assignTime" column="assign_time" /> <result property="assignTime" column="assign_time" />
<result property="finishTime" column="finish_time" /> <result property="finishTime" column="finish_time" />
<result property="delFlag" column="del_flag" /> <result property="delFlag" column="del_flag" />
@@ -17,6 +18,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
<result property="projectName" column="project_name" /> <result property="projectName" column="project_name" />
<result property="designatedUser" column="designated_user" /> <result property="designatedUser" column="designated_user" />
<result property="remark" column="remark" />
</resultMap> </resultMap>
<sql id="selectBizModuleVo"> <sql id="selectBizModuleVo">
@@ -25,13 +27,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
m.module_name, m.module_name,
m.status, m.status,
COALESCE(u1.nick_name, u1.user_name, u2.nick_name, u2.user_name, m.assignee) as assignee, COALESCE(u1.nick_name, u1.user_name, u2.nick_name, u2.user_name, m.assignee) as assignee,
m.assignee as assignee_raw,
COALESCE(u1.user_id, u2.user_id,
CASE WHEN m.assignee REGEXP '^[0-9]+$' THEN CAST(m.assignee AS UNSIGNED)
ELSE NULL END) as assignee_id,
m.assign_time, m.assign_time,
m.finish_time, m.finish_time,
m.del_flag, m.del_flag,
m.create_by, m.create_by,
m.create_time, m.create_time,
m.designated_user, m.designated_user,
p.project_name p.project_name,
m.remark
from biz_module m from biz_module m
left join biz_project p on m.project_id = p.project_id left join biz_project p on m.project_id = p.project_id
left join sys_user u1 on (m.assignee REGEXP '^[0-9]+$') and u1.user_id = CAST(m.assignee AS UNSIGNED) left join sys_user u1 on (m.assignee REGEXP '^[0-9]+$') and u1.user_id = CAST(m.assignee AS UNSIGNED)
@@ -60,7 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="assignTime != null "> and m.assign_time = #{assignTime}</if> <if test="assignTime != null "> and m.assign_time = #{assignTime}</if>
<if test="finishTime != null "> and m.finish_time = #{finishTime}</if> <if test="finishTime != null "> and m.finish_time = #{finishTime}</if>
and m.del_flag = '0' and m.del_flag = '0'
<!-- 权限控制:普通用户只能查看自己项目下的模块或被指派的模块;平台管理员可查看所有 --> <!-- 权限控制:普通用户只能查看自己项目下的模块或被指派的模块;平台管理员/超管可查看所有 -->
<if test="params != null and params.currentUserId != null and params.isAdmin != true"> <if test="params != null and params.currentUserId != null and params.isAdmin != true">
and ( and (
-- 自己是项目所有者 -- 自己是项目所有者
@@ -100,6 +107,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="assignee != null">assignee,</if> <if test="assignee != null">assignee,</if>
<if test="assignTime != null">assign_time,</if> <if test="assignTime != null">assign_time,</if>
<if test="finishTime != null">finish_time,</if> <if test="finishTime != null">finish_time,</if>
<if test="remark != null">remark,</if>
<if test="delFlag != null">del_flag,</if> <if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</if> <if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if> <if test="createTime != null">create_time,</if>
@@ -111,6 +119,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="assignee != null">#{assignee},</if> <if test="assignee != null">#{assignee},</if>
<if test="assignTime != null">#{assignTime},</if> <if test="assignTime != null">#{assignTime},</if>
<if test="finishTime != null">#{finishTime},</if> <if test="finishTime != null">#{finishTime},</if>
<if test="remark != null">#{remark},</if>
<if test="delFlag != null">#{delFlag},</if> <if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</if> <if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if> <if test="createTime != null">#{createTime},</if>
@@ -127,6 +136,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="assignTime != null">assign_time = #{assignTime},</if> <if test="assignTime != null">assign_time = #{assignTime},</if>
<if test="finishTime != null">finish_time = #{finishTime},</if> <if test="finishTime != null">finish_time = #{finishTime},</if>
<if test="designatedUser != null">designated_user = #{designatedUser},</if> <if test="designatedUser != null">designated_user = #{designatedUser},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="delFlag != null">del_flag = #{delFlag},</if> <if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="createBy != null">create_by = #{createBy},</if> <if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if> <if test="createTime != null">create_time = #{createTime},</if>
@@ -159,6 +169,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
m.module_name, m.module_name,
m.status, m.status,
COALESCE(u1.nick_name, u1.user_name, u2.nick_name, u2.user_name, m.assignee) as assignee, COALESCE(u1.nick_name, u1.user_name, u2.nick_name, u2.user_name, m.assignee) as assignee,
COALESCE(u1.user_id, u2.user_id,
CASE WHEN m.assignee REGEXP '^[0-9]+$' THEN CAST(m.assignee AS UNSIGNED)
ELSE NULL END) as assignee_id,
m.assign_time, m.assign_time,
m.finish_time, m.finish_time,
m.del_flag, m.del_flag,
@@ -167,7 +180,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
m.designated_user, m.designated_user,
m.update_by, m.update_by,
m.update_time, m.update_time,
p.project_name p.project_name,
m.remark
from biz_module m from biz_module m
left join biz_project p on m.project_id = p.project_id left join biz_project p on m.project_id = p.project_id
left join sys_user u1 on (m.assignee REGEXP '^[0-9]+$') and u1.user_id = CAST(m.assignee AS UNSIGNED) left join sys_user u1 on (m.assignee REGEXP '^[0-9]+$') and u1.user_id = CAST(m.assignee AS UNSIGNED)

View File

@@ -20,6 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" /> <result property="updateTime" column="update_time" />
<result property="projectName" column="project_name" /> <result property="projectName" column="project_name" />
<result property="moduleName" column="module_name" />
</resultMap> </resultMap>
<!-- 轻量字段:用于列表,排除大字段 doc_content --> <!-- 轻量字段:用于列表,排除大字段 doc_content -->
@@ -38,9 +39,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
d.upload_time as create_time, d.upload_time as create_time,
null as update_by, null as update_by,
null as update_time, null as update_time,
p.project_name as project_name p.project_name as project_name,
m.module_name as module_name
from biz_doc d from biz_doc d
left join biz_project p on p.project_id = d.project_id left join biz_project p on p.project_id = d.project_id
left join biz_module m on m.module_id = d.module_id
</sql> </sql>
<!-- 详情字段:下载/单条查询专用,含 doc_content --> <!-- 详情字段:下载/单条查询专用,含 doc_content -->
@@ -60,18 +63,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
d.upload_time as create_time, d.upload_time as create_time,
null as update_by, null as update_by,
null as update_time, null as update_time,
p.project_name as project_name p.project_name as project_name,
m.module_name as module_name
from biz_doc d from biz_doc d
left join biz_project p on p.project_id = d.project_id left join biz_project p on p.project_id = d.project_id
left join biz_module m on m.module_id = d.module_id
</sql> </sql>
<select id="selectBizDocList" parameterType="BizDoc" resultMap="BizDocResult"> <select id="selectBizDocList" parameterType="BizDoc" resultMap="BizDocResult">
<include refid="selectBizDocListVo"/> <include refid="selectBizDocListVo"/>
<where> <where>
<if test="docId != null and docId != ''"> and doc_id = #{docId}</if> <if test="docId != null and docId != ''"> and d.doc_id = #{docId}</if>
<if test="projectId != null and projectId != ''"> and d.project_id = #{projectId}</if> <if test="projectId != null and projectId != ''"> and d.project_id = #{projectId}</if>
<if test="moduleId != null and moduleId != ''"> and module_id = #{moduleId}</if> <if test="moduleId != null and moduleId != ''"> and d.module_id = #{moduleId}</if>
<if test="kindType != null and kindType != ''"> and kind_type = #{kindType}</if> <if test="kindType != null and kindType != ''"> and d.kind_type = #{kindType}</if>
<if test="docName != null and docName != ''"> and d.file_name like concat('%', #{docName}, '%')</if> <if test="docName != null and docName != ''"> and d.file_name like concat('%', #{docName}, '%')</if>
<if test="docPath != null and docPath != ''"> and d.file_url = #{docPath}</if> <if test="docPath != null and docPath != ''"> and d.file_url = #{docPath}</if>
and d.del_flag = '0' and d.del_flag = '0'
@@ -85,7 +90,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="params != null and params.currentUserId != null"> <if test="params != null and params.currentUserId != null">
and ( and (
-- 项目文档:仅项目创建者可见 或 自己上传的项目文档 -- 项目文档:仅项目创建者可见 或 自己上传的项目文档
(kind_type = '0' and ( (d.kind_type = '0' and (
exists ( exists (
select 1 from biz_project p select 1 from biz_project p
where p.project_id = d.project_id where p.project_id = d.project_id
@@ -94,7 +99,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
or d.upload_by = #{params.currentUsername} or d.upload_by = #{params.currentUsername}
)) ))
-- 模块文档:项目创建者可见全部;普通用户可见与自己强相关的 -- 模块文档:项目创建者可见全部;普通用户可见与自己强相关的
or (kind_type = '1' and ( or (d.kind_type = '1' and (
exists ( exists (
select 1 from biz_project p select 1 from biz_project p
where p.project_id = d.project_id where p.project_id = d.project_id
@@ -119,7 +124,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectBizDocByDocId" parameterType="Long" resultMap="BizDocResult"> <select id="selectBizDocByDocId" parameterType="Long" resultMap="BizDocResult">
<include refid="selectBizDocDetailVo"/> <include refid="selectBizDocDetailVo"/>
where doc_id = #{docId} where d.doc_id = #{docId}
</select> </select>
<insert id="insertBizDoc" parameterType="BizDoc" useGeneratedKeys="true" keyProperty="docId"> <insert id="insertBizDoc" parameterType="BizDoc" useGeneratedKeys="true" keyProperty="docId">

View File

@@ -18,19 +18,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="deadline" column="deadline" /> <result property="deadline" column="deadline" />
<result property="startTime" column="start_time" /> <result property="startTime" column="start_time" />
<result property="projectLabel" column="project_label" /> <result property="projectLabel" column="project_label" />
<result property="remark" column="remark" />
<result property="moduleCount" column="moduleCount" /> <result property="moduleCount" column="moduleCount" />
<result property="completedModuleCount" column="completedModuleCount" /> <result property="completedModuleCount" column="completedModuleCount" />
</resultMap> </resultMap>
<sql id="selectBizProjectVo"> <sql id="selectBizProjectVo">
select project_id, project_name, owner_id, status, del_flag, create_by, create_time, update_by, update_time, finish_time, deadline, start_time, project_label from biz_project select project_id, project_name, owner_id, status, del_flag, create_by, create_time, update_by, update_time, finish_time, deadline, start_time, project_label, remark from biz_project
</sql> </sql>
<select id="selectBizProjectList" parameterType="BizProject" resultMap="BizProjectResult"> <select id="selectBizProjectList" parameterType="BizProject" resultMap="BizProjectResult">
select select
p.project_id, p.project_name, p.owner_id, p.status, p.del_flag, p.project_id, p.project_name, p.owner_id, p.status, p.del_flag,
p.create_by, p.create_time, p.update_by, p.update_time, p.create_by, p.create_time, p.update_by, p.update_time,
p.finish_time, p.deadline, p.start_time, p.project_label, p.finish_time, p.deadline, p.start_time, p.project_label, p.remark,
coalesce(cnt.total, 0) as moduleCount, coalesce(cnt.total, 0) as moduleCount,
coalesce(cnt.completed, 0) as completedModuleCount coalesce(cnt.completed, 0) as completedModuleCount
from biz_project p from biz_project p
@@ -78,6 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deadline != null">deadline,</if> <if test="deadline != null">deadline,</if>
<if test="startTime != null">start_time,</if> <if test="startTime != null">start_time,</if>
<if test="projectLabel != null">project_label,</if> <if test="projectLabel != null">project_label,</if>
<if test="remark != null">remark,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="projectName != null and projectName != ''">#{projectName},</if> <if test="projectName != null and projectName != ''">#{projectName},</if>
@@ -92,6 +94,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deadline != null">#{deadline},</if> <if test="deadline != null">#{deadline},</if>
<if test="startTime != null">#{startTime},</if> <if test="startTime != null">#{startTime},</if>
<if test="projectLabel != null">#{projectLabel},</if> <if test="projectLabel != null">#{projectLabel},</if>
<if test="remark != null">#{remark},</if>
</trim> </trim>
</insert> </insert>
@@ -110,6 +113,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deadline != null">deadline = #{deadline},</if> <if test="deadline != null">deadline = #{deadline},</if>
<if test="startTime != null">start_time = #{startTime},</if> <if test="startTime != null">start_time = #{startTime},</if>
<if test="projectLabel != null">project_label = #{projectLabel},</if> <if test="projectLabel != null">project_label = #{projectLabel},</if>
<if test="remark != null">remark = #{remark},</if>
</trim> </trim>
where project_id = #{projectId} where project_id = #{projectId}
</update> </update>

View File

@@ -45,7 +45,6 @@
<el-table v-loading="loading" :data="moduleList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="moduleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="模块ID" align="center" prop="moduleId" />
<el-table-column label="模块名称" align="center" prop="moduleName"> <el-table-column label="模块名称" align="center" prop="moduleName">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link type="primary" @click.stop="openSubDrawer(scope.row)">{{ scope.row.moduleName }}</el-link> <el-link type="primary" @click.stop="openSubDrawer(scope.row)">{{ scope.row.moduleName }}</el-link>

View File

@@ -1,3 +1,24 @@
-- 统一历史数据:将 biz_module.assignee 迁移为用户ID字符串
-- 注意:仅对 status='1' 或 '2' 且 assignee 非数字的历史记录进行转换
-- 先将 assignee 为用户名的,更新为对应的 user_id
UPDATE biz_module m
LEFT JOIN sys_user u ON m.assignee = u.user_name
SET m.assignee = CAST(u.user_id AS CHAR)
WHERE m.assignee IS NOT NULL
AND m.assignee <> ''
AND m.assignee REGEXP '^[0-9]+$' = 0
AND u.user_id IS NOT NULL;
-- 若 assignee 是昵称(而非用户名),尝试通过昵称匹配
UPDATE biz_module m
LEFT JOIN sys_user u ON m.assignee = u.nick_name
SET m.assignee = CAST(u.user_id AS CHAR)
WHERE m.assignee IS NOT NULL
AND m.assignee <> ''
AND m.assignee REGEXP '^[0-9]+$' = 0
AND u.user_id IS NOT NULL;
-- 约束:未来只允许用 ID 存储 assignee可在业务层保证不在库层加约束
/* /*
Navicat Premium Data Transfer Navicat Premium Data Transfer