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())) {
return AjaxResult.error("仅可指派待接取的模块");
}
// 前端传递的是用户名需要转换为用户ID
if (bizModule.getAssignee() != null && !bizModule.getAssignee().isEmpty()) {
// 仅使用用户ID。优先使用前端传来的 designatedUser
// 如为兼容历史,若未提供 designatedUser 而提供了 assignee则尝试解析/转换为ID。
Long targetUserId = bizModule.getDesignatedUser();
if (targetUserId == null) {
String assigneeRaw = bizModule.getAssignee();
if (assigneeRaw != null && !assigneeRaw.isEmpty()) {
try {
// 先尝试解析为数字用户ID
Long userId = Long.parseLong(bizModule.getAssignee());
bizModule.setDesignatedUser(userId);
targetUserId = Long.parseLong(assigneeRaw);
} catch (NumberFormatException e) {
// 如果不是数字说明是用户名需要查询用户ID
SysUser user = userService.selectUserByUserName(bizModule.getAssignee());
SysUser user = userService.selectUserByUserName(assigneeRaw);
if (user != null) {
bizModule.setDesignatedUser(user.getUserId());
} else {
targetUserId = user.getUserId();
}
}
}
}
if (targetUserId == null) {
return AjaxResult.error("请选择要指派的用户");
}
// 校验用户是否存在
SysUser designated = userService.selectUserById(targetUserId);
if (designated == null) {
return AjaxResult.error("用户不存在");
}
}
}
bizModule.setDesignatedUser(targetUserId);
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.IBizModuleService;
import com.ruoyi.project.service.IBizProjectService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.common.core.domain.entity.SysUser;
/**
* 子模块Controller
@@ -41,6 +43,9 @@ public class BizSubModuleController extends BaseController
@Autowired
private IBizProjectService projectService;
@Autowired
private ISysUserService userService;
/**
* 查询子模块列表(按条件)
*/
@@ -91,14 +96,24 @@ public class BizSubModuleController extends BaseController
// 仅模块接取人可新增子模块兼容历史assignee 可能存为 用户ID/用户名/昵称)
Long currentUserId = getUserId();
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())) {
isAssignee = true;
} else {
String username = getUsername();
if (username != null && username.equals(module.getAssignee())) {
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();
String username = getUsername();
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())) {
isAssignee = true;
} else if (username != null && username.equals(module.getAssignee())) {
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)
@@ -163,12 +188,22 @@ public class BizSubModuleController extends BaseController
Long currentUserId = getUserId();
String username = getUsername();
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())) {
isAssignee = true;
} else if (username != null && username.equals(module.getAssignee())) {
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)

View File

@@ -36,6 +36,9 @@ public class BizModule extends BaseEntity
@Excel(name = "接取人")
private String assignee;
/** 接取人用户ID仅用于前端判定不导出 */
private Long assigneeId;
/** 接取时间 */
@JsonFormat(pattern = "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 remark;
public void setModuleId(Long moduleId)
{
this.moduleId = moduleId;
@@ -108,6 +114,16 @@ public class BizModule extends BaseEntity
return assignee;
}
public Long getAssigneeId()
{
return assigneeId;
}
public void setAssigneeId(Long assigneeId)
{
this.assigneeId = assigneeId;
}
public void setAssignTime(Date assignTime)
{
this.assignTime = assignTime;
@@ -168,6 +184,14 @@ public class BizModule extends BaseEntity
return projectName;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
@@ -177,6 +201,7 @@ public class BizModule extends BaseEntity
.append("moduleName", getModuleName())
.append("status", getStatus())
.append("assignee", getAssignee())
.append("assigneeId", getAssigneeId())
.append("assignTime", getAssignTime())
.append("finishTime", getFinishTime())
.append("designatedUser", getDesignatedUser())
@@ -184,6 +209,7 @@ public class BizModule extends BaseEntity
.append("delFlag", getDelFlag())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("remark", getRemark())
.toString();
}
}

View File

