feat: 职工慰问

This commit is contained in:
2026-10-09 19:39:26 +08:00
parent 45121f7b2e
commit b325e8a8f5
21 changed files with 1048 additions and 38 deletions
@@ -0,0 +1,60 @@
package com.budwk.app.zhgh.staffbenefit.condolence.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.zhgh.staffbenefit.condolence.model.Condolence;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
@IocBean
@Ok("json")
@At("/platform/condolence/approval")
public class CondolenceApprovalController {
@Inject
private Dao dao;
@Inject
private FlowCommonService flowCommonService;
@At
@SaCheckLogin
@Aop(TransAop.READ_COMMITTED)
public Result executeTask(@Param("data") String data) {
Dict args = Json.fromJson(Dict.class, data);
if (args == null || args.getLong(FlowConst.PROCESS_TASK_ID_KEY) == null) {
throw new BaseException("审批任务不能为空");
}
ProcessTask task = dao.fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY));
if (task == null) throw new BaseException("审批任务不存在");
if (!"4dad0bef-3cf2-4a7d-bba3-35020b9b216d".equals(task.getTaskName())
&& !"34f7938e-47a3-4b3a-b4e0-92b7a3f47865".equals(task.getTaskName())
&& !"ecdaef3b-edf4-4143-9a96-887dd5921711".equals(task.getTaskName())
&& !"cbd41337-3c87-4959-9027-809df5c7ef5e".equals(task.getTaskName())) {
throw new BaseException("当前任务不是职工慰问审批任务");
}
ProcessInstance instance = dao.fetch(ProcessInstance.class, task.getProcessInstanceId());
Condolence info = instance == null ? null : dao.fetch(Condolence.class, instance.getBusinessNo());
if (info == null) throw new BaseException("职工慰问申请不存在");
if (StrUtil.isBlank(args.getStr("tf_sign"))) throw new BaseException("请完成审批签字");
if (StrUtil.isBlank(args.getStr("tf_opinion"))) throw new BaseException("请填写审批意见");
// 参与者权限由流程引擎校验,业务入口不接受客户端指定管理员代办。
args.remove(FlowConst.EXT_ENABLE_OPERATOR);
flowCommonService.executeTask(args);
return Result.success();
}
}
@@ -27,7 +27,7 @@ import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @ClassName CondolenceBranchUnionApprovalController
* @ClassName CondolenceFirstApprovalController
* @Author JyuHsin
* @Date 2025/7/28 11:33
* @Version 1.0
@@ -35,26 +35,26 @@ import java.util.List;
*/
@IocBean
@At("/platform/condolence/branchUnionApproval")
@Api("职工慰问分工会审核")
@Api("职工慰问一级审核")
@Ok("json:full")
public class CondolenceBranchUnionApprovalController {
public class CondolenceFirstApprovalController {
@Inject
private CondolenceService condolenceService;
@At("/")
@Ok("beetl:/platform/zhgh/staffbenefit/condolence/branchUnionApproval/index.html")
@SaCheckPermission("condolence.branchUnionApproval")
@SaCheckPermission("condolence.firstApproval")
public void index() {}
@At("/h5")
@Ok("beetl:/platform/zhghh5/staffbenefit/condolence/branchUnionApproval/index.html")
@SaCheckPermission("h5.condolence.branchUnionApproval")
@SaCheckPermission("h5.condolence.firstApproval")
public void h5Index() {}
@At
@ApiOperation("分页查询")
@SaCheckPermission(value = {"condolence.branchUnionApproval", "h5.condolence.branchUnionApproval"}, mode = SaMode.OR)
@SaCheckPermission(value = {"condolence.firstApproval", "h5.condolence.firstApproval"}, mode = SaMode.OR)
public Result pageData(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "type") String type,
@@ -100,7 +100,9 @@ public class CondolenceBranchUnionApprovalController {
cnd.andEX("YEAR(info.createTime)", "=", year);
cnd.and("t.taskName", "=", "4dad0bef-3cf2-4a7d-bba3-35020b9b216d");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (!"superadmin".equals(SecurityUtil.getUserLoginname())) {
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
@@ -0,0 +1,152 @@
package com.budwk.app.zhgh.staffbenefit.condolence.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.condolence.model.Condolence;
import com.budwk.app.zhgh.staffbenefit.condolence.service.CondolenceService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @ClassName CondolenceFourthApprovalController
* @Author JyuHsin
* @Date 2025/7/29 16:23
* @Version 1.0
* @Description TODO
*/
@IocBean
@At("/platform/condolence/fourthApproval")
@Api("职工慰问四级审核")
@Ok("json:full")
public class CondolenceFourthApprovalController {
@Inject
private Dao dao;
@Inject
private CondolenceService condolenceService;
@At("/")
@Ok("beetl:/platform/zhgh/staffbenefit/condolence/fourthApproval/index.html")
@SaCheckPermission("condolence.fourthApproval")
public void index() {}
@At("/h5")
@Ok("beetl:/platform/zhghh5/staffbenefit/condolence/fourthApproval/index.html")
@SaCheckPermission("h5.condolence.fourthApproval")
public void h5Index() {}
@At
@ApiOperation("分页查询")
@SaCheckPermission(value = {"condolence.fourthApproval", "h5.condolence.fourthApproval"}, mode = SaMode.OR)
public Result pageData(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "type") String type,
@Param(value = "unionId") String unionId,
@Param(value = "unitId") String unitId,
@Param(value = "approval") Boolean approval) {
Sql sql = Sqls.create("""
SELECT
info.*,
type.name as typeName,
ins.id AS instanceId,
ins.businessNo,
ins.state instanceState,
ins.variable instanceVariable,
ins.processDefineId instanceProcessDefineId,
t.id taskId,
t.taskName AS taskKey,
t.displayName taskName,
t.taskType,
t.performType taskPerformType,
t.taskState,
t.finishTime,
t.taskParentId,
t.variable taskVariable,
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName),'结束') curTaskName,
IF(rt.id IS NOT NULL, 1, 0) AS canRevoke
FROM
wf_process_task t
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
LEFT JOIN condolence info ON info.id = ins.businessNo
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
LEFT JOIN condolence_type type ON info.type = type.id
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
LEFT JOIN wf_process_task rt ON rt.processInstanceId = ins.id AND rt.taskParentId = t.id AND rt.taskState = 10
$condition
""");
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or(Condolence::getHelpUserName, "like", "%" + pageForm.getSearchKeyword() + "%");
seg.or(Condolence::getHelpLoginName, "like", "%" + pageForm.getSearchKeyword() + "%");
cnd.and(seg);
}
cnd.andEX("info.type", "=", type);
cnd.andEX("YEAR(info.createTime)", "=", year);
cnd.andEX("info.applyUnionId", "=", unionId);
cnd.andEX("info.applyUnitId", "=", unitId);
cnd.and("t.taskName", "=", "cbd41337-3c87-4959-9027-809df5c7ef5e");
if (!"superadmin".equals(SecurityUtil.getUserLoginname()) && !AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name())) {
Sql unitSql = Sqls.queryString("""
SELECT DISTINCT ur.unitId
FROM sys_user_role ur
INNER JOIN sys_role r ON r.id = ur.roleId
WHERE ur.userId = @userId
AND ur.enable = true
AND r.disabled = false
AND r.code = @roleCode
AND ur.unitId IS NOT NULL
AND ur.unitId <> ''
""");
unitSql.setParam("userId", SecurityUtil.getUserId());
unitSql.setParam("roleCode", RoleConstant.UNIT_SCHOOL_LEADER.name());
dao.execute(unitSql);
List<String> managedUnitIds = unitSql.getList(String.class);
if (managedUnitIds.isEmpty()) {
cnd.and(new Static("1 = 0"));
} else {
cnd.and("info.applyUnitId", "in", managedUnitIds);
}
}
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("info.createTime");
} else {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
cnd.groupBy("t.id");
sql.setCondition(cnd);
Pagination<NutMap> pageVO = condolenceService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
}
@@ -33,26 +33,26 @@ import java.util.List;
*/
@IocBean
@At("/platform/condolence/schoolPrincipalApproval")
@Api("职工慰问校工会预审")
@Api("职工慰问二级审核")
@Ok("json:full")
public class CondolenceSchoolPrincipalApprovalController {
public class CondolenceSecondApprovalController {
@Inject
private CondolenceService condolenceService;
@At("/")
@Ok("beetl:/platform/zhgh/staffbenefit/condolence/schoolPrincipalApproval/index.html")
@SaCheckPermission("condolence.schoolPrincipalApproval")
@SaCheckPermission("condolence.secondApproval")
public void index() {}
@At("/h5")
@Ok("beetl:/platform/zhghh5/staffbenefit/condolence/schoolPrincipalApproval/index.html")
@SaCheckPermission("h5.condolence.schoolPrincipalApproval")
@SaCheckPermission("h5.condolence.secondApproval")
public void h5Index() {}
@At
@ApiOperation("分页查询")
@SaCheckPermission(value = {"condolence.schoolPrincipalApproval", "h5.condolence.schoolPrincipalApproval"}, mode = SaMode.OR)
@SaCheckPermission(value = {"condolence.secondApproval", "h5.condolence.secondApproval"}, mode = SaMode.OR)
public Result pageData(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "type") String type,
@@ -27,7 +27,7 @@ import org.nutz.mvc.annotation.Param;
import java.util.List;
/**
* @ClassName CondolenceSchoolUnionApprovalController
* @ClassName CondolenceThirdApprovalController
* @Author JyuHsin
* @Date 2025/7/29 16:23
* @Version 1.0
@@ -35,26 +35,26 @@ import java.util.List;
*/
@IocBean
@At("/platform/condolence/schoolUnionApproval")
@Api("职工慰问校工会审核")
@Api("职工慰问三级审核")
@Ok("json:full")
public class CondolenceSchoolUnionApprovalController {
public class CondolenceThirdApprovalController {
@Inject
private CondolenceService condolenceService;
@At("/")
@Ok("beetl:/platform/zhgh/staffbenefit/condolence/schoolUnionApproval/index.html")
@SaCheckPermission("condolence.schoolUnionApproval")
@SaCheckPermission("condolence.thirdApproval")
public void index() {}
@At("/h5")
@Ok("beetl:/platform/zhghh5/staffbenefit/condolence/schoolUnionApproval/index.html")
@SaCheckPermission("h5.condolence.schoolUnionApproval")
@SaCheckPermission("h5.condolence.thirdApproval")
public void h5Index() {}
@At
@ApiOperation("分页查询")
@SaCheckPermission(value = {"condolence.schoolUnionApproval", "h5.condolence.schoolUnionApproval"}, mode = SaMode.OR)
@SaCheckPermission(value = {"condolence.thirdApproval", "h5.condolence.thirdApproval"}, mode = SaMode.OR)
public Result pageData(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "type") String type,
@@ -104,7 +104,9 @@ public class CondolenceSchoolUnionApprovalController {
cnd.andEX("info.applyUnitId", "=", unitId);
cnd.and("t.taskName", "=", "ecdaef3b-edf4-4143-9a96-887dd5921711");
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
if (!"superadmin".equals(SecurityUtil.getUserLoginname())) {
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
}
if (approval) {
cnd.and("t.taskState", "in", List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
@@ -1 +0,0 @@
ALTER TABLE difficult_help_info ADD COLUMN applyMoney VARCHAR(200) NULL COMMENT '申请金额';
@@ -114,3 +114,4 @@ VALUES ('4d3e3472ae324552b16f0aaf07c37004', '501e0a4edca748ddb739ffb679170d50',
'SCHOOL_OFFICE_DIRECTOR', false, 9614, false, '17a7f8ad3ee947b4a26175049a9c253d', 1791517263500,
'17a7f8ad3ee947b4a26175049a9c253d', 1791517263500, false, null);
ALTER TABLE difficult_help_info ADD COLUMN applyMoney VARCHAR(200) NULL COMMENT '申请金额';
@@ -0,0 +1,132 @@
START TRANSACTION;
-- 一级:分工会主席审批,节点 4dad0bef-3cf2-4a7d-bba3-35020b9b216d。
UPDATE zhgh_cqgmy.sys_menu
SET name = '分工会主席审批', initialPinyinName = 'f', note = '分工会主席审批',
permission = 'condolence.firstApproval'
WHERE id = '8e24dfdb70e448a899ea7de92319789c';
UPDATE zhgh_cqgmy.sys_menu
SET name = '分工会主席审批', initialPinyinName = 'f', note = '分工会主席审批',
permission = 'h5.condolence.firstApproval'
WHERE id = '330e42e0ae914f5392b96fb933f17b5b';
-- 二级:校工会办公室主任审批,节点 34f7938e-47a3-4b3a-b4e0-92b7a3f47865。
UPDATE zhgh_cqgmy.sys_menu
SET name = '校工会办公室主任审批', initialPinyinName = 'x', note = '校工会办公室主任审批',
permission = 'condolence.secondApproval'
WHERE id = '09a59e7a99204ceca8e5dbbf8b2fafcf';
UPDATE zhgh_cqgmy.sys_menu
SET name = '校工会办公室主任审批', initialPinyinName = 'x', note = '校工会办公室主任审批',
permission = 'h5.condolence.secondApproval'
WHERE id = '87a2dcfac0da4ec4870b65693807a4d1';
-- 三级:分工会主席审批,节点 ecdaef3b-edf4-4143-9a96-887dd5921711。
UPDATE zhgh_cqgmy.sys_menu
SET name = '分工会主席审批', initialPinyinName = 'f', note = '分工会主席审批',
permission = 'condolence.thirdApproval'
WHERE id = '0917928006574b2a99f7ef3e8804d873';
UPDATE zhgh_cqgmy.sys_menu
SET name = '分工会主席审批', initialPinyinName = 'f', note = '分工会主席审批',
permission = 'h5.condolence.thirdApproval'
WHERE id = 'c269f94a5c8a4a4a8c8de0bb8f8f9f9a';
-- 四级:分管校领导审批,节点 cbd41337-3c87-4959-9027-809df5c7ef5e。
INSERT INTO zhgh_cqgmy.sys_menu
(id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt,
delFlag, processKey, platform, moduleId, isQuickEntry, picIcon, initialPinyinName,
isRecommendApp, isRecommendService)
VALUES ('3561e97f44d14b47ae07f63ff8312a90', '3b49290f7db44130b9f6394a8212321f', '00900009',
'分管校领导审批', null, 'menu', '/platform/condolence/fourthApproval', null, null, true, false,
'condolence.fourthApproval', '分管校领导审批', 146, false,
'17a7f8ad3ee947b4a26175049a9c253d', UNIX_TIMESTAMP() * 1000,
'17a7f8ad3ee947b4a26175049a9c253d', UNIX_TIMESTAMP() * 1000,
false, null, 'PC', '07d940ba34bd47399cda140894f5d86b', false, null, 'f', false, false);
INSERT INTO zhgh_cqgmy.sys_menu
(id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt,
delFlag, processKey, platform, moduleId, isQuickEntry, picIcon, initialPinyinName,
isRecommendApp, isRecommendService)
VALUES ('f02d5a68bdeb4c63a1b8ce47296d7304', '024811fd168e44948e6ab84911fc26bb', '01220006',
'分管校领导审批', null, 'menu', '/platform/condolence/fourthApproval/h5', null, null, true, false,
'h5.condolence.fourthApproval', '分管校领导审批', 32, false,
'17a7f8ad3ee947b4a26175049a9c253d', UNIX_TIMESTAMP() * 1000,
'17a7f8ad3ee947b4a26175049a9c253d', UNIX_TIMESTAMP() * 1000,
false, null, 'H5', '586fffaeddc94a7493c81b6d69e546ab', false, '/platform/sys/file/download?id=d2095854e67dcf28dea1a4a975e90aba', 'f', false, false);
-- 清除之前的菜单角色权限,按审核角色重新配置。
-- 一级:分工会主席审批,节点 4dad0bef-3cf2-4a7d-bba3-35020b9b216d。
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = '8e24dfdb70e448a899ea7de92319789c';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '8e24dfdb70e448a899ea7de92319789c');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
values ('fd753e8a8c5a404e8e00ef8e0b0c69da', '8e24dfdb70e448a899ea7de92319789c');
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = '330e42e0ae914f5392b96fb933f17b5b';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '330e42e0ae914f5392b96fb933f17b5b');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
values ('fd753e8a8c5a404e8e00ef8e0b0c69da', '330e42e0ae914f5392b96fb933f17b5b');
-- 二级:校工会办公室主任审批,节点 34f7938e-47a3-4b3a-b4e0-92b7a3f47865。
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = '09a59e7a99204ceca8e5dbbf8b2fafcf';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '09a59e7a99204ceca8e5dbbf8b2fafcf');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('494ac71eb8b44d0e99e19b7fde6bd469', '09a59e7a99204ceca8e5dbbf8b2fafcf');
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = '87a2dcfac0da4ec4870b65693807a4d1';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '87a2dcfac0da4ec4870b65693807a4d1');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('494ac71eb8b44d0e99e19b7fde6bd469', '87a2dcfac0da4ec4870b65693807a4d1');
-- 三级:分工会主席审批,节点 ecdaef3b-edf4-4143-9a96-887dd5921711。
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = '0917928006574b2a99f7ef3e8804d873';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '0917928006574b2a99f7ef3e8804d873');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
SELECT id, '0917928006574b2a99f7ef3e8804d873' FROM zhgh_cqgmy.sys_role WHERE code = 'BRANCH_UNION_CHAIRMAN' AND disabled = false AND delFlag = false;
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = 'c269f94a5c8a4a4a8c8de0bb8f8f9f9a';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', 'c269f94a5c8a4a4a8c8de0bb8f8f9f9a');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
SELECT id, 'c269f94a5c8a4a4a8c8de0bb8f8f9f9a' FROM zhgh_cqgmy.sys_role WHERE code = 'BRANCH_UNION_CHAIRMAN' AND disabled = false AND delFlag = false;
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = '3561e97f44d14b47ae07f63ff8312a90';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '3561e97f44d14b47ae07f63ff8312a90');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('b3854469e6f44901b22bb791cb538431', '3561e97f44d14b47ae07f63ff8312a90');
DELETE FROM zhgh_cqgmy.sys_role_menu WHERE menuId = 'f02d5a68bdeb4c63a1b8ce47296d7304';
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', 'f02d5a68bdeb4c63a1b8ce47296d7304');
INSERT INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('b3854469e6f44901b22bb791cb538431', 'f02d5a68bdeb4c63a1b8ce47296d7304');
-- 补充职工慰问父菜单权限。
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '3b49290f7db44130b9f6394a8212321f');
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('494ac71eb8b44d0e99e19b7fde6bd469', '3b49290f7db44130b9f6394a8212321f');
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('b3854469e6f44901b22bb791cb538431', '3b49290f7db44130b9f6394a8212321f');
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
SELECT id, '3b49290f7db44130b9f6394a8212321f' FROM zhgh_cqgmy.sys_role WHERE code = 'BRANCH_UNION_CHAIRMAN' AND disabled = false AND delFlag = false;
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '024811fd168e44948e6ab84911fc26bb');
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('494ac71eb8b44d0e99e19b7fde6bd469', '024811fd168e44948e6ab84911fc26bb');
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
VALUES ('b3854469e6f44901b22bb791cb538431', '024811fd168e44948e6ab84911fc26bb');
INSERT IGNORE INTO zhgh_cqgmy.sys_role_menu (roleId, menuId)
SELECT id, '024811fd168e44948e6ab84911fc26bb' FROM zhgh_cqgmy.sys_role WHERE code = 'BRANCH_UNION_CHAIRMAN' AND disabled = false AND delFlag = false;
COMMIT;
@@ -0,0 +1,14 @@
truncate table condolence_type;
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('00016fcb72234a8f95cd173665bbe563', 'C3', '生育(三孩)', 5000.00, '慰问金 (A)', false, null, null, 0, '17a7f8ad3ee947b4a26175049a9c253d', 1791539298087, '17a7f8ad3ee947b4a26175049a9c253d', 1791539298087, false, null, 8, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('3777d15929dd4c66b3aa9ae67dc62528', 'C2', '生育(二孩)', 3000.00, '慰问金 (A)', false, null, null, 0, '17a7f8ad3ee947b4a26175049a9c253d', 1791539214037, '17a7f8ad3ee947b4a26175049a9c253d', 1791539269588, false, null, 7, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('4cdf253d26044261a1a81359bbde1bb8', 'G', '直系亲属去世', 2000.00, '慰问金 (A)', false, true, '', 0, '17a7f8ad3ee947b4a26175049a9c253d', 1765427298440, '17a7f8ad3ee947b4a26175049a9c253d', 1791539615689, false, null, 2, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('4e316737e71047e0b01aea78524c1416', 'E', '生病住院', 1000.00, '慰问金 (A)', false, true, '每年累计不超过3000元、每人每年最多申请3次', 1, '29847d7826aa415a92d03b9576d01d3f', 1722084651317, '29847d7826aa415a92d03b9576d01d3f', 1791539558039, false, false, null, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('5b5f135e523d4cc5b5dc4355ffe9e024', 'B', '生日', 600.00, '慰问金 (A)', false, null, null, 0, '17a7f8ad3ee947b4a26175049a9c253d', 1791539148841, '17a7f8ad3ee947b4a26175049a9c253d', 1791539148841, false, null, 6, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('60f03a87b62b4823855814afdbf5672a', 'F', '会员去世', 3000.00, '慰问金 (A)', false, true, '需要提供购买的慰问品发票,慰问照片', 0, '17a7f8ad3ee947b4a26175049a9c253d', 1765427276486, '17a7f8ad3ee947b4a26175049a9c253d', 1791539570707, false, null, 1, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('b8ee30faacb2469593dfedb5b52565aa', 'D', '光荣退休', 2000.00, '慰问金 (A)', false, true, '需要提供购买的慰问品发票,慰问照片', 0, '17a7f8ad3ee947b4a26175049a9c253d', 1765427383848, '17a7f8ad3ee947b4a26175049a9c253d', 1791539529423, false, null, 3, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('c90cb10dce6542e99ae271bee6fe8cc0', 'C1', '生育(一孩)', 2000.00, '慰问金 (A)', false, true, '需要提供购买的慰问品发票,慰问照片(会员与婴儿合影照,或慰问人员与会员和婴儿的合影照)', 0, '17a7f8ad3ee947b4a26175049a9c253d', 1765427542820, '17a7f8ad3ee947b4a26175049a9c253d', 1791539263656, false, null, 5, false, true);
INSERT INTO condolence_type (id, code, name, money, way, disabled, isUploadFile, uploadFileDesc, sortNum, createdBy, createdAt, updatedBy, updatedAt, delFlag, isDisabled, location, uploadMeetingRecord, enable) VALUES ('cf4ce7af322d464f8f86d818fcc00203', 'A', '结婚', 1000.00, '慰问金 (A)', false, true, '需要提供购买的慰问品的发票、慰问照片、会员的结婚证复印件', 2, '29847d7826aa415a92d03b9576d01d3f', 1722084861840, '29847d7826aa415a92d03b9576d01d3f', 1768875320985, false, false, null, false, true);
@@ -219,6 +219,15 @@ layout("/layouts/platform.html"){
new Vue({
el: "#app",
store,
components: {
ElDatePicker: {
extends: ELEMENT.DatePicker,
mounted() {
// 手动输入触发 change 前初始化日期面板,避免 picker 尚未创建。
if (!this.picker) this.mountPicker()
}
}
},
data() {
return {
bizId: GetQueryString("bizId"),
@@ -81,6 +81,9 @@ layout("/layouts/platform.html"){
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
<el-form-item label="签字" prop="tf_sign" :rules="[{required:true,message:'请完成审批签字',trigger:['change','blur']}]">
<pc-signature v-model="formData.tf_sign" :key="formData.processTaskId"></pc-signature>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
@@ -135,18 +138,26 @@ layout("/layouts/platform.html"){
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
}
this.$refs.condolenceInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
async handleTaskAction(val) {
try {
const valid = await this.$refs.formRef.validate()
if (!valid) return
} catch (error) {
return
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
@@ -65,6 +65,9 @@ const condolenceInfo = {
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="审批签字" :span="3" v-if="task.taskFormData && task.taskFormData.sign">
<el-image :src="task.taskFormData.sign" style="height: 80px" fit="contain"></el-image>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{
task.taskFormData.opinion }}
</el-descriptions-item>
@@ -0,0 +1,229 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app">
<guava ref="guava">
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
v-model="pageForm.year"
type="year"
value-format="yyyy"
placeholder="请选择年度"
style="width: 100%"
@change="doSearch"
></el-date-picker>
</search-item>
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"
@keyup.enter.native="doSearch">
</el-input>
</search-item>
<search-item label="慰问类型">
<el-select v-model="pageForm.type" @change="doSearch" style="width: 100%"
placeholder="请选择慰问类型" filterable clearable>
<el-option v-for="item in typeOptions"
:value="item.id"
:key="item.id"
:label="item.name"
></el-option>
</el-select>
</search-item>
<search-item label="所属工会">
<el-select v-model="pageForm.unionId" placeholder="请选择所属工会" filterable clearable
@change="doSearch" style="width: 100%">
<el-option
v-for="item in unionList"
:key="item.id"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</search-item>
<search-item label="所属单位">
<el-select @change="doSearch"
clearable
filterable
placeholder="请选择单位" style="width: 100%" v-model="pageForm.unitId">
<el-option :key="item.id" :label="item.name" :value="item.id" v-for="item in unitList"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never">
<table-tool label="申请列表">
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
<el-table-column
:label="column.label"
:prop="column.prop"
:key="column.prop"
:width="column.width"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
v-for="column in tableColumns"
>
<template v-slot="{ row }" v-if="column.prop === 'instanceState'">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="300px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="row.taskState === 10" @click="onAudit(row)" size="mini" type="primary">审核</el-button>
<el-button v-if="row.canRevoke" @click="onRevoke(row)" size="mini" type="danger">撤回</el-button>
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<template #edit>
<condolence-info ref="condolenceInfoRef">
<div v-if="showApprovalForm">
<div class="process-title">
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=":"
class="flow-task-form">
<el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
<el-form-item label="签字" prop="tf_sign" :rules="[{required:true,message:'请完成审批签字',trigger:['change','blur']}]">
<pc-signature v-model="formData.tf_sign" :key="formData.processTaskId"></pc-signature>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
<el-button @click="handleTaskAction(2)" size="small" type="danger">拒绝申请</el-button>
<el-button @click="handleTaskAction(6)" size="small" type="info">退回到发起人</el-button>
<el-button @click="$refs.guava.index()" size="small">取消</el-button>
</el-row>
</div>
</condolence-info>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/info.js'){}#-->
new Vue({
el: "#app",
store,
mixins: [initTableMixins],
components: {
"condolence-info": condolenceInfo
},
data() {
return {
pageForm: {
approval: false
},
typeOptions: [],
tableColumns: [
{prop: 'helpUserName', label: '慰问对象'},
{prop: 'helpLoginName', label: '慰问对象工号'},
{prop: 'applyUserName', label: '申请人'},
{prop: 'applyUnionName', label: '所属工会'},
{prop: 'applyUnitName', label: '所属单位'},
{prop: 'typeName', label: '慰问类型'},
{prop: 'curTaskName', label: '当前节点'},
{prop: 'instanceState', label: '流程状态'},
],
unionList: [],
unitList: [],
formData: {},
showApprovalForm: false
}
},
methods: {
onView(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = false
this.$refs.condolenceInfoRef.onOpen(row)
})
},
onAudit(row) {
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
}
this.$refs.condolenceInfoRef.onOpen(row)
})
},
async handleTaskAction(val) {
try {
const valid = await this.$refs.formRef.validate()
if (!valid) return
} catch (error) {
return
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
onRevoke(row) {
this.$confirm("您确定要撤回吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "info"
}).then(() => {
this.$axios.post("/flow/common/revokeTask", {taskId: row.taskId}).then((res) => {
if (res.code === 0) {
this.$message.success(res.msg)
this.doSearch()
}
})
})
},
queryCondolenceType() {
this.$axios.post('/platform/condolence/type/queryCondolenceType')
.then((resp) => {
this.typeOptions = resp.data
})
},
},
async created() {
this.unionList = await this.$businessTool.listUnion()
this.unitList = await this.$businessTool.listUnit()
this.queryCondolenceType()
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -101,6 +101,9 @@ layout("/layouts/platform.html"){
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
<el-form-item label="签字" prop="tf_sign" :rules="[{required:true,message:'请完成审批签字',trigger:['change','blur']}]">
<pc-signature v-model="formData.tf_sign" :key="formData.processTaskId"></pc-signature>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
@@ -158,18 +161,26 @@ layout("/layouts/platform.html"){
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
}
this.$refs.condolenceInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
async handleTaskAction(val) {
try {
const valid = await this.$refs.formRef.validate()
if (!valid) return
} catch (error) {
return
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
@@ -101,6 +101,9 @@ layout("/layouts/platform.html"){
:rules="[{required:true,message:'必填',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item>
<el-form-item label="签字" prop="tf_sign" :rules="[{required:true,message:'请完成审批签字',trigger:['change','blur']}]">
<pc-signature v-model="formData.tf_sign" :key="formData.processTaskId"></pc-signature>
</el-form-item>
</el-form>
<el-row type="flex" justify="end">
<el-button @click="handleTaskAction(1)" size="small" type="primary">同意申请</el-button>
@@ -158,18 +161,26 @@ layout("/layouts/platform.html"){
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
taskName: row.curTaskName
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
}
this.$refs.condolenceInfoRef.onOpen(row)
})
},
handleTaskAction(val) {
async handleTaskAction(val) {
try {
const valid = await this.$refs.formRef.validate()
if (!valid) return
} catch (error) {
return
}
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: val
@@ -55,7 +55,7 @@ layout("/layouts/platform_h5.html"){
<div id="app">
<div class="condolence-list-page">
<van-nav-bar title="分工会审核" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-nav-bar title="分工会主席审批" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-sticky offset-top="46px">
<div class="condolence-list-sticky">
@@ -148,6 +148,12 @@ layout("/layouts/platform_h5.html"){
maxlength="100"
show-word-limit
></van-field>
<h2 class="condolence-info-card__title">
审批签字<span class="condolence-audit-card__required">*</span>
</h2>
<van-field name="tf_sign" :value="formData.tf_sign" required :rules="[{required:true,message:'请完成审批签字'}]">
<template #input><h5-signature v-model="formData.tf_sign" :key="formData.processTaskId"></h5-signature></template>
</van-field>
</van-form>
</section>
<div class="condolence-popup-actions">
@@ -227,6 +233,7 @@ layout("/layouts/platform_h5.html"){
this.$set(this, "formData", {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
})
this.$refs.infoRef.onOpen(row, row.curTaskName || "慰问审核")
@@ -252,10 +259,10 @@ layout("/layouts/platform_h5.html"){
this.submitTaskAction()
})
},
// 提交 processTaskId、taskName、tf_opinion 和 submitType,接口返回统一响应对象。
// 提交 processTaskId、taskName、tf_opinion、tf_sign 和 submitType,接口返回统一响应对象。
submitTaskAction() {
this.$set(this, "formLoading", true)
this.$axios.post("/flow/common/executeTask", {
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: this.pendingSubmitType
@@ -85,6 +85,9 @@ const condolenceInfo = {
:value="task.ext && task.ext.submitType"
></dict-tag>
</van-cell>
<van-cell v-if="task.taskFormData && task.taskFormData.sign" title="审批签字">
<img :src="task.taskFormData.sign" style="max-width: 100%; height: 80px; object-fit: contain">
</van-cell>
<van-cell class="condolence-info-long-cell" title="办理意见">
<div v-html="task.taskFormData && task.taskFormData.tf_opinion || '暂无'"></div>
</van-cell>
@@ -0,0 +1,350 @@
<!--#
layout("/layouts/platform_h5.html"){
#-->
<style>
#app { --color-primary: #1989fa; }
.condolence-list-page { min-height: 100vh; padding-bottom: calc(24px + env(safe-area-inset-bottom)); box-sizing: border-box; background: #f3f7fd; }
.condolence-list-page .van-nav-bar, .condolence-list-page .van-sticky--fixed { background: #fff; }
.condolence-list-page .van-nav-bar__title { color: #172033; font-size: 16px; font-weight: 600; }
.condolence-list-page .van-nav-bar .van-icon, .condolence-list-page .van-nav-bar__text { color: #1989fa; }
.condolence-list-sticky { padding: 22px 12px 1px; box-sizing: border-box; background: #f3f7fd; }
.condolence-list-search { margin: 0 0 8px; padding: 0; overflow: hidden; border-radius: 12px; background: #fff; box-shadow: 0 5px 16px rgba(43, 73, 112, .1); }
.condolence-list-search .van-search__content { height: 42px; padding-left: 12px; align-items: center; border-radius: 12px; background: #fff; }
.condolence-list-search .van-field__control { color: #263548; font-size: 14px; }
.condolence-list-search .van-field__control::placeholder { color: #a7b0bf; }
.condolence-list-filter { margin-bottom: 8px; overflow: hidden; border-radius: 10px; box-shadow: 0 5px 16px rgba(43, 73, 112, .08); }
.condolence-list-filter .van-dropdown-menu__bar { height: 44px; box-shadow: none; }
.condolence-list-filter .van-dropdown-menu__item, .condolence-list-filter .van-dropdown-menu__title { height: 44px; }
.condolence-list-filter .van-dropdown-menu__item { align-items: center; justify-content: center; }
.condolence-list-filter .van-dropdown-menu__title { display: inline-flex; align-items: center; line-height: 20px; color: #66758a; font-size: 14px; }
.condolence-list-filter .van-dropdown-menu__title--active, .condolence-list-filter .van-dropdown-item__option--active, .condolence-list-filter .van-dropdown-item__option--active .van-dropdown-item__icon { color: #1989fa; }
.condolence-list-filter .van-dropdown-item__content { width: calc(100% - 24px); margin: 0 12px; overflow: hidden; box-sizing: border-box; border-radius: 0 0 12px 12px; box-shadow: 0 10px 24px rgba(31, 65, 108, .14); }
.condolence-list-filter .van-dropdown-item__option { display: flex; min-height: 48px; padding: 0 16px; align-items: center; color: #46566c; font-size: 14px; }
.condolence-list-filter .van-dropdown-item__option .van-cell__title { display: flex; min-height: 20px; align-items: center; line-height: 20px; }
.condolence-list-content { padding: 0 12px; }
.condolence-list-skeleton { padding-top: 2px; }
.condolence-list-skeleton__card { margin-bottom: 12px; padding: 18px 14px 14px; border: 1px solid #e9eff7; border-radius: 12px; background: #fff; box-shadow: 0 5px 16px rgba(43, 73, 112, .08); }
.condolence-list-skeleton__card .van-skeleton { padding: 0; }
.condolence-list-skeleton__card .van-skeleton__title { width: 42%; height: 18px; margin-bottom: 18px; }
.condolence-list-skeleton__card .van-skeleton__row { height: 14px; margin-top: 12px; }
.condolence-list-skeleton__card .van-skeleton__row:nth-child(2n) { width: 72% !important; }
.condolence-list-skeleton__card .van-skeleton__row:last-child { width: 34% !important; margin-top: 18px; margin-left: auto; }
.condolence-list-page .table-list-container { margin-top: 0; padding-bottom: 2px; }
.condolence-list-page .table-list-container .table-list-item { margin-bottom: 12px; padding: 14px; border: 1px solid #e9eff7; border-radius: 12px; box-shadow: 0 5px 16px rgba(43, 73, 112, .08); }
.condolence-card-header { display: flex; margin-bottom: 8px; align-items: flex-start; justify-content: space-between; }
.condolence-card-heading { min-width: 0; padding-right: 10px; flex: 1; }
.condolence-card-title { overflow: hidden; color: #253247; font-size: 15px; font-weight: 600; line-height: 22px; text-overflow: ellipsis; white-space: nowrap; }
.condolence-card-code { margin-top: 1px; color: #9ba6b6; font-size: 12px; line-height: 18px; }
.condolence-card-status { display: inline-flex; flex: none; }
.condolence-card-status .van-tag { min-height: 24px; padding: 3px 9px; border: 0; border-radius: 12px; box-sizing: border-box; font-size: 12px; line-height: 18px; }
.condolence-list-page .table-list-container .table-list-item .item-actions { margin-top: 10px; padding-top: 10px; border-top-color: #edf1f6; }
.condolence-list-page .table-list-container .table-list-item .action-btn { min-height: 28px; padding: 4px 11px; border-radius: 14px; color: #1989fa; background: #eaf4ff; font-size: 12px; line-height: 18px; }
.condolence-list-page .table-list-container .table-list-item .action-btn.delete { color: #f04444; background: #fff0f0; }
.condolence-list-page .table-list-container .table-list-item .action-btn i { margin-right: 5px; font-size: 13px; }
.condolence-list-page .empty-state { padding: 0; }
.condolence-list-empty { display: flex; min-height: 280px; padding: 46px 18px 36px; align-items: center; justify-content: center; box-sizing: border-box; flex-direction: column; text-align: center; }
.condolence-list-empty img { display: block; width: 86%; max-width: 290px; height: auto; object-fit: contain; }
.condolence-list-empty__title { margin-top: 14px; color: #50627a; font-size: 15px; font-weight: 600; line-height: 22px; }
.condolence-list-empty__hint { margin-top: 5px; color: #9aa7b8; font-size: 12px; line-height: 18px; }
</style>
<style id="style-condolence-info-h5">
<!--#include("../common/info.css"){}#-->
</style>
<div id="app">
<div class="condolence-list-page">
<van-nav-bar title="分管校领导审批" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-sticky offset-top="46px">
<div class="condolence-list-sticky">
<van-search
v-model="pageForm.searchKeyword"
class="condolence-list-search"
placeholder="请输入姓名或者工号搜索"
shape="round"
clearable
@search="doSearch"
@clear="doSearch"
></van-search>
<van-dropdown-menu class="condolence-list-filter" :close-on-click-outside="false" :close-on-click-overlay="false">
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
<van-dropdown-item v-model="pageForm.type" :options="typeOptions" :multiple="false"
@change="doSearch"></van-dropdown-item>
<van-dropdown-item v-model="pageForm.approvalText" :options="approvalOptions" :multiple="false"
@change="onApprovalFilterChange"></van-dropdown-item>
</van-dropdown-menu>
</div>
</van-sticky>
<main class="condolence-list-content">
<div class="condolence-list-skeleton" v-if="skeletonLoading">
<div class="condolence-list-skeleton__card" v-for="index in 3" :key="'fourth-approval-skeleton-' + index">
<van-skeleton title :row="5" animated></van-skeleton>
</div>
</div>
<table-list api="/platform/condolence/fourthApproval/pageData" :page_form.sync="pageForm" ref="tableListRef"
v-show="!skeletonLoading" :show_loading_overlay="false" @ready="onReady"
@loading-change="handleListLoadingChange">
<template #header="{index,row}">
<div class="condolence-card-header">
<div class="condolence-card-heading">
<div class="condolence-card-title">{{row.helpUserName || '--'}}</div>
<div class="condolence-card-code">工号:{{row.helpLoginName || '--'}}</div>
</div>
<enum-tag class="condolence-card-status" v-if="row.instanceState" :value="row.instanceState"
name="ProcessInstanceStateEnum" label_key="message" size="small"></enum-tag>
</div>
</template>
<template v-slot="{index,row}">
<table-column label="慰问对象">{{row.helpUserName}}</table-column>
<table-column label="慰问对象工号">{{row.helpLoginName}}</table-column>
<table-column label="申请人">{{row.applyUserName}}</table-column>
<table-column label="所属工会">{{row.applyUnionName}}</table-column>
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
<table-column label="慰问类型">{{row.typeName}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column>
</template>
<template #actions="{index,row}">
<div class="action-btn" @click="onView(row)">
<van-icon name="eye-o"></van-icon>
<span>查看</span>
</div>
<div class="action-btn" v-if="row.taskState === 10" @click="onApproval(row)">
<van-icon name="edit"></van-icon>
<span>审核</span>
</div>
<div class="action-btn delete" v-if="row.canRevoke" @click="onRevoke(row)">
<van-icon name="revoke"></van-icon>
<span>撤回</span>
</div>
</template>
<template #empty>
<div class="condolence-list-empty">
<img src="/assets/mobile/img/condolence/condolence-empty.png" alt="暂无慰问审核记录插画">
<div class="condolence-list-empty__title">暂无慰问审核记录</div>
<div class="condolence-list-empty__hint">当前筛选条件下暂时没有慰问申请</div>
</div>
</template>
</table-list>
</main>
<info ref="infoRef" page-key="condolence-fourth-detail">
<div v-if="showApprovalForm">
<section class="condolence-info-card">
<h2 class="condolence-info-card__title">
审批意见<span class="condolence-audit-card__required">*</span>
</h2>
<van-form ref="formRef">
<van-field
v-model="formData.tf_opinion"
class="condolence-audit-field"
name="tf_opinion"
type="textarea"
rows="6"
placeholder="请输入审批意见"
:rules="[{ required: true, message: '请填写审批意见' }]"
maxlength="100"
show-word-limit
></van-field>
<h2 class="condolence-info-card__title">
审批签字<span class="condolence-audit-card__required">*</span>
</h2>
<van-field name="tf_sign" :value="formData.tf_sign" required :rules="[{required:true,message:'请完成审批签字'}]">
<template #input><h5-signature v-model="formData.tf_sign" :key="formData.processTaskId"></h5-signature></template>
</van-field>
</van-form>
</section>
<div class="condolence-popup-actions">
<van-button class="condolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(6)">退回</van-button>
<van-button class="condolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(20)">不同意</van-button>
<van-button class="condolence-action-primary" type="primary" block :loading="formLoading" @click="handleTaskAction(1)">同意</van-button>
</div>
</div>
</info>
<van-dialog
:value="confirmVisible"
title="提示"
:message="confirmActionType === 'revoke' ? '您确定要撤回吗?' : '您确定要提交吗?'"
show-cancel-button
confirm-button-color="#1989fa"
@confirm="confirmPendingAction"
@cancel="closeActionConfirm"
></van-dialog>
</div>
</div>
<script nonce="${cspNonce!}">
<!--#include('../common/info.js'){}#-->
new Vue({
el: "#app",
store,
components: {
info: condolenceInfo
},
data() {
return {
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0,
searchKeyword: '',
approvalText: "0",
approval: false,
year: new Date().getFullYear(),
type: null,
},
typeOptions: [],
approvalOptions: [
{text: "未审核", value: "0"},
{text: "已审核", value: "1"}
],
skeletonLoading: true,
formData: {},
showApprovalForm: false,
formLoading: false,
confirmVisible: false,
confirmActionType: "task",
pendingSubmitType: null,
pendingRevokeRow: null,
historyLayerUnsubscribe: null
}
},
methods: {
// state.initial 表示当前查询前列表为空,仅此阶段使用整组卡片骨架屏。
handleListLoadingChange(state) {
if (state.initial) this.$set(this, "skeletonLoading", state.loading)
},
// 审核状态下拉值为字符串,接口参数 approval 继续使用布尔值。
onApprovalFilterChange(val) {
this.$set(this.pageForm, "approval", val === "1")
this.doSearch()
},
onReady() {
this.queryCondolenceType()
},
onView(row) {
this.$set(this, "showApprovalForm", false)
this.$refs.infoRef.onOpen(row, "慰问详情")
},
onApproval(row) {
this.$set(this, "showApprovalForm", true)
this.$set(this, "formData", {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
})
this.$refs.infoRef.onOpen(row, row.curTaskName || "慰问审核")
},
// val 为流程提交类型:1 同意、20 不同意、6 退回;校验通过后打开历史栈确认框。
handleTaskAction(val) {
this.$refs.formRef.validate()
.then(() => {
this.$set(this, "confirmActionType", "task")
this.$set(this, "pendingSubmitType", val)
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {
this.closeActionConfirm(() => {
if (this.confirmActionType === "revoke") {
this.revokeTask()
return
}
this.submitTaskAction()
})
},
// 提交 processTaskId、taskName、tf_opinion、tf_sign 和 submitType,接口返回统一响应对象。
submitTaskAction() {
this.$set(this, "formLoading", true)
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: this.pendingSubmitType
})
})
.then((res) => {
if (res && res.code === 0) {
const afterClose = () => {
this.$toast.success(res.msg)
this.doSearch()
}
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.closeAll(afterClose)) return
this.$refs.infoRef.onClose(afterClose)
}
})
.finally(() => {
this.$set(this, "formLoading", false)
})
},
closeActionConfirm(afterClose = null) {
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.close("condolence-action-confirm", afterClose)) return
this.$set(this, "confirmVisible", false)
if (typeof afterClose === "function") afterClose()
},
// row 提供待撤回任务 taskId,确认后保存当前行并由统一确认框执行撤回。
onRevoke(row){
this.$set(this, "confirmActionType", "revoke")
this.$set(this, "pendingRevokeRow", row)
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
},
// 使用 pendingRevokeRow.taskId 撤回任务,接口返回统一响应对象。
revokeTask() {
if (!this.pendingRevokeRow) return
this.$set(this, "formLoading", true)
this.$axios.post("/flow/common/revokeTask", {taskId: this.pendingRevokeRow.taskId})
.then((res) => {
if (res.code === 0) {
this.$toast.success(res.msg)
this.doSearch()
}
})
.finally(() => {
this.$set(this, "formLoading", false)
})
},
queryCondolenceType() {
this.$axios.post('/platform/condolence/type/queryCondolenceType', {}, {h5SkeletonLoading: true})
.then((res) => {
const typeList = res.data || []
this.$set(this, "typeOptions", [
{
text: "全部慰问类型",
value: null
}
].concat(typeList.map((v) => ({ text: v.name, value: v.id }))))
if (this.typeOptions.length > 0) {
this.$set(this.pageForm, "type", this.typeOptions[0].value)
this.doSearch()
}
})
},
doSearch() {
this.$nextTick(() => {
this.pageForm.pageNumber = 1
this.pageForm.totalCount = 0
this.$refs.tableListRef.doSearch()
})
}
},
created() {
if (!window.h5HistoryLayerManager) return
this.$set(this, "historyLayerUnsubscribe", window.h5HistoryLayerManager.subscribe((stack) => {
this.$set(this, "confirmVisible", stack.includes("condolence-action-confirm"))
}))
},
beforeDestroy() {
if (typeof this.historyLayerUnsubscribe === "function") this.historyLayerUnsubscribe()
}
})
</script>
<!--#
}
#-->
@@ -55,7 +55,7 @@ layout("/layouts/platform_h5.html"){
<div id="app">
<div class="condolence-list-page">
<van-nav-bar title="校工会预审" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-nav-bar title="校工会办公室主任审批" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-sticky offset-top="46px">
<div class="condolence-list-sticky">
@@ -148,6 +148,12 @@ layout("/layouts/platform_h5.html"){
maxlength="100"
show-word-limit
></van-field>
<h2 class="condolence-info-card__title">
审批签字<span class="condolence-audit-card__required">*</span>
</h2>
<van-field name="tf_sign" :value="formData.tf_sign" required :rules="[{required:true,message:'请完成审批签字'}]">
<template #input><h5-signature v-model="formData.tf_sign" :key="formData.processTaskId"></h5-signature></template>
</van-field>
</van-form>
</section>
<div class="condolence-popup-actions">
@@ -227,6 +233,7 @@ layout("/layouts/platform_h5.html"){
this.$set(this, "formData", {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
})
this.$refs.infoRef.onOpen(row, row.curTaskName || "慰问审核")
@@ -252,10 +259,10 @@ layout("/layouts/platform_h5.html"){
this.submitTaskAction()
})
},
// 提交 processTaskId、taskName、tf_opinion 和 submitType,接口返回统一响应对象。
// 提交 processTaskId、taskName、tf_opinion、tf_sign 和 submitType,接口返回统一响应对象。
submitTaskAction() {
this.$set(this, "formLoading", true)
this.$axios.post("/flow/common/executeTask", {
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: this.pendingSubmitType
@@ -55,7 +55,7 @@ layout("/layouts/platform_h5.html"){
<div id="app">
<div class="condolence-list-page">
<van-nav-bar title="校工会审核" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-nav-bar title="分工会主席审批" left-text="返回" left-arrow @click-left="historyBack" fixed placeholder></van-nav-bar>
<van-sticky offset-top="46px">
<div class="condolence-list-sticky">
@@ -148,6 +148,12 @@ layout("/layouts/platform_h5.html"){
maxlength="100"
show-word-limit
></van-field>
<h2 class="condolence-info-card__title">
审批签字<span class="condolence-audit-card__required">*</span>
</h2>
<van-field name="tf_sign" :value="formData.tf_sign" required :rules="[{required:true,message:'请完成审批签字'}]">
<template #input><h5-signature v-model="formData.tf_sign" :key="formData.processTaskId"></h5-signature></template>
</van-field>
</van-form>
</section>
<div class="condolence-popup-actions">
@@ -227,6 +233,7 @@ layout("/layouts/platform_h5.html"){
this.$set(this, "formData", {
processTaskId: row.taskId,
taskName: row.curTaskName,
tf_sign: "",
tf_opinion: ""
})
this.$refs.infoRef.onOpen(row, row.curTaskName || "慰问审核")
@@ -252,10 +259,10 @@ layout("/layouts/platform_h5.html"){
this.submitTaskAction()
})
},
// 提交 processTaskId、taskName、tf_opinion 和 submitType,接口返回统一响应对象。
// 提交 processTaskId、taskName、tf_opinion、tf_sign 和 submitType,接口返回统一响应对象。
submitTaskAction() {
this.$set(this, "formLoading", true)
this.$axios.post("/flow/common/executeTask", {
this.$axios.post("/platform/condolence/approval/executeTask", {
data: JSON.stringify({
...this.formData,
submitType: this.pendingSubmitType