@@ -57,10 +57,19 @@ public class BizModuleServiceImpl implements IBizModuleService {
public List<BizModule> selectBizModuleList(BizModule bizModule) {
Long userId = SecurityUtils.getUserId();
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("isAdmin", isAdmin);
bizModule.getParams().put("isAdmin", isAdmin || isPlatformAdmin);
return bizModuleMapper.selectBizModuleList(bizModule);
}
@@ -150,17 +159,8 @@ public class BizModuleServiceImpl implements IBizModuleService {
}
module.setStatus("1"); // 进行中
// 设置接取人为用户名非ID
try {
SysUser u = sysUserService.selectUserById(userId);
if (u != null && u.getUserName() != null) {
module.setAssignee(u.getUserName());
} else {
// 统一用用户ID字符串保存避免用户改名导致前端判断与展示异常
module.setAssignee(String.valueOf(userId));
}
} catch (Exception ex) {
module.setAssignee(String.valueOf(userId));
}
module.setAssignTime(DateUtils.getNowDate());
// 避免重复接取:若已有相同 moduleId 的进行中记录,这里只更新而不新增
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.BizModule;
import com.ruoyi.models.service.IBizSubModuleService;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.common.core.domain.entity.SysUser;
/**
* 子模块Service业务层处理
@@ -24,6 +26,9 @@ public class BizSubModuleServiceImpl implements IBizSubModuleService
@Autowired
private BizModuleMapper moduleMapper;
@Autowired
private ISysUserService sysUserService;
@Override
public BizSubModule selectBizSubModuleBySubId(Long subId)
{
@@ -84,9 +89,24 @@ public class BizSubModuleServiceImpl implements IBizSubModuleService
throw new RuntimeException("父模块不存在");
}
String currentUsername = SecurityUtils.getUsername();
if (!(String.valueOf(userId).equals(module.getAssignee())
|| (module.getAssignee() != null && module.getAssignee().equals(currentUsername))))
{
boolean allowed = false;
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("仅父模块接取人可接取子模块");
}
@@ -111,9 +131,24 @@ public class BizSubModuleServiceImpl implements IBizSubModuleService
throw new RuntimeException("父模块不存在");
}
String currentUsername2 = SecurityUtils.getUsername();
if (!(String.valueOf(userId).equals(module.getAssignee())
|| (module.getAssignee() != null && module.getAssignee().equals(currentUsername2))))
{
boolean allowed2 = false;
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("仅父模块接取人可完成子模块");
}

View File

@@ -62,6 +62,23 @@ public class BizDocController extends BaseController
public TableDataInfo list(BizDoc bizDoc)
{
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);
return getDataTable(list);
}

View File

@@ -47,6 +47,9 @@ public class BizDoc extends BaseEntity
/** 项目名称(展示用) */
private String projectName;
/** 模块名称(展示用,模块文档时有值) */
private String moduleName;
public void setDocId(Long docId)
{
this.docId = docId;
@@ -149,6 +152,16 @@ public class BizDoc extends BaseEntity
this.projectName = projectName;
}
public String getModuleName()
{
return moduleName;
}
public void setModuleName(String moduleName)
{
this.moduleName = moduleName;
}
@Override
public String toString() {
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("delFlag", getDelFlag())
.append("projectName", getProjectName())
.append("moduleName", getModuleName())
.toString();
}
}

View File

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

View File

@@ -46,7 +46,18 @@ public class BizProjectServiceImpl implements IBizProjectService
public List<BizProject> selectBizProjectList(BizProject bizProject)
{
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);
}

View File

@@ -6,7 +6,7 @@ spring:
druid:
# 主库数据源
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
password: Wxit11335577
# 从库数据源

View File

@@ -10,6 +10,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="moduleName" column="module_name" />
<result property="status" column="status" />
<result property="assignee" column="assignee" />
<result property="assigneeId" column="assignee_id" />
<result property="assignTime" column="assign_time" />
<result property="finishTime" column="finish_time" />
<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="projectName" column="project_name" />
<result property="designatedUser" column="designated_user" />
<result property="remark" column="remark" />
</resultMap>
<sql id="selectBizModuleVo">
@@ -25,13 +27,18 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
m.module_name,
m.status,
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.finish_time,
m.del_flag,
m.create_by,
m.create_time,
m.designated_user,
p.project_name
p.project_name,
m.remark
from biz_module m
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)
@@ -60,7 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="assignTime != null "> and m.assign_time = #{assignTime}</if>
<if test="finishTime != null "> and m.finish_time = #{finishTime}</if>
and m.del_flag = '0'
<!-- 权限控制:普通用户只能查看自己项目下的模块或被指派的模块;平台管理员可查看所有 -->
<!-- 权限控制:普通用户只能查看自己项目下的模块或被指派的模块;平台管理员/超管可查看所有 -->
<if test="params != null and params.currentUserId != null and params.isAdmin != true">
and (
-- 自己是项目所有者
@@ -100,6 +107,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="assignee != null">assignee,</if>
<if test="assignTime != null">assign_time,</if>
<if test="finishTime != null">finish_time,</if>
<if test="remark != null">remark,</if>
<if test="delFlag != null">del_flag,</if>
<if test="createBy != null">create_by,</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="assignTime != null">#{assignTime},</if>
<if test="finishTime != null">#{finishTime},</if>
<if test="remark != null">#{remark},</if>
<if test="delFlag != null">#{delFlag},</if>
<if test="createBy != null">#{createBy},</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="finishTime != null">finish_time = #{finishTime},</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="createBy != null">create_by = #{createBy},</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.status,
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.finish_time,
m.del_flag,
@@ -167,7 +180,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
m.designated_user,
m.update_by,
m.update_time,
p.project_name
p.project_name,
m.remark
from biz_module m
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)

View File

@@ -20,6 +20,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
<result property="projectName" column="project_name" />
<result property="moduleName" column="module_name" />
</resultMap>
<!-- 轻量字段:用于列表,排除大字段 doc_content -->
@@ -38,9 +39,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
d.upload_time as create_time,
null as update_by,
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
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>
<!-- 详情字段:下载/单条查询专用,含 doc_content -->
@@ -60,18 +63,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
d.upload_time as create_time,
null as update_by,
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
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>
<select id="selectBizDocList" parameterType="BizDoc" resultMap="BizDocResult">
<include refid="selectBizDocListVo"/>
<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="moduleId != null and moduleId != ''"> and module_id = #{moduleId}</if>
<if test="kindType != null and kindType != ''"> and kind_type = #{kindType}</if>
<if test="moduleId != null and moduleId != ''"> and d.module_id = #{moduleId}</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="docPath != null and docPath != ''"> and d.file_url = #{docPath}</if>
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">
and (
-- 项目文档:仅项目创建者可见 或 自己上传的项目文档
(kind_type = '0' and (
(d.kind_type = '0' and (
exists (
select 1 from biz_project p
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 (kind_type = '1' and (
or (d.kind_type = '1' and (
exists (
select 1 from biz_project p
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">
<include refid="selectBizDocDetailVo"/>
where doc_id = #{docId}
where d.doc_id = #{docId}
</select>
<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="startTime" column="start_time" />
<result property="projectLabel" column="project_label" />
<result property="remark" column="remark" />
<result property="moduleCount" column="moduleCount" />
<result property="completedModuleCount" column="completedModuleCount" />
</resultMap>
<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>
<select id="selectBizProjectList" parameterType="BizProject" resultMap="BizProjectResult">
select
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.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.completed, 0) as completedModuleCount
from biz_project p
@@ -78,6 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deadline != null">deadline,</if>
<if test="startTime != null">start_time,</if>
<if test="projectLabel != null">project_label,</if>
<if test="remark != null">remark,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<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="startTime != null">#{startTime},</if>
<if test="projectLabel != null">#{projectLabel},</if>
<if test="remark != null">#{remark},</if>
</trim>
</insert>
@@ -110,6 +113,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="deadline != null">deadline = #{deadline},</if>
<if test="startTime != null">start_time = #{startTime},</if>
<if test="projectLabel != null">project_label = #{projectLabel},</if>
<if test="remark != null">remark = #{remark},</if>
</trim>
where project_id = #{projectId}
</update>

View File

@@ -45,7 +45,6 @@
<el-table v-loading="loading" :data="moduleList" @selection-change="handleSelectionChange">
<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">
<template slot-scope="scope">
<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