feat: 修复困难帮扶申请表单校验及页面加载闪烁,调整办公室主任拒绝、退回审批时不校验级别和帮扶金额。
新增特殊慰问模块,支持分工会主席统一为多人申请、Excel 导入及人员校验;完善主从表存储、表单校验、审批展示和导出,移除分工会主席审批节点,使用独立流程节点标识。
This commit is contained in:
@@ -41,6 +41,11 @@ public class FlowRecipientUnitSchoolLeaderHandler implements AssignmentHandler {
|
||||
throw new BaseException("未找到申请记录。");
|
||||
}
|
||||
unitId = condolence.getHelpUnitId();
|
||||
} else if ("TSWW".equals(processName)) {
|
||||
com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence info = dao.fetch(
|
||||
com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence.class, businessNo);
|
||||
if (info == null) throw new BaseException("未找到申请记录。");
|
||||
unitId = info.getHelpUnitId();
|
||||
} else {
|
||||
throw new BaseException("当前流程不支持获取受助人所在单位分管校领导。");
|
||||
}
|
||||
|
||||
+6
-2
@@ -55,8 +55,12 @@ public class DifficultHelpApprovalController {
|
||||
if (StrUtil.isBlank(args.getStr("tf_opinion"))) throw new BaseException("请填写审批意见");
|
||||
|
||||
String level = args.getStr("level");
|
||||
Double money = amountApproval ? args.getDouble("money") : null;
|
||||
if (amountApproval) {
|
||||
Integer submitType = args.getInt(FlowConst.SUBMIT_TYPE);
|
||||
boolean skipAmount = "36ebafda-44c2-4bd3-bd7f-10839a575a0d".equals(task.getTaskName())
|
||||
&& (ProcessSubmitTypeEnum.REJECT.getCode().equals(submitType)
|
||||
|| ProcessSubmitTypeEnum.ROLLBACK_TO_OPERATOR.getCode().equals(submitType));
|
||||
Double money = amountApproval && !skipAmount ? args.getDouble("money") : null;
|
||||
if (amountApproval && !skipAmount) {
|
||||
if (StrUtil.isBlank(level) || money == null || !Double.isFinite(money) || money < 0) {
|
||||
throw new BaseException("请填写完整的级别和帮扶金额");
|
||||
}
|
||||
|
||||
+251
@@ -0,0 +1,251 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckRole;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.flow.constant.FlowConst;
|
||||
import com.budwk.app.flow.engine.FlowEngine;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
||||
import com.budwk.app.flow.service.FlowCommonService;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.democratic.suggestionBox.models.SuggestionBox;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
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.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceApplyController
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/8/20 15:40
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@SaCheckRole("BRANCH_UNION_CHAIRMAN")
|
||||
@IocBean
|
||||
@At("/platform/special_condolence/apply")
|
||||
@Api("特殊慰问申请")
|
||||
@Ok("json:full")
|
||||
public class SpecialCondolenceApplyController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private FlowEngine flowEngine;
|
||||
@Inject
|
||||
private SpecialCondolenceService specialcondolenceService;
|
||||
@Inject
|
||||
private FlowCommonService flowCommonService;
|
||||
|
||||
@At("/")
|
||||
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/apply/index.html")
|
||||
@SaCheckPermission("special_condolence.apply")
|
||||
public void index() {}
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/staffbenefit/specialcondolence/apply/index.html")
|
||||
@SaCheckPermission("h5.special_condolence.apply")
|
||||
public void h5Index() {}
|
||||
|
||||
@At
|
||||
@ApiOperation("保存申请")
|
||||
@SaCheckPermission(value = {"special_condolence.apply", "h5.special_condolence.apply"}, mode = SaMode.OR)
|
||||
@SLog(tag = "特殊慰问系统-慰问申请", msg = "保存申请")
|
||||
public Result save(@Param("data") SpecialCondolence specialcondolence) {
|
||||
if(StrUtil.isBlank(specialcondolence.getId())) specialcondolence.setCreateTime(DateUtil.now());
|
||||
prepareApplication(specialcondolence);
|
||||
specialcondolenceService.saveApplication(specialcondolence);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("提交申请")
|
||||
@SaCheckPermission(value = {"special_condolence.apply", "h5.special_condolence.apply"}, mode = SaMode.OR)
|
||||
@SLog(tag = "特殊慰问系统-慰问申请", msg = "提交申请")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Result submit(@Param("data") SpecialCondolence specialcondolence) {
|
||||
if (StrUtil.isBlank(specialcondolence.getRemark()) || specialcondolence.getRemark().trim().length() > 500) throw new com.budwk.app.base.exception.BaseException("请填写500字以内的申请事由");
|
||||
if (StrUtil.isBlank(specialcondolence.getSignature())) throw new com.budwk.app.base.exception.BaseException("请完成申请人签字");
|
||||
if(StrUtil.isBlank(specialcondolence.getId())) specialcondolence.setCreateTime(DateUtil.now());
|
||||
prepareApplication(specialcondolence);
|
||||
specialcondolenceService.saveApplication(specialcondolence);
|
||||
// 开启流程实例
|
||||
Dict args = Dict.create();
|
||||
args.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode());
|
||||
args.set(FlowConst.FORM_DATA, specialcondolence);
|
||||
ProcessInstance instance = flowEngine.startProcessInstanceByKey("TSWW", specialcondolence.getId(), SecurityUtil.getUserId(), args);
|
||||
|
||||
// 自动完成第一个申请任务
|
||||
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
|
||||
for (ProcessTask task : doingTaskList) {
|
||||
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("重新提交申请")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission(value = {"special_condolence.apply", "h5.special_condolence.apply"}, mode = SaMode.OR)
|
||||
public Result submitAgain(@Param("data") SpecialCondolence specialcondolence, @Param("taskId") Long taskId) {
|
||||
if (StrUtil.isBlank(specialcondolence.getRemark()) || specialcondolence.getRemark().trim().length() > 500) throw new com.budwk.app.base.exception.BaseException("请填写500字以内的申请事由");
|
||||
if (StrUtil.isBlank(specialcondolence.getSignature())) throw new com.budwk.app.base.exception.BaseException("请完成申请人签字");
|
||||
ProcessTask task = taskId == null ? null : dao.fetch(ProcessTask.class, taskId);
|
||||
ProcessInstance instance = task == null ? null : dao.fetch(ProcessInstance.class, task.getProcessInstanceId());
|
||||
if (instance == null || !StrUtil.equals(instance.getBusinessNo(), specialcondolence.getId())
|
||||
|| !"startTask".equals(task.getTaskName()) || !SecurityUtil.getUserId().equals(instance.getOperator())) {
|
||||
throw new com.budwk.app.base.exception.BaseException("申请任务不匹配");
|
||||
}
|
||||
prepareApplication(specialcondolence);
|
||||
specialcondolenceService.saveApplication(specialcondolence);
|
||||
|
||||
Dict dict = Dict.create();
|
||||
dict.set(FlowConst.PROCESS_TASK_ID_KEY, taskId);
|
||||
dict.set(FlowConst.FORM_DATA, specialcondolence);
|
||||
dict.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.RE_APPLY.getCode());
|
||||
flowCommonService.executeTask(dict);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("查询用户")
|
||||
@SaCheckPermission(value = {"special_condolence.apply", "h5.special_condolence.apply"}, mode = SaMode.OR)
|
||||
public Object listUser(String keyword) {
|
||||
Sql sql = Sqls.create("""
|
||||
select
|
||||
u.id,
|
||||
u.idCard,
|
||||
u.personType,
|
||||
bank.bankOfDeposit,
|
||||
bank.bankUserName,
|
||||
bank.bankCardNumber,
|
||||
username as userName,
|
||||
loginname as loginName,
|
||||
sex,
|
||||
mobile,
|
||||
technicalTitle,
|
||||
IFNULL(unitname, '暂无') as unitName,
|
||||
unitid as unitId,
|
||||
unionid as unionId,
|
||||
unionname as unionName
|
||||
from
|
||||
vw_user u
|
||||
LEFT JOIN (
|
||||
SELECT idCard, bankOfDeposit, bankUserName, bankCardNumber,
|
||||
ROW_NUMBER() OVER (PARTITION BY idCard ORDER BY createdAt DESC, id DESC) rn
|
||||
FROM special_condolence_recipient WHERE delFlag = false
|
||||
) bank ON bank.idCard = u.idCard AND bank.rn = 1 AND u.idCard <> ''
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (StrUtil.isNotBlank(keyword)) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or(View_user::getLoginname, "like", "%" + keyword + "%");
|
||||
seg.or(View_user::getUsername, "like", "%" + keyword + "%");
|
||||
cnd.and(seg);
|
||||
}
|
||||
if (StrUtil.isBlank(SecurityUtil.getUnionId())) throw new com.budwk.app.base.exception.BaseException("申请人未关联分工会");
|
||||
cnd.and("u.unionId", "=", SecurityUtil.getUnionId());
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = specialcondolenceService.listPageMap(1, 50, sql);
|
||||
return Result.success(pagination.getList());
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission(value = {"special_condolence.apply", "h5.special_condolence.apply"}, mode = SaMode.OR)
|
||||
public void importTemplate(javax.servlet.http.HttpServletResponse response) throws Exception {
|
||||
try (java.io.InputStream input = getClass().getResourceAsStream("/templates/special_condolence/special_condolence_import.xlsx")) {
|
||||
if (input == null) throw new com.budwk.app.base.exception.BaseException("导入模板不存在");
|
||||
com.budwk.app.base.utils.CommonDownloadUtil.download("特殊慰问导入模板.xlsx", input.readAllBytes(), response);
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission(value = {"special_condolence.apply", "h5.special_condolence.apply"}, mode = SaMode.OR)
|
||||
@org.nutz.mvc.annotation.AdaptBy(type = org.nutz.mvc.upload.UploadAdaptor.class, args = {"ioc:fileUpload"})
|
||||
public Result importRecipients(@Param("file") org.nutz.mvc.upload.TempFile file) throws Exception {
|
||||
if (file == null) throw new com.budwk.app.base.exception.BaseException("请选择Excel文件");
|
||||
if (!file.getSubmittedFileName().toLowerCase(java.util.Locale.ROOT).matches(".*\\.(xlsx|xls)$")) throw new com.budwk.app.base.exception.BaseException("仅支持xlsx、xls文件");
|
||||
String[] headers = {"慰问对象", "工号", "身份证号码", "开户行", "户名", "收款账户"};
|
||||
String[] fields = {"helpUserName", "helpLoginName", "idCard", "bankOfDeposit", "bankUserName", "bankCardNumber"};
|
||||
java.util.List<cn.hutool.json.JSONObject> result = new java.util.ArrayList<>();
|
||||
try (java.io.InputStream input = new java.io.FileInputStream(file.getFile());
|
||||
org.apache.poi.ss.usermodel.Workbook workbook = org.apache.poi.ss.usermodel.WorkbookFactory.create(input)) {
|
||||
if (workbook.getNumberOfSheets() == 0) throw new com.budwk.app.base.exception.BaseException("Excel中没有工作表");
|
||||
org.apache.poi.ss.usermodel.Sheet sheet = workbook.getSheetAt(0);
|
||||
org.apache.poi.ss.usermodel.DataFormatter formatter = new org.apache.poi.ss.usermodel.DataFormatter();
|
||||
org.apache.poi.ss.usermodel.Row header = sheet.getRow(0);
|
||||
for (int c = 0; c < headers.length; c++) {
|
||||
if (header == null || !headers[c].equals(formatter.formatCellValue(header.getCell(c)).trim())) throw new com.budwk.app.base.exception.BaseException("表头不正确,请下载导入模板");
|
||||
}
|
||||
if (sheet.getLastRowNum() > 1000) throw new com.budwk.app.base.exception.BaseException("最多导入1000行");
|
||||
for (int r = 1; r <= sheet.getLastRowNum(); r++) {
|
||||
org.apache.poi.ss.usermodel.Row excelRow = sheet.getRow(r);
|
||||
if (excelRow == null) continue;
|
||||
cn.hutool.json.JSONObject row = new cn.hutool.json.JSONObject();
|
||||
boolean empty = true;
|
||||
for (int c = 0; c < fields.length; c++) {
|
||||
org.apache.poi.ss.usermodel.Cell cell = excelRow.getCell(c);
|
||||
String value = formatter.formatCellValue(cell).trim();
|
||||
if (c != 1 && cell != null && cell.getCellType() == org.apache.poi.ss.usermodel.CellType.FORMULA) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行不支持公式,请填写实际值");
|
||||
if ((c == 2 || c == 5) && cell != null && cell.getCellType() == org.apache.poi.ss.usermodel.CellType.NUMERIC) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行工号、身份证和收款账户请使用文本格式,避免数字失真");
|
||||
row.set(fields[c], value);
|
||||
empty = empty && value.isEmpty();
|
||||
}
|
||||
if (empty) continue;
|
||||
for (int c = 0; c < fields.length; c++) {
|
||||
if (c != 1 && row.getStr(fields[c]).isEmpty()) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行:请填写" + headers[c]);
|
||||
}
|
||||
if (!com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceRecipients.validIdCard(row.getStr("idCard"))) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行身份证号码格式不正确");
|
||||
if (!row.getStr("bankCardNumber").matches("[0-9]{6,30}")) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行收款账户格式不正确");
|
||||
com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceRecipients.resolveUser(row, dao, "第" + (r + 1) + "行:");
|
||||
result.add(row);
|
||||
}
|
||||
}
|
||||
if (result.isEmpty()) throw new com.budwk.app.base.exception.BaseException("没有可导入的数据");
|
||||
return Result.success(result);
|
||||
}
|
||||
|
||||
private void prepareApplication(SpecialCondolence info) {
|
||||
if (StrUtil.isNotBlank(info.getId())) {
|
||||
SpecialCondolence existing = dao.fetch(SpecialCondolence.class, info.getId());
|
||||
if (existing == null || !SecurityUtil.getUserId().equals(existing.getCreatedBy())) {
|
||||
throw new com.budwk.app.base.exception.BaseException("只能修改本人申请");
|
||||
}
|
||||
info.setCreatedBy(existing.getCreatedBy());
|
||||
}
|
||||
info.setApplyUserId(SecurityUtil.getUserId());
|
||||
info.setApplyUserName(SecurityUtil.getUserUsername());
|
||||
info.setApplyLoginName(SecurityUtil.getUserLoginname());
|
||||
info.setApplyUnionId(SecurityUtil.getUnionId());
|
||||
info.setApplyUnitId(SecurityUtil.getUnitId());
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.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.specialcondolence.model.SpecialCondolence;
|
||||
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/special_condolence/approval")
|
||||
public class SpecialCondolenceApprovalController {
|
||||
|
||||
@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 (!"c438972e-2f67-4907-b229-cb7aa17da147".equals(task.getTaskName())
|
||||
&& !"7f560675-aeea-4254-a57e-957d03d6b786".equals(task.getTaskName())
|
||||
&& !"af363a4e-fc56-42a0-9906-8c7a2814006b".equals(task.getTaskName())) {
|
||||
throw new BaseException("当前任务不是特殊慰问审批任务");
|
||||
}
|
||||
ProcessInstance instance = dao.fetch(ProcessInstance.class, task.getProcessInstanceId());
|
||||
com.budwk.app.flow.entity.ProcessDefine define = instance == null ? null : dao.fetch(com.budwk.app.flow.entity.ProcessDefine.class, instance.getProcessDefineId());
|
||||
SpecialCondolence info = define == null || !"TSWW".equals(define.getName()) ? null : dao.fetch(SpecialCondolence.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();
|
||||
}
|
||||
}
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.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.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService;
|
||||
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 SpecialCondolenceFourthApprovalController
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 16:23
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@IocBean
|
||||
@At("/platform/special_condolence/fourthApproval")
|
||||
@Api("特殊慰问四级审核")
|
||||
@Ok("json:full")
|
||||
public class SpecialCondolenceFourthApprovalController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private SpecialCondolenceService specialcondolenceService;
|
||||
|
||||
@At("/")
|
||||
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/fourthApproval/index.html")
|
||||
@SaCheckPermission("special_condolence.fourthApproval")
|
||||
public void index() {}
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/staffbenefit/specialcondolence/fourthApproval/index.html")
|
||||
@SaCheckPermission("h5.special_condolence.fourthApproval")
|
||||
public void h5Index() {}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission(value = {"special_condolence.fourthApproval", "h5.special_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 special_condolence info ON info.id = ins.businessNo
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN special_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();
|
||||
cnd.and("info.id", "is not", null);
|
||||
cnd.and(new Static("""
|
||||
NOT EXISTS (
|
||||
SELECT 1 FROM wf_process_task newer
|
||||
WHERE newer.processInstanceId = t.processInstanceId
|
||||
AND newer.taskName = t.taskName
|
||||
AND newer.id > t.id
|
||||
)
|
||||
"""));
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or(SpecialCondolence::getHelpUserName, "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
seg.or(SpecialCondolence::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", "=", "af363a4e-fc56-42a0-9906-8c7a2814006b");
|
||||
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 = specialcondolenceService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pageVO);
|
||||
}
|
||||
}
|
||||
+296
@@ -0,0 +1,296 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
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.sms.SmsService;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.SysOfficeTemplateUtil;
|
||||
import com.budwk.app.flow.engine.FlowEngine;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.flow.vo.ProcessTaskVO;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolenceType;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService;
|
||||
import com.deepoove.poi.data.PictureRenderData;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
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 javax.servlet.http.HttpServletResponse;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceApplyController
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/28 11:06
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@At("/platform/special_condolence/mine")
|
||||
@Api("特殊慰问我的")
|
||||
@Ok("json:full")
|
||||
public class SpecialCondolenceMineController {
|
||||
|
||||
@Inject
|
||||
private SpecialCondolenceService specialcondolenceService;
|
||||
@Inject
|
||||
private FlowEngine flowEngine;
|
||||
@Inject
|
||||
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
|
||||
|
||||
@At("/")
|
||||
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/mine/index.html")
|
||||
@SaCheckPermission("special_condolence.mine")
|
||||
public void index() {}
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/staffbenefit/specialcondolence/mine/index.html")
|
||||
@SaCheckPermission("h5.special_condolence.mine")
|
||||
public void h5Index() {}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission(value = {"special_condolence.mine", "h5.special_condolence.mine"}, mode = SaMode.OR)
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "type") String type) {
|
||||
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,
|
||||
IF((SELECT taskName FROM wf_process_task tt WHERE tt.id = t.taskParentId) = 'startTask', 1, 0) canRevoke,
|
||||
(select MAX(id) from wf_process_task where processInstanceId = ins.id and taskName = 'startTask') AS startTaskId
|
||||
FROM
|
||||
special_condolence info
|
||||
LEFT JOIN special_condolence_type type ON info.type = type.id
|
||||
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = info.id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
id,
|
||||
processInstanceId,
|
||||
taskName,
|
||||
displayName,
|
||||
taskType,
|
||||
performType,
|
||||
taskState,
|
||||
finishTime,
|
||||
taskParentId,
|
||||
variable,
|
||||
ROW_NUMBER() OVER (PARTITION BY processInstanceId ORDER BY createdAt DESC, id DESC) AS rn
|
||||
FROM wf_process_task
|
||||
WHERE taskState = 10
|
||||
) t ON t.processInstanceId = ins.id AND t.rn = 1
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or(SpecialCondolence::getHelpUserName, "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
seg.or(SpecialCondolence::getHelpLoginName, "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
cnd.and(seg);
|
||||
}
|
||||
cnd.andEX("year(info.createTime)", "=", year);
|
||||
cnd.andEX("info.type", "=", type);
|
||||
cnd.and("info.createdBy", "=", SecurityUtil.getUserId());
|
||||
|
||||
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
|
||||
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
|
||||
} else {
|
||||
cnd.desc("info.createTime");
|
||||
}
|
||||
|
||||
sql.setCondition(cnd);
|
||||
Pagination<NutMap> pagination = specialcondolenceService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出特殊慰问申请表")
|
||||
@SaCheckPermission("special_condolence.mine")
|
||||
public void doExportApply(String id, HttpServletResponse response, Boolean print) throws Exception {
|
||||
log.info("[特殊慰问导出] 开始,applyId={}, userId={}, format={}", id, SecurityUtil.getUserId(), Boolean.TRUE.equals(print) ? "PDF" : "Word");
|
||||
SpecialCondolence specialcondolence = specialcondolenceService.loadApplication(id);
|
||||
if (specialcondolence == null) throw new BaseException("该条记录不存在");
|
||||
if (!SecurityUtil.getUserId().equals(specialcondolence.getCreatedBy())) {
|
||||
throw new BaseException("只能导出本人提交的申请");
|
||||
}
|
||||
ProcessInstance instance = specialcondolenceService.dao().fetch(ProcessInstance.class,
|
||||
Cnd.where("businessNo", "=", id).desc("id"));
|
||||
if (instance == null || !ProcessInstanceStateEnum.FINISHED.getCode().equals(instance.getState())) {
|
||||
throw new BaseException("只能导出已完成的申请");
|
||||
}
|
||||
log.info("[特殊慰问导出] 流程已完成,applyId={}, instanceId={}, state={}, applicantSignPresent={}", id, instance.getId(), instance.getState(), StrUtil.isNotBlank(specialcondolence.getSignature()));
|
||||
NutMap docData = Lang.obj2nutmap(specialcondolence);
|
||||
docData.put("payUserName", StrUtil.nullToEmpty(specialcondolence.getBankUserName()));
|
||||
SpecialCondolenceType type = specialcondolenceService.dao().fetch(SpecialCondolenceType.class, specialcondolence.getType());
|
||||
docData.put("typeName", type == null ? "" : type.getName());
|
||||
docData.put("signature", null);
|
||||
if (StrUtil.isNotBlank(specialcondolence.getSignature())) {
|
||||
PictureRenderData signature = sysOfficeTemplateUtil.createPictureRenderData(90, 40, specialcondolence.getSignature());
|
||||
if (signature == null) throw new BaseException("申请人签字图片读取失败");
|
||||
docData.put("signature", signature);
|
||||
}
|
||||
fillApplyApprovals(docData, instance);
|
||||
for (String field : List.of("signature", "secondApprovalSign", "thirdApprovalSign", "fourthApprovalSign")) {
|
||||
Object value = docData.get(field);
|
||||
log.info("[特殊慰问导出] 渲染前图片字段,applyId={}, instanceId={}, field={}, valueType={}", id, instance.getId(), field, value == null ? "null" : value.getClass().getName());
|
||||
}
|
||||
String fileName = "重庆工贸职业技术学院特殊慰问申请表_" + StrUtil.nullToEmpty(specialcondolence.getHelpUserName());
|
||||
try (InputStream input = getClass().getResourceAsStream("/templates/condolence/重庆工贸职业技术学院职工慰问申请表.doc")) {
|
||||
if (input == null) throw new BaseException("特殊慰问申请表模板不存在");
|
||||
boolean pdf = Boolean.TRUE.equals(print);
|
||||
com.aspose.words.Document template = new com.aspose.words.Document(input);
|
||||
template.getRange().replace("职工慰问", "特殊慰问", new com.aspose.words.FindReplaceOptions());
|
||||
com.aspose.words.NodeCollection rows = template.getChildNodes(com.aspose.words.NodeType.ROW, true);
|
||||
for (int i = rows.getCount() - 1; i >= 0; i--) {
|
||||
com.aspose.words.Node row = rows.get(i);
|
||||
if (row.getText().contains("firstApproval") || row.getText().contains("分工会主席")) row.remove();
|
||||
}
|
||||
java.io.ByteArrayOutputStream templateOutput = new java.io.ByteArrayOutputStream();
|
||||
template.save(templateOutput, com.aspose.words.SaveFormat.DOCX);
|
||||
byte[] bytes;
|
||||
if (specialcondolence.getRecipients() != null && !specialcondolence.getRecipients().isEmpty()) {
|
||||
com.aspose.words.Document combined = null;
|
||||
for (cn.hutool.json.JSONObject person : specialcondolence.getRecipients()) {
|
||||
NutMap personData = new NutMap();
|
||||
personData.putAll(docData);
|
||||
personData.putAll(person);
|
||||
personData.put("payUserName", person.getStr("bankUserName"));
|
||||
byte[] rendered = sysOfficeTemplateUtil.renderTemplate(new java.io.ByteArrayInputStream(templateOutput.toByteArray()), personData, null, false, "specialcondolence:" + id);
|
||||
com.aspose.words.Document part = new com.aspose.words.Document(new java.io.ByteArrayInputStream(rendered));
|
||||
if (combined == null) combined = part;
|
||||
else combined.appendDocument(part, com.aspose.words.ImportFormatMode.KEEP_SOURCE_FORMATTING);
|
||||
}
|
||||
java.io.ByteArrayOutputStream output = new java.io.ByteArrayOutputStream();
|
||||
combined.save(output, pdf ? com.aspose.words.SaveFormat.PDF : com.aspose.words.SaveFormat.DOCX);
|
||||
bytes = output.toByteArray();
|
||||
} else {
|
||||
bytes = sysOfficeTemplateUtil.renderTemplate(new java.io.ByteArrayInputStream(templateOutput.toByteArray()), docData, null, pdf, "specialcondolence:" + id);
|
||||
}
|
||||
log.info("[特殊慰问导出] 渲染完成,applyId={}, format={}, outputBytes={}", id, pdf ? "PDF" : "Word", bytes.length);
|
||||
CommonDownloadUtil.download(fileName + (pdf ? ".pdf" : ".docx"), bytes, response);
|
||||
} catch (Exception e) {
|
||||
log.error("[特殊慰问导出] 模板渲染或文件输出失败,applyId={}, instanceId={}, format={}", id, instance.getId(), Boolean.TRUE.equals(print) ? "PDF" : "Word", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private void fillApplyApprovals(NutMap docData, ProcessInstance instance) {
|
||||
String[] taskKeys = {"c438972e-2f67-4907-b229-cb7aa17da147",
|
||||
"7f560675-aeea-4254-a57e-957d03d6b786", "af363a4e-fc56-42a0-9906-8c7a2814006b"};
|
||||
String[] fields = {"secondApproval", "thirdApproval", "fourthApproval"};
|
||||
List<String> suffixes = List.of("Opinion", "Sign", "Year", "Month", "Day");
|
||||
for (String field : fields) {
|
||||
for (String suffix : suffixes) docData.put(field + suffix, "Sign".equals(suffix) ? null : "");
|
||||
}
|
||||
List<ProcessTask> tasks = specialcondolenceService.dao().query(ProcessTask.class,
|
||||
Cnd.where("processInstanceId", "=", instance.getId()).asc("id"));
|
||||
log.info("[特殊慰问导出] 查询审批记录,applyId={}, instanceId={}, taskCount={}, expectedTaskKeys={}", instance.getBusinessNo(), instance.getId(), tasks.size(), List.of(taskKeys));
|
||||
for (ProcessTask task : tasks) {
|
||||
ProcessTaskVO taskVO = flowEngine.processTaskService().findById(task.getId());
|
||||
log.info("[特殊慰问导出] 审批记录,instanceId={}, taskId={}, taskKey={}, displayName={}, state={}, finishTime={}, isFirstTaskNode={}, matchedApproval={}", instance.getId(), task.getId(), task.getTaskName(), task.getDisplayName(), task.getTaskState(), task.getFinishTime(), taskVO.getExt() == null ? null : taskVO.getExt().get("isFirstTaskNode"), List.of(taskKeys).contains(task.getTaskName()));
|
||||
if ("startTask".equals(task.getTaskName()) || (!List.of(taskKeys).contains(task.getTaskName())
|
||||
&& taskVO.getExt() != null && Boolean.TRUE.equals(taskVO.getExt().getBool("isFirstTaskNode")))) {
|
||||
log.info("[特殊慰问导出] 申请节点重置本轮审批字段,instanceId={}, taskId={}, taskKey={}", instance.getId(), task.getId(), task.getTaskName());
|
||||
// 重新申请后,仅导出本轮审批记录。
|
||||
for (String field : fields) {
|
||||
for (String suffix : suffixes) docData.put(field + suffix, "Sign".equals(suffix) ? null : "");
|
||||
}
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < taskKeys.length; i++) {
|
||||
if (!taskKeys[i].equals(task.getTaskName())) continue;
|
||||
for (String suffix : suffixes) docData.put(fields[i] + suffix, "Sign".equals(suffix) ? null : "");
|
||||
if (!ProcessTaskStateEnum.FINISHED.getCode().equals(task.getTaskState())) {
|
||||
log.info("[特殊慰问导出] 跳过未完成审批,instanceId={}, taskId={}, field={}, state={}", instance.getId(), task.getId(), fields[i], task.getTaskState());
|
||||
continue;
|
||||
}
|
||||
Dict data = taskVO.getExt() == null ? Dict.create() : taskVO.getTaskFormData();
|
||||
log.info("[特殊慰问导出] 读取审批表单,instanceId={}, taskId={}, field={}, formKeys={}, signPresent={}, signReferenceLength={}", instance.getId(), task.getId(), fields[i], data.keySet(), StrUtil.isNotBlank(data.getStr("sign")), StrUtil.nullToEmpty(data.getStr("sign")).length());
|
||||
if (StrUtil.isBlank(data.getStr("sign"))) log.warn("[特殊慰问导出] 已完成审批缺少签名字段,instanceId={}, taskId={}, field={}", instance.getId(), task.getId(), fields[i]);
|
||||
docData.put(fields[i] + "Opinion", StrUtil.nullToEmpty(data.getStr("opinion")));
|
||||
if (StrUtil.isNotBlank(data.getStr("sign"))) {
|
||||
PictureRenderData signature = sysOfficeTemplateUtil.createPictureRenderData(90, 40, data.getStr("sign"));
|
||||
if (signature == null) throw new BaseException("审批签字图片读取失败");
|
||||
docData.put(fields[i] + "Sign", signature);
|
||||
log.info("[特殊慰问导出] 审批签名填充完成,instanceId={}, taskId={}, field={}", instance.getId(), task.getId(), fields[i] + "Sign");
|
||||
}
|
||||
docData.put(fields[i] + "Year", task.getFinishTime() == null ? "" : DateUtil.format(task.getFinishTime(), "yyyy"));
|
||||
docData.put(fields[i] + "Month", task.getFinishTime() == null ? "" : DateUtil.format(task.getFinishTime(), "M"));
|
||||
docData.put(fields[i] + "Day", task.getFinishTime() == null ? "" : DateUtil.format(task.getFinishTime(), "d"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("删除")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission(value = {"special_condolence.mine", "h5.special_condolence.mine"}, mode = SaMode.OR)
|
||||
@SLog(tag = "特殊慰问系统-我的申请", msg = "删除特殊慰问")
|
||||
public Result delete(@Param("id") String id) {
|
||||
specialcondolenceService.deleteApplication(id);
|
||||
flowEngine.processInstanceService().deleteProcessInstanceByBusinessKey(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("查询单个慰问申请信息")
|
||||
@SaCheckPermission(value = {"special_condolence", "h5.special_condolence"}, mode = SaMode.OR)
|
||||
public Result info(String id) {
|
||||
SpecialCondolence specialcondolence = specialcondolenceService.loadApplication(id);
|
||||
SpecialCondolenceType type = specialcondolenceService.dao().fetch(SpecialCondolenceType.class, Cnd.where(SpecialCondolenceType::getId, "=", specialcondolence.getType()));
|
||||
NutMap nutMap = Lang.obj2nutmap(specialcondolence);
|
||||
nutMap.put("typeName", type == null ? "" : type.getName());
|
||||
return Result.success(nutMap);
|
||||
}
|
||||
@Inject
|
||||
private SmsService smsService;
|
||||
}
|
||||
+177
@@ -0,0 +1,177 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.controller;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
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.CommonDownloadUtil;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||
import com.budwk.app.sys.param.SysMsgSummaryPageForm;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
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.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 javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceReadController
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 16:25
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "特殊慰问阅览")
|
||||
@At("/platform/special_condolence/read")
|
||||
public class SpecialCondolenceReadController {
|
||||
|
||||
@Inject
|
||||
private SpecialCondolenceService specialcondolenceService;
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("special_condolence.read")
|
||||
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/read/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("special_condolence.read")
|
||||
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) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
info.*,
|
||||
ins.id AS instanceId,
|
||||
type.name as typeName,
|
||||
ins.state instanceState,
|
||||
ins.processDefineId instanceProcessDefineId,
|
||||
t.displayName taskName
|
||||
FROM
|
||||
special_condolence info
|
||||
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
processInstanceId,
|
||||
displayName,
|
||||
createdAt,
|
||||
ROW_NUMBER() OVER (PARTITION BY processInstanceId ORDER BY createdAt DESC) AS rn
|
||||
FROM wf_process_task
|
||||
) t ON t.processInstanceId = ins.id AND t.rn = 1
|
||||
LEFT JOIN special_condolence_type type ON info.type = type.id
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("info.type", "=", type);
|
||||
cnd.andEX("YEAR(info.createTime)", "=", year);
|
||||
cnd.andEX("info.applyUnionId", "=", unionId);
|
||||
cnd.andEX("info.applyUnitId", "=", unitId);
|
||||
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or("info.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
seg.or("info.helpLoginName", "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
cnd.and(seg);
|
||||
}
|
||||
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_CHAIRMAN.name())) {
|
||||
cnd.and("info.applyUnionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
|
||||
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
|
||||
cnd.desc("info.createTime");
|
||||
} else {
|
||||
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
Pagination<NutMap> pageVO = specialcondolenceService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pageVO);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("special_condolence.read")
|
||||
@ApiOperation("导出特殊慰问汇总表")
|
||||
public void onExport(PageForm pageForm,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "type") String type,
|
||||
@Param(value = "unionId") String unionId,
|
||||
@Param(value = "unitId") String unitId,
|
||||
HttpServletResponse response) {
|
||||
//查询审核通过的数据
|
||||
Sql sql = Sqls.create("""
|
||||
select
|
||||
con.*,
|
||||
type.name as typeName
|
||||
from
|
||||
special_condolence con
|
||||
left join wf_process_instance ins on ins.businessNo = con.id
|
||||
left join special_condolence_type type on type.id = con.type
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and(ProcessInstance::getState, "=", ProcessTaskStateEnum.FINISHED.getCode());
|
||||
cnd.andEX("con.type", "=", type);
|
||||
cnd.andEX("YEAR(info.createTime)", "=", year);
|
||||
cnd.andEX("con.applyUnionId", "=", unionId);
|
||||
cnd.andEX("con.applyUnitId", "=", unitId);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or("info.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
seg.or("info.helpLoginName", "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
cnd.and(seg);
|
||||
}
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_CHAIRMAN.name())) {
|
||||
cnd.and("con.applyUnionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
List<NutMap> list = specialcondolenceService.listMap(sql);
|
||||
|
||||
List<ExcelExportEntity> exportEntities = new ArrayList<>();
|
||||
exportEntities.add(new ExcelExportEntity("慰问对象", "helpUserName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("慰问对象工号", "helpLoginName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("申请人", "applyUserName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所在工会", "helpUnionName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所在单位", "helpUnitName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("慰问类型", "typeName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("拟补贴金额", "money", 20));
|
||||
exportEntities.add(new ExcelExportEntity("申请理由", "remark", 20));
|
||||
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
|
||||
CommonDownloadUtil.download("申报人汇总.xlsx", workbook, response);
|
||||
}
|
||||
}
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
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.SecurityUtil;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.nutz.dao.Cnd;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2025/12/23 14:13
|
||||
* @description 校工会预审
|
||||
*/
|
||||
@IocBean
|
||||
@At("/platform/special_condolence/schoolPrincipalApproval")
|
||||
@Api("特殊慰问二级审核")
|
||||
@Ok("json:full")
|
||||
public class SpecialCondolenceSecondApprovalController {
|
||||
|
||||
@Inject
|
||||
private SpecialCondolenceService specialcondolenceService;
|
||||
|
||||
@At("/")
|
||||
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/schoolPrincipalApproval/index.html")
|
||||
@SaCheckPermission("special_condolence.secondApproval")
|
||||
public void index() {}
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/staffbenefit/specialcondolence/schoolPrincipalApproval/index.html")
|
||||
@SaCheckPermission("h5.special_condolence.secondApproval")
|
||||
public void h5Index() {}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission(value = {"special_condolence.secondApproval", "h5.special_condolence.secondApproval"}, 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 special_condolence info ON info.id = ins.businessNo
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN special_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();
|
||||
cnd.and("info.id", "is not", null);
|
||||
cnd.and(new Static("""
|
||||
NOT EXISTS (
|
||||
SELECT 1 FROM wf_process_task newer
|
||||
WHERE newer.processInstanceId = t.processInstanceId
|
||||
AND newer.taskName = t.taskName
|
||||
AND newer.id > t.id
|
||||
)
|
||||
"""));
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or(SpecialCondolence::getHelpUserName, "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
seg.or(SpecialCondolence::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", "=", "c438972e-2f67-4907-b229-cb7aa17da147");
|
||||
// cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
|
||||
|
||||
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 = specialcondolenceService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pageVO);
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
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.SecurityUtil;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.nutz.dao.Cnd;
|
||||
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 SpecialCondolenceThirdApprovalController
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 16:23
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@IocBean
|
||||
@At("/platform/special_condolence/schoolUnionApproval")
|
||||
@Api("特殊慰问三级审核")
|
||||
@Ok("json:full")
|
||||
public class SpecialCondolenceThirdApprovalController {
|
||||
|
||||
@Inject
|
||||
private SpecialCondolenceService specialcondolenceService;
|
||||
|
||||
@At("/")
|
||||
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/schoolUnionApproval/index.html")
|
||||
@SaCheckPermission("special_condolence.thirdApproval")
|
||||
public void index() {}
|
||||
|
||||
@At("/h5")
|
||||
@Ok("beetl:/platform/zhghh5/staffbenefit/specialcondolence/schoolUnionApproval/index.html")
|
||||
@SaCheckPermission("h5.special_condolence.thirdApproval")
|
||||
public void h5Index() {}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission(value = {"special_condolence.thirdApproval", "h5.special_condolence.thirdApproval"}, 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 special_condolence info ON info.id = ins.businessNo
|
||||
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||
LEFT JOIN special_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();
|
||||
cnd.and("info.id", "is not", null);
|
||||
cnd.and(new Static("""
|
||||
NOT EXISTS (
|
||||
SELECT 1 FROM wf_process_task newer
|
||||
WHERE newer.processInstanceId = t.processInstanceId
|
||||
AND newer.taskName = t.taskName
|
||||
AND newer.id > t.id
|
||||
)
|
||||
"""));
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or(SpecialCondolence::getHelpUserName, "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
seg.or(SpecialCondolence::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", "=", "7f560675-aeea-4254-a57e-957d03d6b786");
|
||||
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()));
|
||||
} 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 = specialcondolenceService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pageVO);
|
||||
}
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
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.zhgh.staffbenefit.specialcondolence.model.SpecialCondolenceType;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceTypeService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceTypeController
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 10:00
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "特殊慰问类型")
|
||||
@At("/platform/special_condolence/type")
|
||||
public class SpecialCondolenceTypeController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private SpecialCondolenceTypeService typeService;
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("special_condolence.type")
|
||||
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/type/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("special_condolence.type")
|
||||
public Result pageData(PageForm pageForm) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or(SpecialCondolenceType::getName, "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
seg.or(SpecialCondolenceType::getCode, "like", "%" + pageForm.getSearchKeyword() + "%");
|
||||
cnd.and(seg);
|
||||
}
|
||||
cnd.asc("code");
|
||||
Pagination pagination = typeService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("新增/修改特殊慰问类型")
|
||||
@SaCheckPermission("special_condolence.type")
|
||||
@SLog(tag = "特殊慰问系统-慰问类型", msg = "新增/修改特殊慰问类型")
|
||||
public Object onSubmit(SpecialCondolenceType type) {
|
||||
typeService.insertOrUpdate(type);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("删除特殊慰问类型")
|
||||
@SaCheckPermission("special_condolence.type")
|
||||
@SLog(tag = "特殊慰问系统-慰问类型", msg = "删除特殊慰问类型")
|
||||
public Object onDelete(String id) {
|
||||
typeService.delete(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("查询特殊慰问类型")
|
||||
@SaCheckLogin
|
||||
public Result querySpecialCondolenceType() {
|
||||
List<SpecialCondolenceType> list = typeService.query(Cnd.where(SpecialCondolenceType::getEnable, "=", true).asc(SpecialCondolenceType::getCode));
|
||||
return Result.success(list);
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.interceptor;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.flow.constant.FlowConst;
|
||||
import com.budwk.app.flow.engine.FlowInterceptor;
|
||||
import com.budwk.app.flow.engine.core.Execution;
|
||||
import com.budwk.app.flow.engine.core.ServiceContext;
|
||||
import com.budwk.app.flow.entity.ProcessInstance;
|
||||
import com.budwk.app.zhgh.dayofficework.article.models.Article;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.json.Json;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceSaveInterceptor
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/28 11:01
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
public class SpecialCondolenceSaveInterceptor implements FlowInterceptor {
|
||||
|
||||
@Override
|
||||
public void intercept(Execution execution) {
|
||||
if (!com.budwk.app.web.commons.auth.utils.AuthUtil.hasRoleOr("BRANCH_UNION_CHAIRMAN")) {
|
||||
throw new com.budwk.app.base.exception.BaseException("仅分工会主席可发起特殊慰问申请");
|
||||
}
|
||||
String formDataStr = execution.getArgs().getStr(FlowConst.FORM_DATA);
|
||||
SpecialCondolence specialcondolence = Json.fromJson(SpecialCondolence.class, formDataStr);
|
||||
|
||||
if(StrUtil.isBlank(specialcondolence.getId())) specialcondolence.setCreateTime(DateUtil.now());
|
||||
|
||||
Dao dao = ServiceContext.find(Dao.class);
|
||||
ServiceContext.find(com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService.class).saveApplication(specialcondolence);
|
||||
|
||||
// 设置流程变量
|
||||
execution.getArgs().set("origin", specialcondolence.getOrigin());
|
||||
|
||||
int instanceId = execution.getArgs().getInt(FlowConst.PROCESS_INSTANCE_ID_KEY);
|
||||
dao.update(ProcessInstance.class, Chain.make("businessNo", specialcondolence.getId()), Cnd.where(ProcessInstance::getId, "=", instanceId));
|
||||
|
||||
}
|
||||
}
|
||||
+304
@@ -0,0 +1,304 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.model;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import com.budwk.app.sys.models.Sys_file;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolence
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/28 11:03
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("special_condolence")
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
@Comment("特殊慰问")
|
||||
public class SpecialCondolence extends BaseModel {
|
||||
|
||||
@Name
|
||||
@Comment("ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("申请人ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String applyUserId;
|
||||
|
||||
@Column
|
||||
@Comment("申请人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String applyUserName;
|
||||
|
||||
@Column
|
||||
@Comment("申请人工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 120)
|
||||
private String applyLoginName;
|
||||
|
||||
@Column
|
||||
@Comment("申请人分工会ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String applyUnionId;
|
||||
|
||||
@Column
|
||||
@Comment("申请人分工会")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String applyUnionName;
|
||||
|
||||
@Column
|
||||
@Comment("申请人单位ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String applyUnitId;
|
||||
|
||||
@Column
|
||||
@Comment("申请人单位")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String applyUnitName;
|
||||
|
||||
@Column
|
||||
@Comment("补助人ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String helpUserId;
|
||||
|
||||
@Column
|
||||
@Comment("补助人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String helpUserName;
|
||||
|
||||
@Column
|
||||
@Comment("补助人工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 120)
|
||||
private String helpLoginName;
|
||||
|
||||
@Column
|
||||
@Comment("补助人分工会ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String helpUnionId;
|
||||
|
||||
@Column
|
||||
@Comment("补助人分工会")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String helpUnionName;
|
||||
|
||||
@Column
|
||||
@Comment("补助人单位ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String helpUnitId;
|
||||
|
||||
@Column
|
||||
@Comment("补助人单位")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String helpUnitName;
|
||||
|
||||
@Column
|
||||
@Comment("类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String origin;
|
||||
|
||||
@Column
|
||||
@Comment("收款人")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String payUserId;
|
||||
|
||||
@Column
|
||||
@Comment("收款人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String payUserName;
|
||||
|
||||
@Column
|
||||
@Comment("收款人工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String payLoginName;
|
||||
|
||||
@Column
|
||||
@Comment("慰问类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String type;
|
||||
|
||||
@Column
|
||||
@Comment("慰问编码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String typeCode;
|
||||
|
||||
@Column
|
||||
@Comment("慰问方式")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String way;
|
||||
|
||||
@Column
|
||||
@Comment("统一每人慰问金额")
|
||||
@ColDefine(customType = "decimal(10,2)")
|
||||
private java.math.BigDecimal perMoney;
|
||||
|
||||
@Column
|
||||
@Comment("慰问金额")
|
||||
@ColDefine(type = ColType.FLOAT, width = 10, precision = 2)
|
||||
private Double money;
|
||||
|
||||
@Column
|
||||
@Comment("发生时间")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String occurTime;
|
||||
|
||||
@Column
|
||||
@Comment("生育几孩(孩次)")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 10)
|
||||
private String child;
|
||||
|
||||
@Column
|
||||
@Comment("所在医院")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String hospital;
|
||||
|
||||
@Column
|
||||
@Comment("病房床号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String hospitalHouseNum;
|
||||
|
||||
@Column
|
||||
@Comment("病房床号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String hospitalHouseBedNum;
|
||||
|
||||
@Column
|
||||
@Comment("住院病由")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String hospitalBy;
|
||||
|
||||
@Column
|
||||
@Comment("备注")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 500)
|
||||
private String remark;
|
||||
|
||||
@Column
|
||||
@Comment("附件")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
private List<JSONObject> files;
|
||||
|
||||
@Comment("签字")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||
@Column(hump = true)
|
||||
private String signature;
|
||||
|
||||
@Column
|
||||
@Comment("申请时间")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String createTime;
|
||||
|
||||
|
||||
|
||||
|
||||
@Column
|
||||
@Comment("户名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String bankUserName;
|
||||
|
||||
@Column
|
||||
@Comment("银行账号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String bankCardNumber;
|
||||
|
||||
@Column
|
||||
@Comment("开户行")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String bankOfDeposit;
|
||||
|
||||
@Column
|
||||
@Comment("证明人ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String certifierUserId;
|
||||
|
||||
@Column
|
||||
@Comment("证明人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String certifierUserName;
|
||||
|
||||
@Column
|
||||
@Comment("证明人工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 120)
|
||||
private String certifierLoginName;
|
||||
|
||||
@Column
|
||||
@Comment("证明人分工会ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String certifierUnionId;
|
||||
|
||||
@Column
|
||||
@Comment("证明人分工会")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String certifierUnionName;
|
||||
|
||||
@Column
|
||||
@Comment("证明人单位ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String certifierUnitId;
|
||||
|
||||
@Column
|
||||
@Comment("证明人单位")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String certifierUnitName;
|
||||
|
||||
@Column
|
||||
@Comment("经办人ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String handlerUserId;
|
||||
|
||||
@Column
|
||||
@Comment("经办人姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String handlerUserName;
|
||||
|
||||
@Column
|
||||
@Comment("经办人工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 120)
|
||||
private String handlerLoginName;
|
||||
|
||||
@Column
|
||||
@Comment("经办人分工会ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String handlerUnionId;
|
||||
|
||||
@Column
|
||||
@Comment("经办人分工会")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String handlerUnionName;
|
||||
|
||||
@Column
|
||||
@Comment("经办人单位ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String handlerUnitId;
|
||||
|
||||
@Column
|
||||
@Comment("经办人单位")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String handlerUnitName;
|
||||
|
||||
@Column
|
||||
@Comment("入院时间")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String hospitalizationTime;
|
||||
|
||||
@Column
|
||||
@Comment("出院时间")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String leaveHospitalTime;
|
||||
|
||||
@Column
|
||||
@Comment("当年第几次住院")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer thisYearHospitalizationNum;
|
||||
|
||||
@Comment("慰问对象明细,由明细表加载")
|
||||
private List<JSONObject> recipients;
|
||||
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.model;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("special_condolence_recipient")
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
@TableIndexes({@Index(name = "idx_special_condolence_recipient_apply", fields = {"applyId"}, unique = false)})
|
||||
@Comment("特殊慰问被申请人明细")
|
||||
public class SpecialCondolenceRecipient extends BaseModel {
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("申请ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String applyId;
|
||||
|
||||
@Column
|
||||
@Comment("慰问对象用户ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String helpUserId;
|
||||
|
||||
@Column
|
||||
@Comment("人员类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String personType;
|
||||
|
||||
@Column
|
||||
@Comment("慰问对象工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 120)
|
||||
private String helpLoginName;
|
||||
|
||||
@Column
|
||||
@Comment("慰问对象")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String helpUserName;
|
||||
|
||||
@Column
|
||||
@Comment("慰问类型ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String type;
|
||||
|
||||
@Column
|
||||
@Comment("慰问类型名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String typeName;
|
||||
|
||||
@Column
|
||||
@Comment("慰问类型编码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String typeCode;
|
||||
|
||||
@Column
|
||||
@Comment("慰问方式")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String way;
|
||||
|
||||
@Column
|
||||
@Comment("身份证号码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 18)
|
||||
private String idCard;
|
||||
|
||||
@Column
|
||||
@Comment("开户行")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String bankOfDeposit;
|
||||
|
||||
@Column
|
||||
@Comment("户名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String bankUserName;
|
||||
|
||||
@Column
|
||||
@Comment("收款账户")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String bankCardNumber;
|
||||
|
||||
@Column
|
||||
@Comment("慰问金额")
|
||||
@ColDefine(customType = "decimal(10,2)")
|
||||
private java.math.BigDecimal money;
|
||||
|
||||
@Column
|
||||
@Comment("慰问时间")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String occurTime;
|
||||
|
||||
@Column
|
||||
@Comment("行序号")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer sortNum;
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.model;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.nutz.dao.DB;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceType
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 9:59
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Table("special_condolence_type")
|
||||
@TableMeta("{'mysql-charset':'utf8mb4'}")
|
||||
@Comment("特殊慰问类型")
|
||||
public class SpecialCondolenceType extends BaseModel {
|
||||
|
||||
@Name
|
||||
@Comment("ID")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("编码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String code;
|
||||
|
||||
@Column
|
||||
@Comment("名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String name;
|
||||
|
||||
@Column
|
||||
@Comment("费用")
|
||||
@ColDefine(type = ColType.FLOAT, width = 10, precision = 2)
|
||||
private Double money;
|
||||
|
||||
@Column
|
||||
@Comment("慰问方式")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String way;
|
||||
|
||||
@Column
|
||||
@Comment("是否启用")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("1")
|
||||
private Boolean enable;
|
||||
|
||||
@Column
|
||||
@Comment("是否上传附件")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Boolean isUploadFile;
|
||||
|
||||
@Column
|
||||
@Comment("上传附件说明")
|
||||
@ColDefine(type = ColType.VARCHAR,width = 50)
|
||||
private String uploadFileDesc;
|
||||
|
||||
@Column
|
||||
@Comment("排序字段")
|
||||
@Prev({
|
||||
@SQL(db = DB.MYSQL, value = "SELECT IFNULL(MAX(location),0)+1 FROM special_condolence_type"),
|
||||
@SQL(db = DB.ORACLE, value = "SELECT COALESCE(MAX(location),0)+1 FROM special_condolence_type")
|
||||
})
|
||||
private Integer location;
|
||||
|
||||
@Column
|
||||
@Comment("排序")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private int sortNum;
|
||||
|
||||
@Column
|
||||
@Comment("上传会议纪要")
|
||||
@Default("0")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Boolean uploadMeetingRecord;
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.service;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolenceType;
|
||||
import org.nutz.dao.Dao;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
|
||||
public final class SpecialCondolenceRecipients {
|
||||
private SpecialCondolenceRecipients() {}
|
||||
|
||||
public static void prepare(SpecialCondolence info, Dao dao) {
|
||||
List<JSONObject> rows = info.getRecipients();
|
||||
if (rows == null || rows.isEmpty()) throw new BaseException("请添加慰问对象");
|
||||
if (rows.size() > 1000) throw new BaseException("每次申请最多1000人");
|
||||
if (info.getFiles() != null && info.getFiles().size() > 5) throw new BaseException("最多上传5个附件");
|
||||
if (info.getRemark() != null && info.getRemark().trim().length() > 500) throw new BaseException("申请事由最多500字");
|
||||
if (info.getPerMoney() == null || info.getPerMoney().signum() <= 0 || info.getPerMoney().compareTo(new BigDecimal("10000")) > 0 || info.getPerMoney().scale() > 2) throw new BaseException("每人慰问金额须大于0且不超过10000元,最多两位小数");
|
||||
try { LocalDate.parse(info.getOccurTime()); }
|
||||
catch (Exception e) { throw new BaseException("请选择有效的统一慰问时间"); }
|
||||
BigDecimal total = BigDecimal.ZERO;
|
||||
for (int i = 0; i < rows.size(); i++) {
|
||||
JSONObject row = rows.get(i);
|
||||
String prefix = "第" + (i + 1) + "行:";
|
||||
if (row == null) throw new BaseException(prefix + "明细不能为空");
|
||||
row.set("type", info.getType());
|
||||
row.set("money", info.getPerMoney().toPlainString());
|
||||
row.set("occurTime", info.getOccurTime());
|
||||
resolveUser(row, dao, prefix);
|
||||
String[] fields = {"helpUserName", "type", "idCard", "bankOfDeposit", "bankUserName", "bankCardNumber", "money", "occurTime"};
|
||||
for (String field : fields) {
|
||||
String value = row.getStr(field);
|
||||
if (value == null || value.trim().isEmpty()) throw new BaseException(prefix + "请填写完整的慰问对象信息");
|
||||
row.set(field, value.trim());
|
||||
}
|
||||
if (!validIdCard(row.getStr("idCard"))) throw new BaseException(prefix + "身份证号码不正确");
|
||||
if (!row.getStr("bankCardNumber").matches("[0-9]{6,30}")) throw new BaseException(prefix + "收款账户须为6至30位数字");
|
||||
if (row.getStr("helpUserName").length() > 100 || row.getStr("bankOfDeposit").length() > 100 || row.getStr("bankUserName").length() > 100) throw new BaseException(prefix + "姓名、开户行、户名不能超过100字");
|
||||
if (!row.getStr("money").matches("[0-9]+(\\.[0-9]{1,2})?")) throw new BaseException(prefix + "金额最多两位小数");
|
||||
BigDecimal money = new BigDecimal(row.getStr("money"));
|
||||
if (money.signum() <= 0 || money.compareTo(new BigDecimal("10000")) > 0) throw new BaseException(prefix + "金额须大于0且不超过10000元");
|
||||
try { LocalDate.parse(row.getStr("occurTime")); }
|
||||
catch (Exception e) { throw new BaseException(prefix + "慰问时间格式须为yyyy-MM-dd"); }
|
||||
SpecialCondolenceType type = dao.fetch(SpecialCondolenceType.class, row.getStr("type"));
|
||||
if (type == null || !Boolean.TRUE.equals(type.getEnable())) throw new BaseException(prefix + "慰问类型不存在或已停用");
|
||||
row.set("typeName", type.getName());
|
||||
row.set("typeCode", type.getCode());
|
||||
row.set("way", type.getWay());
|
||||
if (Boolean.TRUE.equals(type.getIsUploadFile()) && (info.getFiles() == null || info.getFiles().isEmpty())) throw new BaseException(prefix + "该慰问类型需要上传附件");
|
||||
total = total.add(money);
|
||||
}
|
||||
JSONObject first = rows.get(0);
|
||||
String name = first.getStr("helpUserName");
|
||||
info.setHelpUserName((rows.size() > 1 && name.length() > 90 ? name.substring(0, 90) : name) + (rows.size() > 1 ? "等" + rows.size() + "人" : ""));
|
||||
info.setHelpUnitId(info.getApplyUnitId());
|
||||
info.setHelpUnitName(info.getApplyUnitName());
|
||||
info.setHelpUnionId(info.getApplyUnionId());
|
||||
info.setHelpUnionName(info.getApplyUnionName());
|
||||
info.setType(first.getStr("type"));
|
||||
info.setTypeCode(first.getStr("typeCode"));
|
||||
info.setWay(first.getStr("way"));
|
||||
info.setOccurTime(first.getStr("occurTime"));
|
||||
info.setMoney(total.doubleValue());
|
||||
info.setBankOfDeposit(first.getStr("bankOfDeposit"));
|
||||
info.setBankUserName(first.getStr("bankUserName"));
|
||||
info.setBankCardNumber(first.getStr("bankCardNumber"));
|
||||
}
|
||||
|
||||
public static void resolveUser(JSONObject row, Dao dao, String prefix) {
|
||||
String userId = row.getStr("helpUserId");
|
||||
com.budwk.app.sys.views.View_user user;
|
||||
String unionId = com.budwk.app.web.commons.auth.utils.SecurityUtil.getUnionId();
|
||||
if (cn.hutool.core.util.StrUtil.isBlank(unionId)) throw new BaseException(prefix + "申请人未关联分工会");
|
||||
if (cn.hutool.core.util.StrUtil.isNotBlank(userId)) {
|
||||
user = dao.fetch(com.budwk.app.sys.views.View_user.class, org.nutz.dao.Cnd.where("id", "=", userId));
|
||||
} else {
|
||||
org.nutz.dao.Cnd identity = org.nutz.dao.Cnd.where("unionId", "=", unionId)
|
||||
.and("idCard", "=", row.getStr("idCard")).and("username", "=", row.getStr("helpUserName"));
|
||||
java.util.List<com.budwk.app.sys.views.View_user> dispatched = dao.query(com.budwk.app.sys.views.View_user.class,
|
||||
identity.and("personType", "=", "劳务派遣人员"));
|
||||
if (dispatched.size() > 1) throw new BaseException(prefix + "劳务派遣人员身份重复,请核对档案");
|
||||
if (dispatched.size() == 1) {
|
||||
user = dispatched.get(0);
|
||||
} else {
|
||||
if (cn.hutool.core.util.StrUtil.isBlank(row.getStr("helpLoginName"))) throw new BaseException(prefix + "普通人员必须填写工号");
|
||||
java.util.List<com.budwk.app.sys.views.View_user> users = dao.query(com.budwk.app.sys.views.View_user.class,
|
||||
org.nutz.dao.Cnd.where("unionId", "=", unionId).and("loginname", "=", row.getStr("helpLoginName"))
|
||||
.and("username", "=", row.getStr("helpUserName")).and("idCard", "=", row.getStr("idCard")));
|
||||
if (users.size() != 1) throw new BaseException(prefix + "工号、姓名、身份证不匹配或不属于申请人本工会");
|
||||
user = users.get(0);
|
||||
}
|
||||
}
|
||||
if (user == null) throw new BaseException(prefix + "慰问对象不存在");
|
||||
if (!java.util.Objects.equals(user.getUnionId(), unionId)) throw new BaseException(prefix + "只能选择申请人本工会人员");
|
||||
if (!"劳务派遣人员".equals(user.getPersonType()) && (cn.hutool.core.util.StrUtil.isBlank(row.getStr("helpLoginName")) || !java.util.Objects.equals(user.getLoginname(), row.getStr("helpLoginName")))) throw new BaseException(prefix + "工号与慰问对象不一致");
|
||||
if (cn.hutool.core.util.StrUtil.isNotBlank(user.getIdCard()) && !user.getIdCard().equalsIgnoreCase(row.getStr("idCard"))) throw new BaseException(prefix + "身份证号码与所选人员不一致");
|
||||
row.set("helpUserId", user.getId());
|
||||
row.set("helpLoginName", user.getLoginname());
|
||||
row.set("personType", user.getPersonType());
|
||||
row.set("helpUserName", user.getUsername());
|
||||
}
|
||||
|
||||
public static boolean validIdCard(String value) {
|
||||
if (value == null || !value.matches("[1-9][0-9]{16}[0-9Xx]")) return false;
|
||||
try { LocalDate.parse(value.substring(6, 14), java.time.format.DateTimeFormatter.BASIC_ISO_DATE); }
|
||||
catch (Exception e) { return false; }
|
||||
int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
|
||||
int sum = 0;
|
||||
for (int i = 0; i < weights.length; i++) sum += (value.charAt(i) - '0') * weights[i];
|
||||
return "10X98765432".charAt(sum % 11) == Character.toUpperCase(value.charAt(17));
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceService
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 11:21
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
public interface SpecialCondolenceService extends BaseService<SpecialCondolence> {
|
||||
void saveApplication(SpecialCondolence info);
|
||||
SpecialCondolence loadApplication(String id);
|
||||
void deleteApplication(String id);
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolenceType;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceTypeService
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 10:03
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
public interface SpecialCondolenceTypeService extends BaseService<SpecialCondolenceType> {
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.service.impl;
|
||||
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolenceRecipient;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceRecipients;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceServiceImpl
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 11:22
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class SpecialCondolenceServiceImpl extends BaseServiceImpl<SpecialCondolence> implements SpecialCondolenceService {
|
||||
|
||||
public SpecialCondolenceServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void saveApplication(SpecialCondolence info) {
|
||||
SpecialCondolenceRecipients.prepare(info, dao());
|
||||
dao().insertOrUpdate(info);
|
||||
dao().clear(SpecialCondolenceRecipient.class,
|
||||
Cnd.where("applyId", "=", info.getId()));
|
||||
int sort = 0;
|
||||
for (JSONObject row : info.getRecipients()) {
|
||||
SpecialCondolenceRecipient person = new SpecialCondolenceRecipient();
|
||||
person.setApplyId(info.getId());
|
||||
person.setHelpUserName(row.getStr("helpUserName"));
|
||||
person.setHelpUserId(row.getStr("helpUserId"));
|
||||
person.setHelpLoginName(row.getStr("helpLoginName"));
|
||||
person.setPersonType(row.getStr("personType"));
|
||||
person.setType(row.getStr("type"));
|
||||
person.setTypeName(row.getStr("typeName"));
|
||||
person.setTypeCode(row.getStr("typeCode"));
|
||||
person.setWay(row.getStr("way"));
|
||||
person.setIdCard(row.getStr("idCard"));
|
||||
person.setBankOfDeposit(row.getStr("bankOfDeposit"));
|
||||
person.setBankUserName(row.getStr("bankUserName"));
|
||||
person.setBankCardNumber(row.getStr("bankCardNumber"));
|
||||
person.setMoney(new BigDecimal(row.getStr("money")));
|
||||
person.setOccurTime(row.getStr("occurTime"));
|
||||
person.setSortNum(sort++);
|
||||
dao().insert(person);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpecialCondolence loadApplication(String id) {
|
||||
SpecialCondolence info = fetch(id);
|
||||
if (info != null) {
|
||||
List<JSONObject> rows = new ArrayList<>();
|
||||
for (SpecialCondolenceRecipient person : dao().query(
|
||||
SpecialCondolenceRecipient.class,
|
||||
Cnd.where("applyId", "=", id).asc("sortNum").asc("id"))) {
|
||||
rows.add(JSONUtil.parseObj(person));
|
||||
}
|
||||
info.setRecipients(rows);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void deleteApplication(String id) {
|
||||
dao().clear(SpecialCondolenceRecipient.class,
|
||||
Cnd.where("applyId", "=", id));
|
||||
delete(id);
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.budwk.app.zhgh.staffbenefit.specialcondolence.service.impl;
|
||||
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolenceType;
|
||||
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceTypeService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
/**
|
||||
* @ClassName SpecialCondolenceTypeServiceImpl
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/7/29 10:03
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class SpecialCondolenceTypeServiceImpl extends BaseServiceImpl<SpecialCondolenceType> implements SpecialCondolenceTypeService {
|
||||
|
||||
public SpecialCondolenceTypeServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
-- 全量初始化:完整定义特殊慰问申请主表、被申请人明细表和慰问类型表。
|
||||
-- 表已存在时不执行本文件中的建表语句;本文件不复制数据、不配置角色授权和工作流。
|
||||
CREATE TABLE `special_condolence` (
|
||||
`id` varchar(32) NOT NULL COMMENT 'ID',
|
||||
`applyUserId` varchar(32) DEFAULT NULL COMMENT '申请人ID',
|
||||
`applyUserName` varchar(100) DEFAULT NULL COMMENT '申请人姓名',
|
||||
`applyLoginName` varchar(120) DEFAULT NULL COMMENT '申请人工号',
|
||||
`applyUnionId` varchar(32) DEFAULT NULL COMMENT '申请人分工会ID',
|
||||
`applyUnionName` varchar(100) DEFAULT NULL COMMENT '申请人分工会',
|
||||
`applyUnitId` varchar(32) DEFAULT NULL COMMENT '申请人单位ID',
|
||||
`applyUnitName` varchar(100) DEFAULT NULL COMMENT '申请人单位',
|
||||
`helpUserId` varchar(32) DEFAULT NULL COMMENT '补助人ID',
|
||||
`helpUserName` varchar(100) DEFAULT NULL COMMENT '补助人姓名',
|
||||
`helpLoginName` varchar(120) DEFAULT NULL COMMENT '补助人工号',
|
||||
`helpUnionId` varchar(32) DEFAULT NULL COMMENT '补助人分工会ID',
|
||||
`helpUnionName` varchar(100) DEFAULT NULL COMMENT '补助人分工会',
|
||||
`helpUnitId` varchar(32) DEFAULT NULL COMMENT '补助人单位ID',
|
||||
`helpUnitName` varchar(100) DEFAULT NULL COMMENT '补助人单位',
|
||||
`origin` varchar(20) DEFAULT NULL COMMENT '类型',
|
||||
`payUserId` varchar(32) DEFAULT NULL COMMENT '收款人',
|
||||
`payUserName` varchar(30) DEFAULT NULL COMMENT '收款人姓名',
|
||||
`payLoginName` varchar(20) DEFAULT NULL COMMENT '收款人工号',
|
||||
`type` varchar(32) DEFAULT NULL COMMENT '慰问类型',
|
||||
`typeCode` varchar(32) DEFAULT NULL COMMENT '慰问编码',
|
||||
`way` varchar(20) DEFAULT NULL COMMENT '慰问方式',
|
||||
`perMoney` decimal(10,2) DEFAULT NULL COMMENT '统一每人慰问金额',
|
||||
`money` float(10,2) DEFAULT NULL COMMENT '慰问金额',
|
||||
`occurTime` varchar(30) DEFAULT NULL COMMENT '发生时间',
|
||||
`child` varchar(10) DEFAULT NULL COMMENT '生育几孩(孩次)',
|
||||
`hospital` varchar(50) DEFAULT NULL COMMENT '所在医院',
|
||||
`hospitalHouseNum` varchar(20) DEFAULT NULL COMMENT '病房床号',
|
||||
`hospitalHouseBedNum` varchar(20) DEFAULT NULL COMMENT '病房床号',
|
||||
`hospitalBy` varchar(100) DEFAULT NULL COMMENT '住院病由',
|
||||
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
|
||||
`files` json DEFAULT NULL COMMENT '附件',
|
||||
`signature` varchar(255) DEFAULT NULL COMMENT '签字',
|
||||
`createTime` varchar(30) DEFAULT NULL COMMENT '申请时间',
|
||||
`bankUserName` varchar(100) DEFAULT NULL COMMENT '户名',
|
||||
`bankCardNumber` varchar(100) DEFAULT NULL COMMENT '银行账号',
|
||||
`bankOfDeposit` varchar(100) DEFAULT NULL COMMENT '开户行',
|
||||
`certifierUserId` varchar(32) DEFAULT NULL COMMENT '证明人ID',
|
||||
`certifierUserName` varchar(100) DEFAULT NULL COMMENT '证明人姓名',
|
||||
`certifierLoginName` varchar(120) DEFAULT NULL COMMENT '证明人工号',
|
||||
`certifierUnionId` varchar(32) DEFAULT NULL COMMENT '证明人分工会ID',
|
||||
`certifierUnionName` varchar(100) DEFAULT NULL COMMENT '证明人分工会',
|
||||
`certifierUnitId` varchar(32) DEFAULT NULL COMMENT '证明人单位ID',
|
||||
`certifierUnitName` varchar(100) DEFAULT NULL COMMENT '证明人单位',
|
||||
`handlerUserId` varchar(32) DEFAULT NULL COMMENT '经办人ID',
|
||||
`handlerUserName` varchar(100) DEFAULT NULL COMMENT '经办人姓名',
|
||||
`handlerLoginName` varchar(120) DEFAULT NULL COMMENT '经办人工号',
|
||||
`handlerUnionId` varchar(32) DEFAULT NULL COMMENT '经办人分工会ID',
|
||||
`handlerUnionName` varchar(100) DEFAULT NULL COMMENT '经办人分工会',
|
||||
`handlerUnitId` varchar(32) DEFAULT NULL COMMENT '经办人单位ID',
|
||||
`handlerUnitName` varchar(100) DEFAULT NULL COMMENT '经办人单位',
|
||||
`hospitalizationTime` varchar(30) DEFAULT NULL COMMENT '入院时间',
|
||||
`leaveHospitalTime` varchar(30) DEFAULT NULL COMMENT '出院时间',
|
||||
`thisYearHospitalizationNum` int DEFAULT NULL COMMENT '当年第几次住院',
|
||||
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
|
||||
`createdAt` bigint DEFAULT NULL COMMENT '创建时间(毫秒时间戳)',
|
||||
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
|
||||
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间(毫秒时间戳)',
|
||||
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='特殊慰问申请';
|
||||
|
||||
CREATE TABLE `special_condolence_type` (
|
||||
`id` varchar(32) NOT NULL COMMENT 'ID',
|
||||
`code` varchar(30) DEFAULT NULL COMMENT '编码',
|
||||
`name` varchar(50) DEFAULT NULL COMMENT '名称',
|
||||
`money` float(10,2) DEFAULT NULL COMMENT '费用',
|
||||
`way` varchar(20) DEFAULT NULL COMMENT '慰问方式',
|
||||
`enable` tinyint(1) DEFAULT 1 COMMENT '是否启用',
|
||||
`isUploadFile` tinyint(1) DEFAULT NULL COMMENT '是否上传附件',
|
||||
`uploadFileDesc` varchar(50) DEFAULT NULL COMMENT '上传附件说明',
|
||||
`location` int DEFAULT NULL COMMENT '排序字段',
|
||||
`sortNum` int NOT NULL DEFAULT 0 COMMENT '排序',
|
||||
`uploadMeetingRecord` tinyint(1) DEFAULT 0 COMMENT '上传会议纪要',
|
||||
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
|
||||
`createdAt` bigint DEFAULT NULL COMMENT '创建时间(毫秒时间戳)',
|
||||
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
|
||||
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间(毫秒时间戳)',
|
||||
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='特殊慰问类型';
|
||||
|
||||
-- 一份申请对应一个流程实例;多名被申请人通过 applyId 关联同一份申请。
|
||||
CREATE TABLE `special_condolence_recipient` (
|
||||
`id` varchar(32) NOT NULL COMMENT '明细ID',
|
||||
`applyId` varchar(32) NOT NULL COMMENT '申请主表ID',
|
||||
`helpUserId` varchar(32) NOT NULL COMMENT '慰问对象用户ID',
|
||||
`helpLoginName` varchar(120) DEFAULT NULL COMMENT '慰问对象工号',
|
||||
`personType` varchar(50) DEFAULT NULL COMMENT '人员类型',
|
||||
`helpUserName` varchar(100) NOT NULL COMMENT '慰问对象',
|
||||
`type` varchar(32) NOT NULL COMMENT '慰问类型ID',
|
||||
`typeName` varchar(50) DEFAULT NULL COMMENT '慰问类型名称',
|
||||
`typeCode` varchar(32) DEFAULT NULL COMMENT '慰问类型编码',
|
||||
`way` varchar(20) DEFAULT NULL COMMENT '慰问方式',
|
||||
`idCard` varchar(18) NOT NULL COMMENT '身份证号码',
|
||||
`bankOfDeposit` varchar(100) NOT NULL COMMENT '开户行',
|
||||
`bankUserName` varchar(100) NOT NULL COMMENT '户名',
|
||||
`bankCardNumber` varchar(30) NOT NULL COMMENT '收款账户',
|
||||
`money` decimal(10,2) NOT NULL COMMENT '慰问金额',
|
||||
`occurTime` varchar(30) NOT NULL COMMENT '慰问时间',
|
||||
`sortNum` int NOT NULL DEFAULT 0 COMMENT '行序号',
|
||||
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
|
||||
`createdAt` bigint DEFAULT NULL COMMENT '创建时间(毫秒时间戳)',
|
||||
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
|
||||
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间(毫秒时间戳)',
|
||||
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_special_condolence_recipient_apply` (`applyId`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='特殊慰问被申请人明细';
|
||||
|
||||
-- 主表保留原有摘要字段兼容现有列表,money 为整份申请的金额合计。
|
||||
-- 被申请人的完整信息保存在 special_condolence_recipient 中,不在主表使用 JSON 存储。
|
||||
|
||||
-- 新增 PC、H5 菜单,角色授权由管理员另行配置。
|
||||
START TRANSACTION;
|
||||
CREATE TEMPORARY TABLE special_condolence_menu_map AS
|
||||
SELECT id oldId, MD5(CONCAT('special_condolence:', id)) newId
|
||||
FROM sys_menu
|
||||
WHERE id IN ('3b49290f7db44130b9f6394a8212321f', '024811fd168e44948e6ab84911fc26bb')
|
||||
OR (href LIKE '/platform/condolence/%' AND href NOT LIKE '%/branchUnionApproval%');
|
||||
CREATE TEMPORARY TABLE special_condolence_parent_map (
|
||||
oldId varchar(32) NOT NULL COMMENT '原父菜单ID',
|
||||
newId varchar(32) NOT NULL COMMENT '特殊慰问父菜单ID',
|
||||
PRIMARY KEY (oldId)
|
||||
);
|
||||
INSERT INTO special_condolence_parent_map (oldId, newId)
|
||||
SELECT oldId, newId FROM special_condolence_menu_map;
|
||||
|
||||
INSERT INTO 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)
|
||||
SELECT map.newId, COALESCE(parent.newId, m.parentId),
|
||||
CONCAT('T', SUBSTRING(map.newId, 1, 7)), REPLACE(m.name, '职工慰问', '特殊慰问'),
|
||||
m.aliasName, m.type, REPLACE(m.href, '/condolence/', '/special_condolence/'), m.target,
|
||||
m.icon, m.showit, m.disabled,
|
||||
CASE m.id WHEN '3b49290f7db44130b9f6394a8212321f' THEN 'special_condolence'
|
||||
WHEN '024811fd168e44948e6ab84911fc26bb' THEN 'h5.special_condolence'
|
||||
ELSE REPLACE(m.permission, 'condolence', 'special_condolence') END,
|
||||
REPLACE(m.note, '职工慰问', '特殊慰问'), m.location, m.hasChildren,
|
||||
m.createdBy, UNIX_TIMESTAMP()*1000, m.updatedBy, UNIX_TIMESTAMP()*1000, m.delFlag,
|
||||
REPLACE(m.processKey, 'ZGWW', 'TSWW'), m.platform, m.moduleId, m.isQuickEntry,
|
||||
m.picIcon, IF(m.name = '职工慰问', 't', m.initialPinyinName), m.isRecommendApp, m.isRecommendService
|
||||
FROM sys_menu m JOIN special_condolence_menu_map map ON map.oldId = m.id
|
||||
LEFT JOIN special_condolence_parent_map parent ON parent.oldId = m.parentId
|
||||
WHERE NOT EXISTS (SELECT 1 FROM sys_menu existing WHERE existing.id = map.newId);
|
||||
|
||||
-- 父子菜单路径保持树形前缀关系。
|
||||
UPDATE sys_menu child JOIN sys_menu parent ON parent.id = child.parentId
|
||||
JOIN special_condolence_menu_map map ON map.newId = child.id
|
||||
SET child.path = CONCAT(parent.path, RIGHT(child.id, 4));
|
||||
|
||||
DROP TEMPORARY TABLE special_condolence_menu_map;
|
||||
DROP TEMPORARY TABLE special_condolence_parent_map;
|
||||
|
||||
-- 权限部分,不要删除
|
||||
-- SYSADMIN
|
||||
-- 特殊慰问 web
|
||||
INSERT INTO sys_role_menu (roleId, menuId) VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '4c46696d75ff0eddf5cb57fac3e5d06d');
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '3e97a91e7aa9566cdae94850038a6212'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', '6c5be59ffb8d7c524ec72f2a02d6c6d2'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', '7f66eb63b6ebd81c5eee9c5c2de2ed98'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', '8d5ebaa091eee01abb33e89e3dcc92f8'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', '9c37242f50c5fb4a9c1b2b9b9dd0e2fd'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', '9f4f850904fe751db1cd13977374f99b'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', 'b24a5bef9ccbf7241c5bb85e80352f8f');
|
||||
|
||||
-- 特殊慰问 h5
|
||||
INSERT INTO sys_role_menu (roleId, menuId) VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '2145812145ee6548552504b4f5a55ff7');
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '42b4b5f54593cf023961ad1c9ce36f53'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', '4f3212a13a54fbb2a082ee77651c9a73'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', '739f64c71fe776dc3520ebb2977c2d68'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', 'b6c725beaf3bfe9f2b29f46855c45a24'),
|
||||
('7f4a820d5a394bb8a0a92d6699afe7c8', 'eb3d1b27d51b84df1cebf24e1278e26c');
|
||||
|
||||
|
||||
-- 校工会办公室主任
|
||||
-- 特殊慰问 web
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES
|
||||
('494ac71eb8b44d0e99e19b7fde6bd469', '4c46696d75ff0eddf5cb57fac3e5d06d'),
|
||||
('494ac71eb8b44d0e99e19b7fde6bd469', '7f66eb63b6ebd81c5eee9c5c2de2ed98');
|
||||
|
||||
-- 特殊慰问 h5
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES
|
||||
('494ac71eb8b44d0e99e19b7fde6bd469', '2145812145ee6548552504b4f5a55ff7'),
|
||||
('494ac71eb8b44d0e99e19b7fde6bd469', '42b4b5f54593cf023961ad1c9ce36f53');
|
||||
|
||||
-- 校工会主席
|
||||
-- 特殊慰问 web
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES
|
||||
('6aece46b946e4fb9ac4cb15c0cd8c3e6', '4c46696d75ff0eddf5cb57fac3e5d06d'),
|
||||
('6aece46b946e4fb9ac4cb15c0cd8c3e6', 'b24a5bef9ccbf7241c5bb85e80352f8f');
|
||||
|
||||
-- 特殊慰问 h5
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES
|
||||
('6aece46b946e4fb9ac4cb15c0cd8c3e6', '2145812145ee6548552504b4f5a55ff7'),
|
||||
('6aece46b946e4fb9ac4cb15c0cd8c3e6', 'b6c725beaf3bfe9f2b29f46855c45a24');
|
||||
|
||||
-- 校工会主席
|
||||
-- 特殊慰问 web
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES
|
||||
('b3854469e6f44901b22bb791cb538431', '4c46696d75ff0eddf5cb57fac3e5d06d'),
|
||||
('b3854469e6f44901b22bb791cb538431', '9c37242f50c5fb4a9c1b2b9b9dd0e2fd');
|
||||
|
||||
-- 特殊慰问 h5
|
||||
INSERT INTO sys_role_menu (roleId, menuId)
|
||||
VALUES
|
||||
('b3854469e6f44901b22bb791cb538431', '2145812145ee6548552504b4f5a55ff7'),
|
||||
('b3854469e6f44901b22bb791cb538431', '739f64c71fe776dc3520ebb2977c2d68');
|
||||
|
||||
|
||||
COMMIT;
|
||||
Binary file not shown.
@@ -1,8 +1,9 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<div id="app">
|
||||
<el-card shadow="never" v-if="isShow">
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never" v-if="pageLoading" v-loading="pageLoading" element-loading-text="正在加载申请信息" style="min-height: 300px"></el-card>
|
||||
<el-card shadow="never" v-else-if="isShow">
|
||||
<snaker-start slot="header" label="困难帮扶申请" define_key="KNBF"></snaker-start>
|
||||
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=":" class="flow-task-form">
|
||||
<el-descriptions :column="3" border>
|
||||
@@ -318,6 +319,7 @@ layout("/layouts/platform.html"){
|
||||
bizId: GetQueryString("bizId"),
|
||||
taskId: GetQueryString("taskId"),
|
||||
isShow: false,
|
||||
pageLoading: true,
|
||||
time: '',
|
||||
blockMessage: '',
|
||||
formData: {
|
||||
@@ -453,10 +455,12 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
},
|
||||
findOne(id) {
|
||||
this.$axios.post('/platform/difficultHelp/mine/findOne', { id }).then(res => {
|
||||
return this.$axios.post('/platform/difficultHelp/mine/findOne', { id }).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.formData = res.data
|
||||
this.queryRecipients(res.data.loginName)
|
||||
} else {
|
||||
throw new Error(res.msg || '申请信息加载失败,请刷新页面重试')
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -617,7 +621,7 @@ layout("/layouts/platform.html"){
|
||||
return { status: 200, msg: "卡号有效。" };
|
||||
},
|
||||
async getIsCanPlay() {
|
||||
this.$axios.post('/platform/difficultHelp/apply/getIsCanPlay').then(res => {
|
||||
return this.$axios.post('/platform/difficultHelp/apply/getIsCanPlay').then(res => {
|
||||
if (res.code === 0) {
|
||||
// 新增申请进入页面时,优先校验当前登录人本年度是否已经申请过,已申请则直接拦截新增。
|
||||
if (!this.bizId && res.data.hasCurrentYearApply && !this.$auth.hasRoleOr('BRANCH_UNION_CHAIRMAN')) {
|
||||
@@ -631,16 +635,25 @@ layout("/layouts/platform.html"){
|
||||
if (res.data.applyCount !== null && res.data.applyCount !== undefined && res.data.applyCount !== 0) {
|
||||
this.$set(this.formData, 'applyCount', res.data.applyCount)
|
||||
}
|
||||
} else {
|
||||
throw new Error(res.msg || '申请资格加载失败,请刷新页面重试')
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
await this.getIsCanPlay();
|
||||
if (this.bizId) {
|
||||
this.findOne(this.bizId)
|
||||
} else {
|
||||
this.modeChange("1")
|
||||
try {
|
||||
await this.getIsCanPlay();
|
||||
if (this.bizId) {
|
||||
await this.findOne(this.bizId)
|
||||
} else {
|
||||
this.modeChange("1")
|
||||
}
|
||||
} catch (error) {
|
||||
this.isShow = false
|
||||
this.blockMessage = error.message || '申请信息加载失败,请刷新页面重试'
|
||||
} finally {
|
||||
this.pageLoading = false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+10
-1
@@ -305,7 +305,16 @@ layout("/layouts/platform.html"){
|
||||
|
||||
async handleTaskAction(val) {
|
||||
try {
|
||||
const valid = await this.$refs.formRef.validate()
|
||||
let valid
|
||||
if (val === 2 || val === 6) {
|
||||
this.$refs.formRef.clearValidate(['level', 'money'])
|
||||
const results = await Promise.all(['tf_opinion', 'tf_sign'].map(prop => new Promise(resolve => {
|
||||
this.$refs.formRef.validateField(prop, error => resolve(!error))
|
||||
})))
|
||||
valid = results.every(result => result)
|
||||
} else {
|
||||
valid = await this.$refs.formRef.validate()
|
||||
}
|
||||
if (!valid) return
|
||||
} catch (error) {
|
||||
return
|
||||
|
||||
+301
@@ -0,0 +1,301 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style nonce="${cspNonce!}">
|
||||
<!--#include('recipients.css'){}#-->
|
||||
</style>
|
||||
<div id="app" class="special-condolence-apply" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<snaker-start slot="header" label="特殊慰问" define_key="TSWW"></snaker-start>
|
||||
<el-form size="small" :model="formData" ref="formRef" :rules="formRules" label-width="0" label-suffix=":"
|
||||
class="flow-task-form">
|
||||
<div class="special-condolence-section-title">申请人信息</div>
|
||||
<el-descriptions :column="2" border size="small">
|
||||
<el-descriptions-item label="申请人姓名">{{formData.applyUserName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请人工号">{{formData.applyLoginName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请人单位">{{formData.applyUnitName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请人工会">{{formData.applyUnionName}}</el-descriptions-item>
|
||||
|
||||
</el-descriptions>
|
||||
<!--#include('recipients.html'){}#-->
|
||||
<div class="special-condolence-section-title">申请说明与签字</div>
|
||||
<el-descriptions :column="3" border size="small">
|
||||
<el-descriptions-item label="申请事由" :span="3">
|
||||
<el-form-item prop="remark" label="申请事由">
|
||||
<el-input maxlength="500" v-model="formData.remark" placeholder="请填写申请事由"
|
||||
type="textarea" :rows="3" resize="none"></el-input>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :span="3" v-if="chooseType.isUploadFile === true">
|
||||
<template slot="label">
|
||||
附件
|
||||
<el-tooltip class="item" effect="dark" :content="'上传附件说明:' + chooseType.uploadFileDesc"
|
||||
placement="top-start"
|
||||
v-if="chooseType.isUploadFile && chooseType.uploadFileDesc">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<el-form-item prop="files" label="附件">
|
||||
<file-upload
|
||||
:value.sync="formData.files"
|
||||
:upload_number="5"
|
||||
upload_result_category="array"
|
||||
complete_result
|
||||
upload_mode="drag"
|
||||
></file-upload>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="签字" :span="3">
|
||||
<el-form-item prop="signature" label="签字">
|
||||
<pc-signature v-model="formData.signature"></pc-signature>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-form>
|
||||
<el-row type="flex" justify="end" class="special-condolence-actions">
|
||||
<el-button type="primary" plain @click="onSave">保存申请</el-button>
|
||||
<el-button type="primary" @click="onSubmit" v-if="!taskId">提交申请</el-button>
|
||||
<el-button type="primary" @click="onFinishTask" v-else>提交申请</el-button>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('recipients.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
mixins: [specialCondolenceRecipients],
|
||||
components: {
|
||||
ElDatePicker: {
|
||||
extends: ELEMENT.DatePicker,
|
||||
mounted() {
|
||||
// 手动输入触发 change 前初始化日期面板,避免 picker 尚未创建。
|
||||
if (!this.picker) this.mountPicker()
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
bizId: GetQueryString("bizId"),
|
||||
taskId: GetQueryString("taskId"),
|
||||
formData: { recipients: [] },
|
||||
formRules: {
|
||||
recipients: [{ validator: (rule, value, callback) => callback(value && value.length ? undefined : new Error("请添加慰问对象")), trigger: "change" }],
|
||||
helpUserId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
payUserId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
type: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
way: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
money: [
|
||||
{ required: true, message: "请填写慰问金额", trigger: ["change", "blur"] },
|
||||
{ validator: (rule, value, callback) => callback(this.validateMoney(value) ? undefined : new Error("慰问金额须大于0且不超过10000元,最多两位小数")), trigger: ["change", "blur"] }
|
||||
],
|
||||
occurTime: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
child: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
hospital: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
hospitalHouseNum: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
hospitalHouseBedNum: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
hospitalBy: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
deadImmediateFamily: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
remark: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
files: [{ required: true, type: "array", min: 1, max: 5, message: "请上传1至5个附件", trigger: ["change", "blur"] }],
|
||||
signature: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
handlerUserId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
// certifierUserId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
bankCardNumber: [
|
||||
{ required: true, message: "请填写银行卡号或对公账户号", trigger: ["change", "blur"] },
|
||||
{ pattern: /^[0-9]{6,30}$/, message: "收款账户须为6至30位数字(银行卡号或对公账户号)", trigger: ["change", "blur"] }
|
||||
],
|
||||
bankUserName: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
bankOfDeposit: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
thisYearHospitalizationNum: [
|
||||
{ required: true, message: "必填", trigger: ["change", "blur"] },
|
||||
{ type: "integer", min: 0, max: 10000, message: "住院次数须为0至10000的整数", trigger: ["change", "blur"] }
|
||||
],
|
||||
leaveHospitalTime: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
hospitalizationTime: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||
},
|
||||
chooseType: {},
|
||||
payUserOptions: [],
|
||||
helpUserOptions: [],
|
||||
typeOptions: [],
|
||||
|
||||
handlerUserOptions: [],
|
||||
certifierUserOptions: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
validateMoney(value) {
|
||||
return /^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$/.test(String(value)) && Number(value) > 0 && Number(value) <= 10000
|
||||
},
|
||||
createRemoteMethod(options) {
|
||||
return (keyword) => {
|
||||
this.selectQueryUser(keyword, options)
|
||||
}
|
||||
},
|
||||
selectQueryUser(keyword, options) {
|
||||
options.length = 0
|
||||
this.$axios.post("/platform/special_condolence/apply/listUser", { keyword: keyword }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
options.push(...res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
helpUserChange(val) {
|
||||
const user = this.helpUserOptions.find(o => o.id === val)
|
||||
if (user) {
|
||||
const { userName, loginName, unitId, unitName, unionId, unionName } = user
|
||||
this.$set(this.formData, "helpUserName", userName)
|
||||
this.$set(this.formData, "helpLoginName", loginName)
|
||||
this.$set(this.formData, "helpUnitId", unitId)
|
||||
this.$set(this.formData, "helpUnitName", unitName)
|
||||
this.$set(this.formData, "helpUnionId", unionId)
|
||||
this.$set(this.formData, "helpUnionName", unionName)
|
||||
}
|
||||
},
|
||||
handlerUserChange(val) {
|
||||
const user = this.handlerUserOptions.find(o => o.id === val)
|
||||
if (user) {
|
||||
const { userName, loginName, unitId, unitName, unionId, unionName } = user
|
||||
this.$set(this.formData, "handlerUserName", userName)
|
||||
this.$set(this.formData, "handlerLoginName", loginName)
|
||||
this.$set(this.formData, "handlerUnitId", unitId)
|
||||
this.$set(this.formData, "handlerUnitName", unitName)
|
||||
this.$set(this.formData, "handlerUnionId", unionId)
|
||||
this.$set(this.formData, "handlerUnionName", unionName)
|
||||
}
|
||||
},
|
||||
certifierUserChange(val) {
|
||||
const user = this.certifierUserOptions.find(o => o.id === val)
|
||||
if (user) {
|
||||
const { userName, loginName, unitId, unitName, unionId, unionName } = user
|
||||
this.$set(this.formData, "certifierUserName", userName)
|
||||
this.$set(this.formData, "certifierLoginName", loginName)
|
||||
this.$set(this.formData, "certifierUnitId", unitId)
|
||||
this.$set(this.formData, "certifierUnitName", unitName)
|
||||
this.$set(this.formData, "certifierUnionId", unionId)
|
||||
this.$set(this.formData, "certifierUnionName", unionName)
|
||||
}
|
||||
},
|
||||
payUserChange(val) {
|
||||
const user = this.payUserOptions.find(o => o.id === val)
|
||||
if (user) {
|
||||
const { userName, loginName } = user
|
||||
this.$set(this.formData, "payUserName", userName)
|
||||
this.$set(this.formData, "payLoginName", loginName)
|
||||
}
|
||||
},
|
||||
typeChange(id) {
|
||||
this.chooseType = this.typeOptions.find(o => o.id === id)
|
||||
if (this.chooseType) {
|
||||
this.$set(this.formData, "perMoney", this.chooseType.money)
|
||||
this.$set(this.formData, "way", this.chooseType.way)
|
||||
this.$set(this.formData, "typeCode", this.chooseType.code)
|
||||
}
|
||||
},
|
||||
onSave() {
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
if (!valid) return
|
||||
this.$confirm("您确定保存吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/apply/save", { data: JSON.stringify(this.formData) }).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
commonUtil.pjaxPush("/platform/special_condolence/mine")
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm("您确定要提交吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/apply/submit", {
|
||||
data: JSON.stringify(this.formData)
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
commonUtil.pjaxPush("/platform/special_condolence/mine")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
onFinishTask() {
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm("您确定要提交吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/apply/submitAgain", {
|
||||
data: JSON.stringify(this.formData),
|
||||
taskId: GetQueryString("taskId")
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
commonUtil.pjaxPush("/platform/special_condolence/mine")
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
init() {
|
||||
if (this.bizId) {
|
||||
this.$axios.post("/platform/special_condolence/mine/info", { id: this.bizId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.formData = res.data
|
||||
this.initRecipients()
|
||||
this.selectQueryUser(this.formData.helpLoginName, this.helpUserOptions)
|
||||
this.selectQueryUser(this.formData.certifierLoginName, this.certifierUserOptions)
|
||||
this.selectQueryUser(this.formData.handlerLoginName, this.handlerUserOptions)
|
||||
this.chooseType = this.typeOptions.find(o => o.id === this.formData.type)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const { username, loginname, id, unit, union, mobile } = this.$store.state.user
|
||||
this.formData = {
|
||||
recipients: [this.newRecipient()],
|
||||
perMoney: undefined,
|
||||
occurTime: this.$moment().format('YYYY-MM-DD'),
|
||||
applyUserName: username,
|
||||
applyLoginName: loginname,
|
||||
applyUserId: id,
|
||||
applyUnitId: unit?.id,
|
||||
applyUnitName: unit?.name,
|
||||
applyUnionId: union?.id,
|
||||
applyUnionName: union?.name
|
||||
}
|
||||
}
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post("/platform/special_condolence/type/querySpecialCondolenceType")
|
||||
.then((resp) => {
|
||||
this.typeOptions = resp.data
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.querySpecialCondolenceType()
|
||||
this.init()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
.special-condolence-apply .el-card__body { padding: 24px; }
|
||||
.special-condolence-apply .special-condolence-section-title { display: flex; align-items: center; gap: 10px; margin: 24px 0 14px; color: #303133; font-size: 15px; font-weight: 600; line-height: 24px; }
|
||||
.special-condolence-apply .el-descriptions__table { table-layout: fixed; }
|
||||
.special-condolence-apply .flow-task-form > .special-condolence-section-title:first-child { margin-top: 0; }
|
||||
.special-condolence-apply .el-descriptions { font-size: 14px; }
|
||||
.special-condolence-apply .el-descriptions .el-descriptions-item__cell { height: 50px; padding: 8px 12px; box-sizing: border-box; font-size: 14px; line-height: 32px; vertical-align: middle; }
|
||||
.special-condolence-apply .el-descriptions-item__label.is-bordered-label { width: 130px; min-width: 130px; max-width: 130px; font-weight: 400; }
|
||||
.special-condolence-apply .el-descriptions-item__content { font-weight: 400; }
|
||||
.special-condolence-apply .el-descriptions .el-form-item__content { line-height: 32px; }
|
||||
.special-condolence-apply .el-descriptions .el-input__inner { height: 32px; line-height: 32px; font-size: 14px; }
|
||||
.special-condolence-apply .el-descriptions .el-input__icon { line-height: 32px; }
|
||||
.special-condolence-apply .el-descriptions .el-textarea__inner { font-size: 14px; line-height: 22px; }
|
||||
|
||||
.special-condolence-apply .el-descriptions-item__label { width: 130px; color: #606266; background: #f7f9fc; }
|
||||
.special-condolence-apply .special-condolence-recipients { margin: 28px 0; border: 1px solid #e4e7ed; border-radius: 6px; overflow: hidden; }
|
||||
.special-condolence-apply .special-condolence-toolbar { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 14px; padding: 18px 20px; }
|
||||
.special-condolence-apply .special-condolence-toolbar .special-condolence-section-title { margin: 0 0 4px; }
|
||||
.special-condolence-hint { color: #606266; font-size: 12px; line-height: 20px; }
|
||||
.special-condolence-apply .special-condolence-toolbar-buttons { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||
.special-condolence-apply .special-condolence-toolbar-buttons .el-button { margin: 0; }
|
||||
.special-condolence-apply .special-condolence-table-item { margin: 0; }
|
||||
.special-condolence-apply .special-condolence-table-item > .el-form-item__content { line-height: normal; }
|
||||
.special-condolence-apply .special-condolence-table-item .el-form-item__error { position: static; padding: 8px 20px; }
|
||||
.special-condolence-apply .special-condolence-table-item .el-table th { background: #f5f7fa; color: #606266; font-weight: 600; }
|
||||
.special-condolence-apply .special-condolence-table-item .el-table .cell { padding: 0 8px; }
|
||||
.special-condolence-apply .special-condolence-table-item .el-select,
|
||||
.special-condolence-apply .special-condolence-table-item .el-input-number,
|
||||
.special-condolence-apply .special-condolence-table-item .el-date-editor { width: 100%; }
|
||||
.special-condolence-apply .special-condolence-table-item .el-input-number .el-input__inner { text-align: right; }
|
||||
.special-condolence-apply .special-condolence-delete { color: #d64040; }
|
||||
.special-condolence-apply .special-condolence-table-footer { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 10px; padding: 10px 20px; background: #fafbfd; }
|
||||
.special-condolence-apply .special-condolence-total { display: flex; align-items: baseline; gap: 6px; color: #606266; font-size: 13px; font-variant-numeric: tabular-nums; }
|
||||
.special-condolence-apply .special-condolence-total > span { margin-left: 18px; }
|
||||
.special-condolence-apply .special-condolence-total-amount { color: #303133; font-size: 20px; }
|
||||
.special-condolence-apply .special-condolence-actions { gap: 12px; margin-top: 24px; padding-top: 20px; border-top: 1px solid #ebeef5; }
|
||||
.special-condolence-apply .special-condolence-actions .el-button { margin: 0; min-width: 108px; }
|
||||
.special-condolence-dialog { max-width: calc(100vw - 32px); border-radius: 8px; }
|
||||
.special-condolence-dialog .el-dialog__header { padding: 22px 24px 16px; border-bottom: 1px solid #ebeef5; }
|
||||
.special-condolence-dialog .el-dialog__body { padding: 24px; }
|
||||
.special-condolence-dialog .el-dialog__footer { padding: 16px 24px; border-top: 1px solid #ebeef5; }
|
||||
.special-condolence-dialog .special-condolence-template { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; padding: 16px; border: 1px solid #dce6f3; border-radius: 6px; background: #f6f9fe; }
|
||||
.special-condolence-dialog .special-condolence-template > i { color: #409eff; font-size: 28px; }
|
||||
.special-condolence-dialog .special-condolence-template > div { flex: 1; min-width: 180px; }
|
||||
.special-condolence-dialog .special-condolence-template p { margin: 5px 0 0; color: #606266; font-size: 12px; line-height: 18px; }
|
||||
.special-condolence-dialog .special-condolence-upload-title { margin: 22px 0 12px; font-weight: 600; }
|
||||
.special-condolence-dialog .special-condolence-upload .el-upload,
|
||||
.special-condolence-dialog .special-condolence-upload .el-upload-dragger { width: 100%; }
|
||||
.special-condolence-dialog .special-condolence-upload .el-upload-dragger { height: auto; min-height: 150px; padding: 22px 12px; }
|
||||
.special-condolence-dialog .special-condolence-upload .el-icon-upload,
|
||||
.special-condolence-dialog .special-condolence-upload .el-icon-loading { display: block; margin: 0 0 16px; color: #909399; font-size: 44px; line-height: 48px; }
|
||||
.special-condolence-dialog .el-upload__tip { margin-bottom: 16px; line-height: 20px; }
|
||||
.special-condolence-dialog .special-condolence-batch-note { margin-bottom: 24px; padding: 12px 16px; background: #f5f7fa; border-radius: 4px; line-height: 22px; }
|
||||
.special-condolence-dialog .special-condolence-batch-form .el-select,
|
||||
.special-condolence-dialog .special-condolence-batch-form .el-input-number,
|
||||
.special-condolence-dialog .special-condolence-batch-form .el-date-editor { width: 100%; }
|
||||
@media (max-width: 768px) {
|
||||
.special-condolence-apply .el-card__body { padding: 16px; }
|
||||
.special-condolence-apply .special-condolence-toolbar { padding: 14px; }
|
||||
.special-condolence-apply .special-condolence-total > span { margin-left: 8px; }
|
||||
}
|
||||
|
||||
.special-condolence-apply .special-condolence-table-item .el-table .el-form-item { margin: 8px 0 20px; }
|
||||
.special-condolence-apply .special-condolence-table-item .el-table .el-form-item__error { position: absolute; padding: 4px 0 0; font-size: 11px; line-height: 14px; white-space: normal; }
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<div class="special-condolence-section-title">统一慰问配置</div>
|
||||
<el-descriptions :column="3" border size="small">
|
||||
<el-descriptions-item label="慰问类型">
|
||||
<el-form-item label="慰问类型" prop="type">
|
||||
<el-select v-model="formData.type" filterable @change="typeChange" style="width:100%" placeholder="请选择慰问类型">
|
||||
<el-option v-for="t in typeOptions" :key="t.id" :value="t.id" :label="t.name"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="慰问金额">
|
||||
<el-form-item label="慰问金额" prop="perMoney" :rules="recipientRules.money">
|
||||
<el-input-number v-model="formData.perMoney" :precision="2" :min="0" :max="10000" :controls="false" style="width:100%" placeholder="每人慰问金额(元)"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="慰问时间">
|
||||
<el-form-item label="慰问时间" prop="occurTime" :rules="recipientRules.occurTime">
|
||||
<el-date-picker v-model="formData.occurTime" type="date" value-format="yyyy-MM-dd" style="width:100%" placeholder="请选择慰问时间"></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<section class="special-condolence-recipients">
|
||||
<div class="special-condolence-toolbar">
|
||||
<div>
|
||||
<div class="special-condolence-section-title">慰问对象明细 <el-tag size="small" effect="plain">{{ recipientCount }} 人</el-tag></div>
|
||||
<div class="special-condolence-hint">一行填写一位慰问对象,所有人员随本申请统一审批。</div>
|
||||
</div>
|
||||
<div class="special-condolence-toolbar-buttons">
|
||||
<el-button size="small" icon="el-icon-upload2" @click="importVisible = true">Excel 导入</el-button>
|
||||
<el-button size="small" type="primary" icon="el-icon-plus" @click="formData.recipients.push(newRecipient())">新增慰问对象</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item prop="recipients" label-width="0" class="special-condolence-table-item">
|
||||
<el-table :data="formData.recipients" border stripe size="small" max-height="520" empty-text="暂无慰问对象,点击新增或从 Excel 导入">
|
||||
<el-table-column type="index" label="序号" width="55" align="center" fixed="left"></el-table-column>
|
||||
<el-table-column label="慰问对象" width="200" fixed="left"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.helpUserId'" :rules="recipientRules.helpUserId"><user-select size="small" :ref="'recipientUser' + s.$index" v-model="s.row.helpUserId" api="/platform/special_condolence/apply/listUser" api_input_key_name="keyword" :option_list="recipientOptions(s.row)" :option_label_func="item => item.userName + '(' + (item.loginName || '') + ')'" @hook:mounted="seedRecipientOptions(s.row, s.$index)" @change="id => recipientUserChange(s.row, s.$index, id)"></user-select></el-form-item></template></el-table-column>
|
||||
<el-table-column label="工号" min-width="150"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.helpLoginName'" :rules="[{ validator: (rule, value, cb) => cb(s.row.personType === '劳务派遣人员' || value ? undefined : new Error('普通人员工号不能为空')), trigger: 'change' }]"><el-input size="small" v-model="s.row.helpLoginName" readonly placeholder="选人后带出,劳务派遣可空"></el-input></el-form-item></template></el-table-column>
|
||||
<el-table-column label="身份证号码" min-width="205"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.idCard'" :rules="recipientRules.idCard"><el-input size="small" v-model="s.row.idCard" maxlength="18" placeholder="请输入18位身份证号"></el-input></el-form-item></template></el-table-column>
|
||||
<el-table-column label="开户行" min-width="190"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.bankOfDeposit'" :rules="recipientRules.bankOfDeposit"><el-input size="small" v-model="s.row.bankOfDeposit" maxlength="100" placeholder="请输入开户银行及支行"></el-input></el-form-item></template></el-table-column>
|
||||
<el-table-column label="户名" min-width="140"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.bankUserName'" :rules="recipientRules.bankUserName"><el-input size="small" v-model="s.row.bankUserName" maxlength="100" placeholder="请输入账户户名"></el-input></el-form-item></template></el-table-column>
|
||||
<el-table-column label="收款账户" min-width="215"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.bankCardNumber'" :rules="recipientRules.bankCardNumber"><el-input size="small" v-model="s.row.bankCardNumber" maxlength="30" placeholder="银行卡号或对公账户号"></el-input></el-form-item></template></el-table-column>
|
||||
<el-table-column label="操作" fixed="right" width="75" align="center"><template slot-scope="s"><el-button size="small" type="text" class="special-condolence-delete" @click="formData.recipients.splice(s.$index, 1)">删除</el-button></template></el-table-column>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
<div class="special-condolence-table-footer">
|
||||
<el-button type="text" icon="el-icon-plus" @click="formData.recipients.push(newRecipient())">继续添加一行</el-button>
|
||||
<div class="special-condolence-total">共 <strong>{{ recipientCount }}</strong> 人<span>慰问金额合计</span><strong class="special-condolence-total-amount">¥ {{ recipientTotal }}</strong></div>
|
||||
</div>
|
||||
</section>
|
||||
<el-dialog title="Excel 导入慰问对象" :visible.sync="importVisible" width="560px" custom-class="special-condolence-dialog" :close-on-click-modal="!importLoading" :close-on-press-escape="!importLoading" :show-close="!importLoading" append-to-body>
|
||||
<div class="special-condolence-template">
|
||||
<i class="el-icon-document"></i>
|
||||
<div><strong>第一步:下载并填写模板</strong><p>按模板表头填写,一行对应一位慰问对象。</p></div>
|
||||
<el-button size="small" type="primary" plain icon="el-icon-download" @click="$downLoad('/platform/special_condolence/apply/importTemplate')">下载模板</el-button>
|
||||
</div>
|
||||
<div class="special-condolence-upload-title">第二步:上传填写好的文件</div>
|
||||
<el-upload class="special-condolence-upload" drag action="" accept=".xlsx,.xls" :http-request="importRecipients" :show-file-list="false" :disabled="importLoading">
|
||||
<i :class="importLoading ? 'el-icon-loading' : 'el-icon-upload'"></i>
|
||||
<div class="el-upload__text">{{ importLoading ? '正在导入,请稍候…' : '将 Excel 文件拖到此处,或点击选择文件' }}</div>
|
||||
<div slot="tip" class="el-upload__tip">支持 .xlsx、.xls 格式,单次最多 1000 行。导入的数据将追加到当前表格。</div>
|
||||
</el-upload>
|
||||
<el-alert title="工号、身份证号码和收款账户请保持文本格式。普通人员须填写正确工号;劳务派遣人员免校验工号,均须属于申请人本工会。" type="info" :closable="false" show-icon></el-alert>
|
||||
<span slot="footer"><el-button :disabled="importLoading" @click="importVisible = false">关闭</el-button></span>
|
||||
</el-dialog>
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
const specialCondolenceRecipients = {
|
||||
data() {
|
||||
return { recipientRules: this.createRecipientRules(), importVisible: false, importLoading: false }
|
||||
},
|
||||
computed: {
|
||||
recipientCount() {
|
||||
return (this.formData.recipients || []).length
|
||||
},
|
||||
recipientTotal() {
|
||||
const money = Number(this.formData.perMoney)
|
||||
const cents = (Number.isFinite(money) && money > 0 ? Math.round(money * 100) : 0) * this.recipientCount
|
||||
return (cents / 100).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
typeOptions() { this.chooseType = this.typeOptions.find(t => t.id === this.formData.type) || {} },
|
||||
'formData.type'(value) { this.chooseType = this.typeOptions.find(t => t.id === value) || {} }
|
||||
},
|
||||
methods: {
|
||||
createRecipientRules() {
|
||||
const required = label => ({ required: true, whitespace: true, message: '请填写' + label, trigger: ['blur', 'change'] })
|
||||
return {
|
||||
helpUserId: [{ required: true, message: '请选择慰问对象', trigger: 'change' }],
|
||||
type: [{ required: true, message: '请选择慰问类型', trigger: 'change' }],
|
||||
idCard: [required('身份证号码'), { validator: (rule, value, cb) => cb(this.validRecipientIdCard(value) ? undefined : new Error('身份证号码不正确')), trigger: ['blur', 'change'] }],
|
||||
bankOfDeposit: [required('开户行'), { max: 100, message: '开户行最多100字', trigger: 'blur' }],
|
||||
bankUserName: [required('户名'), { max: 100, message: '户名最多100字', trigger: 'blur' }],
|
||||
bankCardNumber: [required('收款账户'), { pattern: /^[0-9]{6,30}$/, message: '请输入6至30位数字账户', trigger: ['blur', 'change'] }],
|
||||
money: [{ validator: (rule, value, cb) => cb(/^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$/.test(String(value)) && Number(value) > 0 && Number(value) <= 10000 ? undefined : new Error('金额须大于0且不超过10000元,最多两位小数')), trigger: ['blur', 'change'] }],
|
||||
occurTime: [{ validator: (rule, value, cb) => cb(this.$moment(value, 'YYYY-MM-DD', true).isValid() ? undefined : new Error('请选择有效慰问时间')), trigger: ['blur', 'change'] }]
|
||||
}
|
||||
},
|
||||
validRecipientIdCard(value) {
|
||||
const card = String(value || '').toUpperCase()
|
||||
if (!/^[1-9][0-9]{16}[0-9X]$/.test(card) || !this.$moment(card.substring(6, 14), 'YYYYMMDD', true).isValid()) return false
|
||||
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
|
||||
return '10X98765432'[weights.reduce((sum, weight, index) => sum + weight * Number(card[index]), 0) % 11] === card[17]
|
||||
},
|
||||
recipientOptions(row) {
|
||||
return row.helpUserId ? [{ id: row.helpUserId, userName: row.helpUserName, loginName: row.helpLoginName }] : []
|
||||
},
|
||||
seedRecipientOptions(row, index) {
|
||||
const component = this.$refs['recipientUser' + index]
|
||||
if (component && row.helpUserId) component.options = this.recipientOptions(row)
|
||||
},
|
||||
recipientUserChange(row, index, id) {
|
||||
const component = this.$refs['recipientUser' + index]
|
||||
const user = component && component.options.find(item => item.id === id)
|
||||
this.$set(row, 'helpUserId', user ? user.id : '')
|
||||
this.$set(row, 'helpUserName', user ? user.userName : '')
|
||||
this.$set(row, 'helpLoginName', user ? user.loginName : '')
|
||||
this.$set(row, 'personType', user ? user.personType : '')
|
||||
this.$set(row, 'idCard', user ? user.idCard || '' : '')
|
||||
this.$set(row, 'bankOfDeposit', user ? user.bankOfDeposit || '' : '')
|
||||
this.$set(row, 'bankUserName', user ? user.bankUserName || user.userName : '')
|
||||
this.$set(row, 'bankCardNumber', user ? user.bankCardNumber || '' : '')
|
||||
this.$nextTick(() => this.$refs.formRef.validateField('recipients.' + index + '.helpUserId'))
|
||||
},
|
||||
|
||||
newRecipient() {
|
||||
return { helpUserId: '', helpLoginName: '', personType: '', helpUserName: '', idCard: '', bankOfDeposit: '', bankUserName: '', bankCardNumber: '' }
|
||||
},
|
||||
initRecipients() {
|
||||
if (this.formData.perMoney == null && this.formData.recipients && this.formData.recipients.length) this.$set(this.formData, 'perMoney', Number(this.formData.recipients[0].money))
|
||||
if (!this.formData.recipients || !this.formData.recipients.length) {
|
||||
this.$set(this.formData, 'recipients', this.formData.helpUserName ? [Object.assign(this.newRecipient(), this.formData, { recipients: undefined })] : [this.newRecipient()])
|
||||
}
|
||||
},
|
||||
async importRecipients(request) {
|
||||
this.importLoading = true
|
||||
try {
|
||||
const data = new FormData()
|
||||
data.append('file', request.file)
|
||||
const result = await this.$axios.post('/platform/special_condolence/apply/importRecipients', data)
|
||||
if (result.code === 0) {
|
||||
const rows = this.formData.recipients.filter(r => r.helpUserName || r.type || r.idCard || r.bankCardNumber || r.bankUserName || r.bankOfDeposit || r.money)
|
||||
this.$set(this.formData, 'recipients', rows.concat(result.data))
|
||||
this.importVisible = false
|
||||
this.$message.success('导入成功,共' + result.data.length + '人')
|
||||
} else this.$message.error(result.msg || '导入失败')
|
||||
} catch (error) {
|
||||
this.$message.error('导入失败,请检查文件内容后重试')
|
||||
} finally {
|
||||
this.importLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
const specialcondolenceInfo = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<div class="process-title">
|
||||
申请信息
|
||||
<el-link type="primary" @click="openChart">点击查看流程图</el-link>
|
||||
</div>
|
||||
<el-descriptions :column="3" border>
|
||||
<el-descriptions-item label="申请人姓名">{{ viewData.applyUserName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请人工号">{{ viewData.applyLoginName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请人单位">{{ viewData.applyUnitName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="申请人工会">{{ viewData.applyUnionName }}</el-descriptions-item>
|
||||
<template v-if="viewData.recipients && viewData.recipients.length">
|
||||
<el-descriptions-item label="慰问类型">{{ viewData.typeName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="每人慰问金额">{{ viewData.perMoney }} 元</el-descriptions-item>
|
||||
<el-descriptions-item label="慰问时间">{{ viewData.occurTime }}</el-descriptions-item>
|
||||
</template>
|
||||
<template v-if="!viewData.recipients || !viewData.recipients.length">
|
||||
<el-descriptions-item label="慰问对象">{{ viewData.helpUserName }}</el-descriptions-item>
|
||||
<!-- <el-descriptions-item label="经办人">{{ viewData.handlerUserName }}</el-descriptions-item>-->
|
||||
<el-descriptions-item label="证明人">{{ viewData.certifierUserName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="慰问类型">{{ viewData.typeName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="慰问金额">{{ viewData.money }}</el-descriptions-item>
|
||||
<el-descriptions-item label="慰问时间">{{ viewData.occurTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="收款账户">{{ viewData.bankCardNumber }}</el-descriptions-item>
|
||||
<el-descriptions-item label="户名">{{ viewData.bankUserName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开户行">{{ viewData.bankOfDeposit }}</el-descriptions-item>
|
||||
<template v-if="['2'].includes(viewData.typeCode)">
|
||||
<el-descriptions-item label="入院时间">{{ viewData.hospitalizationTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="出院时间">{{ viewData.leaveHospitalTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="当年第几次住院">{{ viewData.thisYearHospitalizationNum }}
|
||||
</el-descriptions-item>
|
||||
</template>
|
||||
</template>
|
||||
<el-descriptions-item label="申请事由" :span="3">
|
||||
<div style="white-space: pre-line">{{ viewData.remark }}</div>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="附件" :span="3">
|
||||
<file-preview v-if="viewData.files && viewData.files.length > 0" :files="viewData.files"
|
||||
complete_result></file-preview>
|
||||
<span v-else>暂无附件</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="签字" :span="3">
|
||||
<el-image :src="viewData.signature"
|
||||
v-if="viewData.signature"
|
||||
class="signature-image"></el-image>
|
||||
<span v-else>暂无签字</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<div v-if="viewData.recipients && viewData.recipients.length" class="process-title" style="display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-top:20px">
|
||||
<span>慰问对象明细 <el-tag size="small" effect="plain">{{ viewData.recipients.length }} 人</el-tag></span>
|
||||
<span style="font-size:14px;font-weight:normal">慰问金额合计:<strong>¥ {{ detailTotal }}</strong></span>
|
||||
</div>
|
||||
<el-table v-if="viewData.recipients && viewData.recipients.length" :data="viewData.recipients" border stripe size="small" max-height="480" class="mt10" :header-cell-style="{ background: '#f5f7fa', color: '#606266' }">
|
||||
<el-table-column type="index" label="序号" width="55" align="center" fixed="left"></el-table-column>
|
||||
<el-table-column prop="helpUserName" label="慰问对象" width="130" fixed="left"></el-table-column>
|
||||
<el-table-column prop="helpLoginName" label="工号" min-width="130"></el-table-column>
|
||||
<el-table-column prop="idCard" label="身份证号码" min-width="190"></el-table-column>
|
||||
<el-table-column prop="bankOfDeposit" label="开户行" min-width="180" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column prop="bankUserName" label="户名" min-width="150"></el-table-column>
|
||||
<el-table-column prop="bankCardNumber" label="收款账户" min-width="210"></el-table-column>
|
||||
</el-table>
|
||||
<template v-for="task in doneTasks">
|
||||
<div class="mt10">
|
||||
<div class="process-title">{{ task.displayName }}</div>
|
||||
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
|
||||
v-if="task.ext.isFirstTaskNode">
|
||||
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
|
||||
}}({{task.ext.initiatorAccount}})
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="办理结果">
|
||||
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"></dict-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
|
||||
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName
|
||||
}}({{task.taskFormData.loginName}})
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
|
||||
<el-descriptions-item label="办理结果">
|
||||
<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>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
</template>
|
||||
<slot></slot>
|
||||
<snaker-chart ref="snakerChartRef"></snaker-chart>
|
||||
</div>
|
||||
`,
|
||||
store,
|
||||
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailTotal() {
|
||||
const cents = (this.viewData.recipients || []).reduce((sum, row) => {
|
||||
const money = Number(row.money)
|
||||
return sum + (Number.isFinite(money) ? Math.round(money * 100) : 0)
|
||||
}, 0)
|
||||
return (cents / 100).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
this.row = row
|
||||
this.visible = true
|
||||
this.getInfo()
|
||||
this.getDoneTasks()
|
||||
},
|
||||
getInfo() {
|
||||
this.$axios.post('/platform/special_condolence/mine/info', {id: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 获取已办任务审批记录
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doneTasks = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
// 查看流程图
|
||||
openChart(){
|
||||
this.$refs.snakerChartRef.onOpenFull(this.row.instanceProcessDefineId, this.row.instanceId)
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.el-descriptions-item__label {
|
||||
width: 200px;
|
||||
min-width: 200px;
|
||||
max-width: 200px;
|
||||
}
|
||||
.el-tabs__header {
|
||||
margin: 0;
|
||||
}
|
||||
`
|
||||
}
|
||||
+229
@@ -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>
|
||||
<specialcondolence-info ref="specialcondolenceInfoRef">
|
||||
<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>
|
||||
</specialcondolence-info>
|
||||
</template>
|
||||
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"specialcondolence-info": specialcondolenceInfo
|
||||
},
|
||||
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.specialcondolenceInfoRef.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.specialcondolenceInfoRef.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/special_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()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType')
|
||||
.then((resp) => {
|
||||
this.typeOptions = resp.data
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.unitList = await this.$businessTool.listUnit()
|
||||
this.querySpecialCondolenceType()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+170
@@ -0,0 +1,170 @@
|
||||
<!--#
|
||||
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>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never">
|
||||
<table-tool label="申请列表">
|
||||
<el-button type="primary" size="small" @click="onAdd">
|
||||
<i class="ti-plus"></i>
|
||||
新增申请
|
||||
</el-button>
|
||||
</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="300">
|
||||
<template slot-scope="{row}">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
|
||||
<el-button v-if="row.canRevoke" size="mini" type="danger" @click="onRevoke(row)">撤回</el-button>
|
||||
<el-dropdown v-if="row.createdBy === $store.state.user.id && row.instanceState == 20" trigger="click" @command="format => doExportApply(row, format)">
|
||||
<el-button size="mini" type="primary">导出</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="pdf">导出 PDF</el-dropdown-item>
|
||||
<el-dropdown-item command="word">导出 Word</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
<el-button v-if="row.taskKey === 'startTask' || !row.instanceId" @click="onDelete(row.id)" size="mini" type="danger">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #view>
|
||||
<specialcondolence-info ref="specialcondolenceInfoRef"></specialcondolence-info>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"specialcondolence-info": specialcondolenceInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeOptions: [],
|
||||
tableColumns: [
|
||||
{prop: 'helpUserName', label: '慰问对象'},
|
||||
{prop: 'helpLoginName', label: '慰问对象工号'},
|
||||
{prop: 'applyUserName', label: '申请人'},
|
||||
{prop: 'applyUnionName', label: '所属工会'},
|
||||
{prop: 'applyUnitName', label: '所属单位'},
|
||||
{prop: 'typeName', label: '慰问类型'},
|
||||
{prop: 'taskName', label: '当前节点'},
|
||||
{prop: 'instanceState', label: '流程状态'},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doExportApply(row, format) {
|
||||
this.$downLoad('/platform/special_condolence/mine/doExportApply?id=' + row.id + '&print=' + (format === 'pdf'))
|
||||
},
|
||||
onAdd() {
|
||||
commonUtil.pjaxPush('/platform/special_condolence/apply')
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.guava.view(()=>{
|
||||
this.$refs.specialcondolenceInfoRef.onOpen(row)
|
||||
})
|
||||
},
|
||||
onEdit(row) {
|
||||
commonUtil.pjaxPush('/platform/special_condolence/apply?taskId=' + (row.startTaskId || '') + "&bizId=" + row.id)
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$confirm("您确定要撤回吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onDelete(id) {
|
||||
this.$confirm("您确定要删除吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/mine/delete", { id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType')
|
||||
.then((resp) => {
|
||||
this.typeOptions = resp.data
|
||||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.querySpecialCondolenceType()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
<!--#
|
||||
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-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出</el-button>
|
||||
</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="180">
|
||||
<template slot-scope="{row}">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')" @click="onDelete(row.id)" size="mini" type="danger">
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #edit>
|
||||
<specialcondolence-info ref="specialcondolenceInfoRef"></specialcondolence-info>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"specialcondolence-info": specialcondolenceInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
typeOptions: [],
|
||||
tableColumns: [
|
||||
{prop: 'helpUserName', label: '慰问对象'},
|
||||
{prop: 'helpLoginName', label: '慰问对象工号'},
|
||||
{prop: 'applyUserName', label: '申请人'},
|
||||
{prop: 'applyUnionName', label: '所属工会'},
|
||||
{prop: 'applyUnitName', label: '所属单位'},
|
||||
{prop: 'typeName', label: '慰问类型'},
|
||||
{prop: 'taskName', label: '当前节点'},
|
||||
{prop: 'instanceState', label: '流程状态'},
|
||||
],
|
||||
unionList: [],
|
||||
unitList: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onDelete(id) {
|
||||
this.$confirm("您确定要删除吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/mine/delete", { id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onExport() {
|
||||
this.$downLoad(loc() + '/onExport', this.pageForm)
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.guava.edit(()=>{
|
||||
this.$refs.specialcondolenceInfoRef.onOpen(row)
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType')
|
||||
.then((resp) => {
|
||||
this.typeOptions = resp.data
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.unitList = await this.$businessTool.listUnit()
|
||||
this.querySpecialCondolenceType()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+229
@@ -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>
|
||||
<specialcondolence-info ref="specialcondolenceInfoRef">
|
||||
<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>
|
||||
</specialcondolence-info>
|
||||
</template>
|
||||
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"specialcondolence-info": specialcondolenceInfo
|
||||
},
|
||||
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.specialcondolenceInfoRef.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.specialcondolenceInfoRef.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/special_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()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType')
|
||||
.then((resp) => {
|
||||
this.typeOptions = resp.data
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.unitList = await this.$businessTool.listUnit()
|
||||
this.querySpecialCondolenceType()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+229
@@ -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>
|
||||
<specialcondolence-info ref="specialcondolenceInfoRef">
|
||||
<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>
|
||||
</specialcondolence-info>
|
||||
</template>
|
||||
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"specialcondolence-info": specialcondolenceInfo
|
||||
},
|
||||
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.specialcondolenceInfoRef.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.specialcondolenceInfoRef.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/special_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()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType')
|
||||
.then((resp) => {
|
||||
this.typeOptions = resp.data
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.unitList = await this.$businessTool.listUnit()
|
||||
this.querySpecialCondolenceType()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
const basicForm = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="110px" label-position="left">
|
||||
<el-form-item label="类型编码" prop="code">
|
||||
<el-input type="text" v-model="formData.code" maxlength="50"
|
||||
placeholder="请填写类型编码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型名称" prop="name">
|
||||
<el-input type="text" v-model="formData.name" maxlength="50"
|
||||
placeholder="请填写类型名称"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="慰问费用" prop="money">
|
||||
<el-input-number style="width: 100%" v-model="formData.money"
|
||||
placeholder="请填写慰问费用" controls-position="right" :controls="false"
|
||||
precision="2"
|
||||
:min="0"
|
||||
:max="10000"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item label="慰问方式" prop="way">
|
||||
<el-radio-group v-model="formData.way">
|
||||
<el-radio-button label="慰问金 (A)" border>慰问金 (A)</el-radio-button>
|
||||
<el-radio-button label="提货券 (B)" border>提货券 (B)</el-radio-button>
|
||||
<el-radio-button label="慰问品 (C)" border>慰问品 (C)</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否启用" prop="enable">
|
||||
<el-switch
|
||||
v-model="formData.enable"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
<!--<el-form-item label="上传会议纪要" prop="uploadMeetingRecord">
|
||||
<el-radio-group v-model="formData.uploadMeetingRecord">
|
||||
<el-radio-button :label="true">上传</el-radio-button>
|
||||
<el-radio-button :label="false">不上传</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>-->
|
||||
<el-form-item label="是否上传附件" prop="isUploadFile">
|
||||
<el-radio-group v-model="formData.isUploadFile">
|
||||
<el-radio-button :label="true">是</el-radio-button>
|
||||
<el-radio-button :label="false">否</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="上传附件说明" prop="uploadFileDesc" v-if="formData.isUploadFile">
|
||||
<el-input v-model="formData.uploadFileDesc" maxlength="50" clearable placeholder="请填写上传附件说明"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row class="mt10" justify="end" type="flex">
|
||||
<el-button @click="$emit('refresh')">取消</el-button>
|
||||
<el-button @click="onSubmit" type="primary">提交</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
formData: { isUploadFile: false },
|
||||
formRules: {
|
||||
name: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
money: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
way: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
code: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
isUploadFile: [{required: true, message: '必填', trigger: ['blur', 'change']}],
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(row) {
|
||||
if(row && row.id) {
|
||||
this.formData = clone(row)
|
||||
} else {
|
||||
this.formData = { isUploadFile: false }
|
||||
}
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm("您确定要提交吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(async () => {
|
||||
const resp = await this.$axios.post("/platform/special_condolence/type/onSubmit", this.formData)
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.$emit('refresh')
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.el-input-number .el-input__inner {
|
||||
text-align: left;
|
||||
}
|
||||
`
|
||||
}
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="名称/编码">
|
||||
<el-input placeholder="请输入名称或编码" clearable v-model="pageForm.searchKeyword"
|
||||
@keyup.enter.native="doSearch">
|
||||
</el-input>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt20">
|
||||
<table-tool label="类型列表">
|
||||
<el-button type="primary" size="small" @click="onAdd">
|
||||
<i class="ti-plus"></i>
|
||||
新增类型
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize">
|
||||
<el-table-column label="序号" type="index" :index="indexMethod" width="60"></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 === 'isUploadFile'">
|
||||
<span v-if="row.isUploadFile" class="text-success">是</span>
|
||||
<span v-else class="text-danger">否</span>
|
||||
</template>
|
||||
<template v-slot="{ row }" v-else-if="column.prop === 'enable'">
|
||||
<el-switch
|
||||
@change="switchChange(row)"
|
||||
v-model="row.enable"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949">
|
||||
</el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="230">
|
||||
<template v-slot="{ row }">
|
||||
<el-button @click="onEdit(row)" size="mini" type="primary">编辑</el-button>
|
||||
<el-button @click="onDelete(row)" size="mini" type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<template #edit>
|
||||
<basic-form ref="basicFormRef" @refresh="refresh"></basic-form>
|
||||
</template>
|
||||
|
||||
</guava>
|
||||
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('basicForm.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"basic-form": basicForm,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableColumns: [
|
||||
{prop: 'code', label: '类型编码'},
|
||||
{prop: 'name', label: '类型名称'},
|
||||
{prop: 'money', label: '金额'},
|
||||
{prop: 'way', label: '慰问方式'},
|
||||
// {prop: 'isUploadFile', label: '是否上传附件'},
|
||||
{prop: 'enable', label: '是否启用'},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refresh() {
|
||||
this.doSearch()
|
||||
this.$refs.guava.index()
|
||||
},
|
||||
onAdd() {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.basicFormRef.onOpen()
|
||||
})
|
||||
},
|
||||
onEdit(row) {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.basicFormRef.onOpen(row)
|
||||
})
|
||||
},
|
||||
onDelete(row) {
|
||||
this.$confirm("您确定要删除吗, 是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/special_condolence/type/onDelete", { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
switchChange(row) {
|
||||
this.$axios.post("/platform/special_condolence/type/onSubmit", row).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.post(loc() + "/pageData", this.pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data.list
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+513
@@ -0,0 +1,513 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style scoped>
|
||||
#app {
|
||||
--color-primary: #1989fa;
|
||||
}
|
||||
|
||||
#app > .van-nav-bar .van-icon,
|
||||
#app > .van-nav-bar .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
#app > .van-nav-bar .van-nav-bar__title,
|
||||
#app > .van-nav-bar .van-nav-bar__text,
|
||||
#app > .van-nav-bar .van-nav-bar__arrow {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.search-dialog {
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
/* 慰问申请页复用提案撰写页的 Card 层级,仅覆盖当前表单分组和底部操作栏。 */
|
||||
.specialcondolence-apply-form.form-container {
|
||||
min-height: 100%;
|
||||
padding: 12px 15px calc(84px + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fc;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, 0.08);
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .specialcondolence-card__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
font-weight: 600;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .specialcondolence-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.specialcondolence-card__desc {
|
||||
padding: 0 14px 8px 21px;
|
||||
color: orangered;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section .van-cell:not(:last-child)::after {
|
||||
right: 14px;
|
||||
left: 14px;
|
||||
border-color: #eef2f7;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section .van-field__label {
|
||||
width: 84px;
|
||||
color: #596779;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section .van-field__value,
|
||||
.specialcondolence-apply-form .form-section .van-field__control {
|
||||
color: #4f5d70;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section .van-field__control::placeholder {
|
||||
color: #b1bac6;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-form .form-section .van-cell--required::before {
|
||||
left: 6px;
|
||||
color: #f06464;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-actions {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: flex;
|
||||
gap: 9px;
|
||||
padding: 10px 18px calc(10px + env(safe-area-inset-bottom));
|
||||
border-top: 1px solid #edf1f6;
|
||||
background: rgba(255, 255, 255, 0.98);
|
||||
box-shadow: 0 -4px 14px rgba(50, 78, 112, 0.06);
|
||||
}
|
||||
|
||||
.specialcondolence-apply-actions .van-button {
|
||||
height: 40px;
|
||||
margin: 0;
|
||||
border-radius: 14px !important;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-actions .van-button:first-child {
|
||||
flex: 1;
|
||||
color: #1989fa;
|
||||
border-color: #1989fa;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.specialcondolence-apply-actions .van-button:last-child {
|
||||
flex: 1.08;
|
||||
border-color: #1989fa;
|
||||
background: #1989fa;
|
||||
}
|
||||
|
||||
#app .van-action-sheet__header,
|
||||
#app .van-picker__title,
|
||||
.van-dialog__header {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
#app .van-action-sheet__name,
|
||||
#app .van-action-sheet__cancel,
|
||||
#app .van-empty__description,
|
||||
#app .van-search__field,
|
||||
#app .van-picker__cancel,
|
||||
#app .van-picker__confirm,
|
||||
.van-dialog__message {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#app .van-picker-column__item {
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<!-- 导航栏 -->
|
||||
<van-nav-bar title="特殊慰问申请" left-text="返回" left-arrow @click-left="historyBack" fixed
|
||||
placeholder></van-nav-bar>
|
||||
|
||||
<!-- 表单容器 -->
|
||||
<van-form ref="formRef" class="form-container specialcondolence-apply-form">
|
||||
|
||||
<!-- 基本信息 -->
|
||||
<section class="form-section">
|
||||
<h2 class="specialcondolence-card__title">基本信息</h2>
|
||||
<van-cell-group :border="false">
|
||||
<van-field label="申请人姓名" :rules="[{ required: true }]" v-model="formData.applyUserName" readonly
|
||||
required name="applyUserName"></van-field>
|
||||
<van-field label="申请人工号" :rules="[{ required: true }]" v-model="formData.applyLoginName" readonly
|
||||
required name="applyLoginName"></van-field>
|
||||
<van-field label="申请人单位" :rules="[{ required: true }]" v-model="formData.applyUnitName" readonly
|
||||
required name="applyUnitName"></van-field>
|
||||
<van-field label="申请人工会" :rules="[{ required: true }]" v-model="formData.applyUnionName" readonly
|
||||
required name="applyUnionName"></van-field>
|
||||
|
||||
<van-field label="慰问类型" required><template #input><select v-model="formData.type" @change="typeChange(formData.type)"><option value="">请选择</option><option v-for="t in typeOptions" :key="t.id" :value="t.id">{{t.name}}</option></select></template></van-field>
|
||||
<van-field v-model="formData.perMoney" label="每人金额" type="number" required :rules="[{ validator: validateMoney, message: '金额须大于0且不超过10000元,最多两位小数' }]"></van-field>
|
||||
<van-field v-model="formData.occurTime" label="慰问时间" placeholder="yyyy-MM-dd" required :rules="[{required:true}]"></van-field>
|
||||
<div v-for="(person, index) in formData.recipients" :key="index">
|
||||
<van-cell :title="'慰问对象 ' + (index + 1)"><van-button native-type="button" size="mini" @click="formData.recipients.splice(index, 1)">删除</van-button></van-cell>
|
||||
<van-field v-model="person.helpUserName" label="慰问对象" required :rules="[{required:true}]"></van-field>
|
||||
<van-field v-model="person.helpLoginName" label="工号" placeholder="普通人员必填,劳务派遣可空"></van-field>
|
||||
<van-field v-model="person.idCard" label="身份证号码" maxlength="18" required :rules="[{required:true}]"></van-field>
|
||||
<van-field v-model="person.bankOfDeposit" label="开户行" maxlength="100" required :rules="[{required:true}]"></van-field>
|
||||
<van-field v-model="person.bankUserName" label="户名" maxlength="100" required :rules="[{required:true}]"></van-field>
|
||||
<van-field v-model="person.bankCardNumber" label="收款账户" maxlength="30" required :rules="[{required:true}]"></van-field>
|
||||
</div>
|
||||
<van-button native-type="button" @click="formData.recipients.push(newRecipient())">增加一行</van-button>
|
||||
<van-field
|
||||
v-model="formData.remark"
|
||||
name="remark"
|
||||
maxlength="500"
|
||||
label="申请事由"
|
||||
type="textarea"
|
||||
rows="4"
|
||||
autosize
|
||||
placeholder="请输入申请事由"
|
||||
:rules="[{ required: true }]"
|
||||
required
|
||||
></van-field>
|
||||
</van-cell-group>
|
||||
</section>
|
||||
|
||||
<section class="form-section" v-if="chooseType.isUploadFile === true">
|
||||
<h2 class="specialcondolence-card__title">附件材料</h2>
|
||||
<div v-if="chooseType.isUploadFile && chooseType.uploadFileDesc" class="specialcondolence-card__desc">
|
||||
{{ '附件说明:' + chooseType.uploadFileDesc }}
|
||||
</div>
|
||||
<van-cell-group :border="false">
|
||||
<van-field class="direction-column-field" name="files" label="附件" required
|
||||
:rules="[{ validator: () => Array.isArray(formData.files) && formData.files.length > 0 && formData.files.length <= 5, message: '请上传1至5个附件' }]">
|
||||
<template #input>
|
||||
<h5-file-upload
|
||||
slot="input"
|
||||
:value.sync="formData.files"
|
||||
:upload_number="5"
|
||||
upload_text="上传附件"
|
||||
upload_result_category="array"
|
||||
complete_result
|
||||
></h5-file-upload>
|
||||
<div class="specialcondolence-card__desc">最多上传 5 个文件</div>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
</section>
|
||||
|
||||
<section class="form-section">
|
||||
<h2 class="specialcondolence-card__title">签字确认</h2>
|
||||
<van-cell-group :border="false">
|
||||
<van-field class="direction-column-field" name="signature" label="" :value="formData.signature"
|
||||
:rules="[{ required: true, message: '请填写签字' }]">
|
||||
<template #input>
|
||||
<h5-signature v-model="formData.signature" slot="input"></h5-signature>
|
||||
</template>
|
||||
</van-field>
|
||||
</van-cell-group>
|
||||
</section>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<div class="form-actions specialcondolence-apply-actions">
|
||||
<van-button native-type="button" @click="onSave" round type="info" plain>保存申请</van-button>
|
||||
<van-button @click="onSubmit" round type="info" v-if="!taskId">提交申请</van-button>
|
||||
<van-button @click="onFinishTask" round type="info" v-else>提交申请</van-button>
|
||||
</div>
|
||||
</van-form>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include("/platform/zhgh/staffbenefit/specialcondolence/apply/recipients.js"){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
mixins: [specialCondolenceRecipients],
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
bizId: GetQueryString("bizId"),
|
||||
taskId: GetQueryString("taskId"),
|
||||
formData: { recipients: [] },
|
||||
|
||||
chooseType: {},
|
||||
userOptions: [],
|
||||
typeOptions: [],
|
||||
|
||||
helpUserSelectShow: false,
|
||||
payUserSelectShow: false,
|
||||
showTypePicker: false,
|
||||
typeColumns: [],
|
||||
searchKeyword: "",
|
||||
|
||||
showTimePicker: false,
|
||||
showChildPicker: false,
|
||||
showFamilyPicker: false,
|
||||
|
||||
certifierUserSelectShow: false,
|
||||
handlerUserSelectShow: false,
|
||||
|
||||
showHospitalizationTimePicker: false,
|
||||
showLeaveHospitalTimePicker: false,
|
||||
minDate: new Date(2024, 0, 1),
|
||||
maxDate: new Date(),
|
||||
|
||||
typeDefaultIndex: 0
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
validateMoney(value) {
|
||||
return /^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$/.test(String(value)) && Number(value) > 0 && Number(value) <= 10000
|
||||
},
|
||||
// 选择出院时间
|
||||
showLeaveHospitalTimePickerClick() {
|
||||
if (this.formData.leaveHospitalTime) {
|
||||
this.formData.leaveHospitalDate = new Date(this.formData.leaveHospitalTime)
|
||||
}
|
||||
this.showLeaveHospitalTimePicker = true
|
||||
},
|
||||
// 选择住院时间
|
||||
showHospitalizationTimePickerClick() {
|
||||
if (this.formData.hospitalizationTime) {
|
||||
this.formData.hospitalizationDate = new Date(this.formData.hospitalizationTime)
|
||||
}
|
||||
this.showHospitalizationTimePicker = true
|
||||
},
|
||||
// 选择慰问时间
|
||||
showTimePickerClick() {
|
||||
if (this.formData.occurTime) {
|
||||
this.formData.occurDate = new Date(this.formData.occurTime)
|
||||
}else{
|
||||
this.formData.occurDate = new Date()
|
||||
}
|
||||
this.showTimePicker = true
|
||||
},
|
||||
// 选择慰问类型
|
||||
showTypePickerClick() {
|
||||
if (this.formData.type) {
|
||||
this.typeDefaultIndex = this.typeOptions.findIndex(item => item.id === this.formData.type)
|
||||
}
|
||||
this.showTypePicker = true
|
||||
},
|
||||
//经办人
|
||||
handlerUserChange(user) {
|
||||
const { id, userName, loginName, unitId, unitName, unionId, unionName } = user
|
||||
this.$set(this.formData, "handlerUserId", id)
|
||||
this.$set(this.formData, "handlerUserName", userName)
|
||||
this.$set(this.formData, "handlerLoginName", loginName)
|
||||
this.$set(this.formData, "handlerUnitId", unitId)
|
||||
this.$set(this.formData, "handlerUnitName", unitName)
|
||||
this.$set(this.formData, "handlerUnionId", unionId)
|
||||
this.$set(this.formData, "handlerUnionName", unionName)
|
||||
this.handlerUserSelectShow = false
|
||||
this.searchKeyword = ""
|
||||
this.userOptions = []
|
||||
},
|
||||
//证明人
|
||||
certifierUserChange(user) {
|
||||
const { id, userName, loginName, unitId, unitName, unionId, unionName } = user
|
||||
this.$set(this.formData, "certifierUserId", id)
|
||||
this.$set(this.formData, "certifierUserName", userName)
|
||||
this.$set(this.formData, "certifierLoginName", loginName)
|
||||
this.$set(this.formData, "certifierUnitId", unitId)
|
||||
this.$set(this.formData, "certifierUnitName", unitName)
|
||||
this.$set(this.formData, "certifierUnionId", unionId)
|
||||
this.$set(this.formData, "certifierUnionName", unionName)
|
||||
this.certifierUserSelectShow = false
|
||||
this.searchKeyword = ""
|
||||
this.userOptions = []
|
||||
},
|
||||
async userRemoteMethod(event, type) {
|
||||
if (event) {
|
||||
this.userOptions = await this.selectQueryUser(event)
|
||||
if (type === "help") {
|
||||
this.helpUserSelectShow = true
|
||||
} else if (type === "certifier") {
|
||||
this.certifierUserSelectShow = true
|
||||
} else if (type === "handler") {
|
||||
this.handlerUserSelectShow = true
|
||||
}
|
||||
}
|
||||
},
|
||||
async selectQueryUser(keyword) {
|
||||
const res = await this.$axios.post("/platform/special_condolence/apply/listUser", { keyword: keyword })
|
||||
return res.data
|
||||
},
|
||||
helpUserChange(user) {
|
||||
const { id, userName, loginName, unitId, unitName, unionId, unionName } = user
|
||||
this.$set(this.formData, "helpUserId", id)
|
||||
this.$set(this.formData, "helpUserName", userName)
|
||||
this.$set(this.formData, "helpLoginName", loginName)
|
||||
this.$set(this.formData, "helpUnitId", unitId)
|
||||
this.$set(this.formData, "helpUnitName", unitName)
|
||||
this.$set(this.formData, "helpUnionId", unionId)
|
||||
this.$set(this.formData, "helpUnionName", unionName)
|
||||
this.helpUserSelectShow = false
|
||||
this.searchKeyword = ""
|
||||
this.userOptions = []
|
||||
},
|
||||
payUserChange(user) {
|
||||
const { id, userName, loginName } = user
|
||||
this.$set(this.formData, "payUserId", id)
|
||||
this.$set(this.formData, "payUserName", userName)
|
||||
this.$set(this.formData, "payLoginName", loginName)
|
||||
this.payUserSelectShow = false
|
||||
this.searchKeyword = ""
|
||||
this.userOptions = []
|
||||
},
|
||||
typeChange(id) {
|
||||
this.chooseType = this.typeOptions.find(o => o.id === id)
|
||||
if (this.chooseType) {
|
||||
this.$set(this.formData, "perMoney", this.chooseType.money)
|
||||
this.$set(this.formData, "way", this.chooseType.way)
|
||||
this.$set(this.formData, "typeCode", this.chooseType.code)
|
||||
}
|
||||
},
|
||||
onTypeConfirm(o) {
|
||||
this.$set(this.formData, "typeName", o.text)
|
||||
this.$set(this.formData, "type", o.value)
|
||||
this.typeChange(o.value)
|
||||
this.showTypePicker = false
|
||||
},
|
||||
onSave() {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定保存吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/apply/save", { data: JSON.stringify(this.formData) }).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.$pjaxReplace("/platform/special_condolence/mine/h5")
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async onSubmit() {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
if (!this.formData.signature){
|
||||
this.$toast.fail("请填写签字")
|
||||
return
|
||||
}
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交申请吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/apply/submit", { data: JSON.stringify(this.formData) }).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.$pjaxReplace("/platform/special_condolence/mine/h5")
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
async onFinishTask() {
|
||||
this.$refs.formRef.validate().then(() => {
|
||||
if (!this.formData.signature){
|
||||
this.$toast.fail("请填写签字")
|
||||
return
|
||||
}
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要提交申请吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/special_condolence/apply/submitAgain", {
|
||||
data: JSON.stringify(this.formData),
|
||||
taskId: GetQueryString("taskId")
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.$pjaxReplace("/platform/special_condolence/mine/h5")
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
init() {
|
||||
if (this.bizId) {
|
||||
this.$axios.post("/platform/special_condolence/mine/info", { id: this.bizId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.formData = res.data
|
||||
this.initRecipients()
|
||||
this.selectQueryUser(this.formData.helpLoginName, this.helpUserOptions)
|
||||
this.selectQueryUser(this.formData.payLoginName, this.payUserOptions)
|
||||
this.chooseType = this.typeOptions.find(o => o.id === this.formData.type)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const { username, loginname, id, unit, union, mobile } = this.$store.state.user
|
||||
this.formData = {
|
||||
recipients: [this.newRecipient()],
|
||||
perMoney: undefined,
|
||||
occurTime: this.$moment().format('YYYY-MM-DD'),
|
||||
applyUserName: username,
|
||||
applyLoginName: loginname,
|
||||
applyUserId: id,
|
||||
applyUnitId: unit?.id,
|
||||
applyUnitName: unit?.name,
|
||||
applyUnionId: union?.id,
|
||||
applyUnionName: union?.name
|
||||
}
|
||||
}
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post("/platform/special_condolence/type/querySpecialCondolenceType")
|
||||
.then((res) => {
|
||||
this.typeOptions = JSON.parse(JSON.stringify(res.data))
|
||||
res.data.forEach((v) => {
|
||||
this.typeColumns.push({ value: v.id, text: v.name })
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.querySpecialCondolenceType()
|
||||
this.init()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
.specialcondolence-full-popup {
|
||||
--color-primary: #1989fa;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background: #f3f7fc;
|
||||
}
|
||||
|
||||
.specialcondolence-full-popup__page {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
padding-top: 46px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.specialcondolence-full-popup__page > .van-nav-bar {
|
||||
z-index: 20;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.specialcondolence-full-popup__page > .van-nav-bar .van-icon,
|
||||
.specialcondolence-full-popup__page > .van-nav-bar .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.specialcondolence-full-popup__scroll {
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
flex: 1;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.specialcondolence-info-main {
|
||||
padding: 12px 15px calc(18px + env(safe-area-inset-bottom));
|
||||
}
|
||||
|
||||
.specialcondolence-info-card {
|
||||
margin-bottom: 11px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #e9eff7;
|
||||
border-radius: 10px;
|
||||
background: #fff;
|
||||
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
|
||||
}
|
||||
|
||||
.specialcondolence-info-card__title {
|
||||
position: relative;
|
||||
margin: 0;
|
||||
padding: 12px 14px 8px 21px;
|
||||
color: #354255;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card__title::before {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
bottom: 11px;
|
||||
left: 12px;
|
||||
width: 2px;
|
||||
border-radius: 2px;
|
||||
background: #1989fa;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* 审核意见复用详情 Card 标题,并与提案 delegation 审核输入区保持一致。 */
|
||||
.specialcondolence-audit-card__required {
|
||||
margin-left: 4px;
|
||||
color: #ee0a24;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-field.specialcondolence-audit-field {
|
||||
width: calc(100% - 28px);
|
||||
margin: 0 14px 14px;
|
||||
padding: 12px;
|
||||
box-sizing: border-box;
|
||||
border: 1px solid #c9d5e5;
|
||||
border-radius: 10px;
|
||||
background: #f7f9fd;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-field.specialcondolence-audit-field .van-field__control {
|
||||
min-height: 150px;
|
||||
color: #253247;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-field.specialcondolence-audit-field .van-field__control::placeholder {
|
||||
color: #9aa7b8;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-field.specialcondolence-audit-field .van-field__word-limit {
|
||||
color: #718096;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-field.specialcondolence-audit-field::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.specialcondolence-popup-actions {
|
||||
display: flex;
|
||||
padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
|
||||
justify-content: space-between;
|
||||
column-gap: 10px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.specialcondolence-popup-actions .van-button {
|
||||
border-radius: 14px;
|
||||
}
|
||||
|
||||
.specialcondolence-popup-actions .specialcondolence-action-primary {
|
||||
border-color: #1989fa;
|
||||
background: #1989fa;
|
||||
}
|
||||
|
||||
.specialcondolence-popup-actions .specialcondolence-action-danger {
|
||||
border-color: #ff4d4f;
|
||||
background: #ff4d4f;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-cell-group {
|
||||
margin: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-cell {
|
||||
min-height: 44px;
|
||||
padding: 10px 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-cell:not(:last-child)::after {
|
||||
right: 14px;
|
||||
left: 14px;
|
||||
border-color: #eef2f7;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-cell__title {
|
||||
width: 102px;
|
||||
color: #596779;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
flex: 0 0 102px;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .van-cell__value {
|
||||
min-width: 0;
|
||||
color: #4f5d70;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
text-align: left;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.specialcondolence-info-long-cell {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .specialcondolence-attachments .empty-container {
|
||||
height: auto;
|
||||
justify-content: flex-start;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.specialcondolence-info-card .specialcondolence-attachments .empty-text {
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.specialcondolence-info-opinion > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.specialcondolence-info-opinion > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.specialcondolence-signature-image,
|
||||
.specialcondolence-approval-signature-image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.specialcondolence-signature-image .van-image__img,
|
||||
.specialcondolence-approval-signature-image {
|
||||
object-fit: contain;
|
||||
object-position: left center;
|
||||
}
|
||||
|
||||
.specialcondolence-info-opinion img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
const specialcondolenceInfo = {
|
||||
template: /*language=HTML*/ `
|
||||
<van-popup
|
||||
v-model="visible"
|
||||
position="right"
|
||||
class="specialcondolence-full-popup"
|
||||
:close-on-click-overlay="false"
|
||||
get-container="#app"
|
||||
>
|
||||
<div class="specialcondolence-full-popup__page">
|
||||
<van-nav-bar
|
||||
:title="popupTitle"
|
||||
left-arrow
|
||||
left-text="返回"
|
||||
fixed
|
||||
@click-left="onClose()"
|
||||
></van-nav-bar>
|
||||
<div class="specialcondolence-full-popup__scroll">
|
||||
<main class="specialcondolence-info-main">
|
||||
<section class="specialcondolence-info-card">
|
||||
<h2 class="specialcondolence-info-card__title">基本信息</h2>
|
||||
<van-cell-group :border="false">
|
||||
<van-cell title="申请人姓名">{{ viewData.applyUserName || '--' }}</van-cell>
|
||||
<van-cell title="申请人工号">{{ viewData.applyLoginName || '--' }}</van-cell>
|
||||
<van-cell title="申请人单位">{{ viewData.applyUnitName || '--' }}</van-cell>
|
||||
<van-cell title="申请人工会">{{ viewData.applyUnionName || '--' }}</van-cell>
|
||||
<template v-if="viewData.recipients && viewData.recipients.length">
|
||||
<van-cell title="慰问类型" :value="viewData.typeName"></van-cell>
|
||||
<van-cell title="每人慰问金额" :value="viewData.perMoney"></van-cell>
|
||||
<van-cell title="慰问时间" :value="viewData.occurTime"></van-cell>
|
||||
</template>
|
||||
<template v-for="(person, index) in viewData.recipients">
|
||||
<van-cell :title="'慰问对象 ' + (index + 1)" :value="person.helpUserName"></van-cell>
|
||||
<van-cell title="工号" :value="person.helpLoginName || '--'"></van-cell>
|
||||
<van-cell title="身份证号码" :value="person.idCard"></van-cell>
|
||||
<van-cell title="开户行" :value="person.bankOfDeposit"></van-cell>
|
||||
<van-cell title="户名" :value="person.bankUserName"></van-cell>
|
||||
<van-cell title="收款账户" :value="person.bankCardNumber"></van-cell>
|
||||
</template>
|
||||
<template v-if="!viewData.recipients || !viewData.recipients.length">
|
||||
<van-cell title="慰问对象">{{ viewData.helpUserName || '--' }}</van-cell>
|
||||
<!-- <van-cell title="证明人">{{ viewData.certifierUserName || '--' }}</van-cell> -->
|
||||
<van-cell title="慰问类型">{{ viewData.typeName || '--' }}</van-cell>
|
||||
<van-cell title="慰问金额">{{ viewData.money || '--' }}</van-cell>
|
||||
<van-cell title="慰问时间">{{ viewData.occurTime || '--' }}</van-cell>
|
||||
<van-cell title="收款账户">{{ viewData.bankCardNumber || '--' }}</van-cell>
|
||||
<van-cell title="户名">{{ viewData.bankUserName || '--' }}</van-cell>
|
||||
<van-cell title="开户行">
|
||||
{{ viewData.bankOfDeposit || '暂无' }}
|
||||
</van-cell>
|
||||
<template v-if="['2'].includes(viewData.typeCode)">
|
||||
<van-cell title="入院时间">{{ viewData.hospitalizationTime || '--' }}</van-cell>
|
||||
<van-cell title="出院时间">{{ viewData.leaveHospitalTime || '--' }}</van-cell>
|
||||
<van-cell title="当年第几次住院(次)">{{ viewData.thisYearHospitalizationNum || '--' }}</van-cell>
|
||||
</template>
|
||||
<van-cell title="申请事由">
|
||||
{{ viewData.remark || '暂无' }}
|
||||
</van-cell>
|
||||
</template>
|
||||
<van-cell class="specialcondolence-info-long-cell" title="附件">
|
||||
<file-preview class="specialcondolence-attachments" :files="viewData.files" complete_result></file-preview>
|
||||
</van-cell>
|
||||
<van-cell class="specialcondolence-info-long-cell" title="签字">
|
||||
<van-image
|
||||
v-if="viewData.signature"
|
||||
:src="viewData.signature"
|
||||
class="specialcondolence-signature-image"
|
||||
fit="contain"
|
||||
></van-image>
|
||||
<span v-else>暂无签字</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</section>
|
||||
|
||||
<section
|
||||
v-for="(task, index) in doneTasks"
|
||||
:key="task.id || index"
|
||||
class="specialcondolence-info-card"
|
||||
>
|
||||
<h2 class="specialcondolence-info-card__title">{{ task.displayName || '办理记录' }}</h2>
|
||||
<van-cell-group :border="false" v-if="task.ext && task.ext.isFirstTaskNode">
|
||||
<van-cell title="申请用户">
|
||||
{{ task.ext.initiatorName || '--' }}({{ task.ext.initiatorAccount || '--' }})
|
||||
</van-cell>
|
||||
<van-cell title="申请时间">{{ task.finishTime || '--' }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag
|
||||
:options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
:value="task.ext.submitType"
|
||||
></dict-tag>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell-group :border="false" v-else>
|
||||
<van-cell title="办理用户">
|
||||
{{ task.taskFormData && task.taskFormData.userName || '--' }}({{ task.taskFormData && task.taskFormData.loginName || '--' }})
|
||||
</van-cell>
|
||||
<van-cell title="办理时间">{{ task.finishTime || '--' }}</van-cell>
|
||||
<van-cell title="办理结果">
|
||||
<dict-tag
|
||||
:options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
|
||||
: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" class="specialcondolence-approval-signature-image">
|
||||
</van-cell>
|
||||
<van-cell title="办理意见">
|
||||
<div class="specialcondolence-info-opinion" v-html="task.taskFormData && task.taskFormData.tf_opinion || '暂无'"></div>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</section>
|
||||
|
||||
<slot></slot>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
`,
|
||||
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
|
||||
props: {
|
||||
pageKey: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
popupTitle: "慰问详情",
|
||||
viewData: {},
|
||||
doneTasks: [],
|
||||
row: null,
|
||||
historyLayerUnsubscribe: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 浏览器历史变化时,只同步当前慰问详情弹框的显示状态。
|
||||
syncHistoryLayerStack(stack) {
|
||||
this.$set(this, "visible", stack.includes("specialcondolence-detail"))
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开慰问详情或审核弹框。
|
||||
* row 传列表当前行,title 传顶部导航标题;无返回值。
|
||||
*/
|
||||
onOpen(row, title = "慰问详情") {
|
||||
this.$set(this, "row", row)
|
||||
this.$set(this, "popupTitle", title)
|
||||
this.$set(this, "viewData", {})
|
||||
this.$set(this, "doneTasks", [])
|
||||
this.getInfo()
|
||||
this.getDoneTasks()
|
||||
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("specialcondolence-detail")) return
|
||||
this.$set(this, "visible", true)
|
||||
},
|
||||
|
||||
// 顶部返回按钮与业务主动关闭统一回退弹框对应的浏览器历史。
|
||||
onClose(afterClose = null) {
|
||||
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.close("specialcondolence-detail", afterClose)) return
|
||||
this.$set(this, "visible", false)
|
||||
if (typeof afterClose === "function") afterClose()
|
||||
},
|
||||
|
||||
getInfo() {
|
||||
this.$axios.post("/platform/special_condolence/mine/info", {id: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, "viewData", res.data || {})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getDoneTasks() {
|
||||
this.$axios.post("/flow/common/doneTasks", {bizId: this.row.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, "doneTasks", res.data || [])
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (!window.h5HistoryLayerManager) return
|
||||
window.h5HistoryLayerManager.ensureRegistered(this.pageKey)
|
||||
this.$set(this, "historyLayerUnsubscribe", window.h5HistoryLayerManager.subscribe((stack) => {
|
||||
this.syncHistoryLayerStack(stack)
|
||||
}))
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (typeof this.historyLayerUnsubscribe === "function") this.historyLayerUnsubscribe()
|
||||
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.pageKey === this.pageKey) {
|
||||
window.h5HistoryLayerManager.unregister(this.pageKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
+367
@@ -0,0 +1,367 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
#app { --color-primary: #1989fa; }
|
||||
.specialcondolence-list-page { min-height: 100vh; padding-bottom: calc(24px + env(safe-area-inset-bottom)); box-sizing: border-box; background: #f3f7fd; }
|
||||
.specialcondolence-list-page .van-nav-bar, .specialcondolence-list-page .van-sticky--fixed { background: #fff; }
|
||||
.specialcondolence-list-page .van-nav-bar__title { color: #172033; font-size: 16px; font-weight: 600; }
|
||||
.specialcondolence-list-page .van-nav-bar .van-icon, .specialcondolence-list-page .van-nav-bar__text { color: #1989fa; }
|
||||
.specialcondolence-list-sticky { padding: 22px 12px 1px; box-sizing: border-box; background: #f3f7fd; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-search .van-search__content { height: 42px; padding-left: 12px; align-items: center; border-radius: 12px; background: #fff; }
|
||||
.specialcondolence-list-search .van-field__control { color: #263548; font-size: 14px; }
|
||||
.specialcondolence-list-search .van-field__control::placeholder { color: #a7b0bf; }
|
||||
.specialcondolence-list-filter { margin-bottom: 8px; overflow: hidden; border-radius: 10px; box-shadow: 0 5px 16px rgba(43, 73, 112, .08); }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__bar { height: 44px; box-shadow: none; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item, .specialcondolence-list-filter .van-dropdown-menu__title { height: 44px; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item { align-items: center; justify-content: center; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title { display: inline-flex; align-items: center; line-height: 20px; color: #66758a; font-size: 14px; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title--active, .specialcondolence-list-filter .van-dropdown-item__option--active, .specialcondolence-list-filter .van-dropdown-item__option--active .van-dropdown-item__icon { color: #1989fa; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-filter .van-dropdown-item__option { display: flex; min-height: 48px; padding: 0 16px; align-items: center; color: #46566c; font-size: 14px; }
|
||||
.specialcondolence-list-filter .van-dropdown-item__option .van-cell__title { display: flex; min-height: 20px; align-items: center; line-height: 20px; }
|
||||
.specialcondolence-list-content { padding: 0 12px; }
|
||||
.specialcondolence-list-skeleton { padding-top: 2px; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton { padding: 0; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__title { width: 42%; height: 18px; margin-bottom: 18px; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row { height: 14px; margin-top: 12px; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:nth-child(2n) { width: 72% !important; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:last-child { width: 34% !important; margin-top: 18px; margin-left: auto; }
|
||||
.specialcondolence-list-page .table-list-container { margin-top: 0; padding-bottom: 2px; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-card-header { display: flex; margin-bottom: 8px; align-items: flex-start; justify-content: space-between; }
|
||||
.specialcondolence-card-heading { min-width: 0; padding-right: 10px; flex: 1; }
|
||||
.specialcondolence-card-title { overflow: hidden; color: #253247; font-size: 15px; font-weight: 600; line-height: 22px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.specialcondolence-card-code { margin-top: 1px; color: #9ba6b6; font-size: 12px; line-height: 18px; }
|
||||
.specialcondolence-card-status { display: inline-flex; flex: none; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .item-actions { margin-top: 10px; padding-top: 10px; border-top-color: #edf1f6; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn.delete { color: #f04444; background: #fff0f0; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn i { margin-right: 5px; font-size: 13px; }
|
||||
.specialcondolence-list-page .empty-state { padding: 0; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-empty img { display: block; width: 86%; max-width: 290px; height: auto; object-fit: contain; }
|
||||
.specialcondolence-list-empty__title { margin-top: 14px; color: #50627a; font-size: 15px; font-weight: 600; line-height: 22px; }
|
||||
.specialcondolence-list-empty__hint { margin-top: 5px; color: #9aa7b8; font-size: 12px; line-height: 18px; }
|
||||
</style>
|
||||
|
||||
<style id="style-specialcondolence-info-h5">
|
||||
<!--#include("../common/info.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<div class="specialcondolence-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="specialcondolence-list-sticky">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
class="specialcondolence-list-search"
|
||||
placeholder="请输入姓名或者工号搜索"
|
||||
shape="round"
|
||||
clearable
|
||||
@search="doSearch"
|
||||
@clear="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu class="specialcondolence-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="specialcondolence-list-content">
|
||||
<div class="specialcondolence-list-skeleton" v-if="skeletonLoading">
|
||||
<div class="specialcondolence-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/special_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="specialcondolence-card-header">
|
||||
<div class="specialcondolence-card-heading">
|
||||
<div class="specialcondolence-card-title">{{row.helpUserName || '--'}}</div>
|
||||
<div class="specialcondolence-card-code">工号:{{row.helpLoginName || '--'}}</div>
|
||||
</div>
|
||||
<enum-tag class="specialcondolence-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="specialcondolence-list-empty">
|
||||
<img src="/assets/mobile/img/condolence/condolence-empty.png" alt="暂无慰问审核记录插画">
|
||||
<div class="specialcondolence-list-empty__title">暂无慰问审核记录</div>
|
||||
<div class="specialcondolence-list-empty__hint">当前筛选条件下暂时没有慰问申请</div>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
</main>
|
||||
|
||||
<info ref="infoRef" page-key="specialcondolence-fourth-detail">
|
||||
<div v-if="showApprovalForm">
|
||||
<section class="specialcondolence-info-card">
|
||||
<h2 class="specialcondolence-info-card__title">
|
||||
审批意见<span class="specialcondolence-audit-card__required">*</span>
|
||||
</h2>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
class="specialcondolence-audit-field"
|
||||
name="tf_opinion"
|
||||
type="textarea"
|
||||
rows="6"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
<h2 class="specialcondolence-info-card__title">
|
||||
审批签字<span class="specialcondolence-audit-card__required">*</span>
|
||||
</h2>
|
||||
<van-field name="tf_sign" :value="formData.tf_sign" :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="specialcondolence-popup-actions">
|
||||
<van-button class="specialcondolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button class="specialcondolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(2)">不同意</van-button>
|
||||
<van-button class="specialcondolence-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: specialcondolenceInfo
|
||||
},
|
||||
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.querySpecialCondolenceType()
|
||||
this.openTodoTask()
|
||||
},
|
||||
openTodoTask() {
|
||||
const taskId = GetQueryString("taskId")
|
||||
const bizId = GetQueryString("bizId")
|
||||
if (!taskId || !bizId) return
|
||||
this.$axios.post("/flow/common/taskInfo", {taskId}).then((res) => {
|
||||
if (res.code !== 0 || !res.data) return
|
||||
const task = res.data
|
||||
if (task.taskName !== "af363a4e-fc56-42a0-9906-8c7a2814006b") return
|
||||
const row = {id: bizId, taskId: task.id, curTaskName: task.displayName}
|
||||
if (task.taskState === 10 && task.executable && GetQueryString("tab") === "todo") {
|
||||
this.onApproval(row)
|
||||
} else {
|
||||
this.onView(row)
|
||||
}
|
||||
})
|
||||
},
|
||||
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("specialcondolence-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/special_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("specialcondolence-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("specialcondolence-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)
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType', {}, {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("specialcondolence-action-confirm"))
|
||||
}))
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (typeof this.historyLayerUnsubscribe === "function") this.historyLayerUnsubscribe()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+475
@@ -0,0 +1,475 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
#app {
|
||||
--color-primary: #1989fa;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: calc(24px + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fd;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .van-nav-bar,
|
||||
.specialcondolence-list-page .van-sticky--fixed {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .van-nav-bar__title {
|
||||
color: #172033;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .van-nav-bar .van-icon,
|
||||
.specialcondolence-list-page .van-nav-bar__text {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.specialcondolence-list-sticky {
|
||||
padding: 22px 12px 1px;
|
||||
box-sizing: border-box;
|
||||
background: #f3f7fd;
|
||||
}
|
||||
|
||||
.specialcondolence-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);
|
||||
}
|
||||
|
||||
.specialcondolence-list-search .van-search__content {
|
||||
height: 42px;
|
||||
padding-left: 12px;
|
||||
align-items: center;
|
||||
border-radius: 12px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.specialcondolence-list-search .van-field__control {
|
||||
color: #263548;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-search .van-field__control::placeholder {
|
||||
color: #a7b0bf;
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter {
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 5px 16px rgba(43, 73, 112, .08);
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter .van-dropdown-menu__bar {
|
||||
height: 44px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item,
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title {
|
||||
height: 44px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
line-height: 20px;
|
||||
color: #66758a;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title--active,
|
||||
.specialcondolence-list-filter .van-dropdown-item__option--active,
|
||||
.specialcondolence-list-filter .van-dropdown-item__option--active .van-dropdown-item__icon {
|
||||
color: #1989fa;
|
||||
}
|
||||
|
||||
.specialcondolence-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);
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter .van-dropdown-item__option {
|
||||
display: flex;
|
||||
min-height: 48px;
|
||||
padding: 0 16px;
|
||||
align-items: center;
|
||||
color: #46566c;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-filter .van-dropdown-item__option .van-cell__title {
|
||||
display: flex;
|
||||
min-height: 20px;
|
||||
align-items: center;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-content {
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-skeleton {
|
||||
padding-top: 2px;
|
||||
}
|
||||
|
||||
.specialcondolence-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);
|
||||
}
|
||||
|
||||
.specialcondolence-list-skeleton__card .van-skeleton {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__title {
|
||||
width: 42%;
|
||||
height: 18px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row {
|
||||
height: 14px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:nth-child(2n) {
|
||||
width: 72% !important;
|
||||
}
|
||||
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:last-child {
|
||||
width: 34% !important;
|
||||
margin-top: 18px;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .table-list-container {
|
||||
margin-top: 0;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.specialcondolence-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);
|
||||
}
|
||||
|
||||
.specialcondolence-card-header {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.specialcondolence-card-heading {
|
||||
min-width: 0;
|
||||
padding-right: 10px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.specialcondolence-card-title {
|
||||
overflow: hidden;
|
||||
color: #253247;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.specialcondolence-card-code {
|
||||
margin-top: 1px;
|
||||
color: #9ba6b6;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.specialcondolence-card-status {
|
||||
display: inline-flex;
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.specialcondolence-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;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .item-actions {
|
||||
margin-top: 10px;
|
||||
padding-top: 10px;
|
||||
border-top-color: #edf1f6;
|
||||
}
|
||||
|
||||
.specialcondolence-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;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn.delete {
|
||||
color: #f04444;
|
||||
background: #fff0f0;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn i {
|
||||
margin-right: 5px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-page .empty-state {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.specialcondolence-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;
|
||||
}
|
||||
|
||||
.specialcondolence-list-empty img {
|
||||
display: block;
|
||||
width: 86%;
|
||||
max-width: 290px;
|
||||
height: auto;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.specialcondolence-list-empty__title {
|
||||
margin-top: 14px;
|
||||
color: #50627a;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.specialcondolence-list-empty__hint {
|
||||
margin-top: 5px;
|
||||
color: #9aa7b8;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style id="style-specialcondolence-info-h5">
|
||||
<!--#include("../common/info.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<div class="specialcondolence-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="specialcondolence-list-sticky">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
class="specialcondolence-list-search"
|
||||
placeholder="请输入姓名或者工号搜索"
|
||||
shape="round"
|
||||
clearable
|
||||
@search="doSearch"
|
||||
@clear="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu class="specialcondolence-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-menu>
|
||||
</div>
|
||||
</van-sticky>
|
||||
|
||||
<main class="specialcondolence-list-content">
|
||||
<div class="specialcondolence-list-skeleton" v-if="skeletonLoading">
|
||||
<div class="specialcondolence-list-skeleton__card" v-for="index in 3" :key="'mine-skeleton-' + index">
|
||||
<van-skeleton title :row="5" animated></van-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<table-list api="/platform/special_condolence/mine/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="specialcondolence-card-header">
|
||||
<div class="specialcondolence-card-heading">
|
||||
<div class="specialcondolence-card-title">{{row.helpUserName || '--'}}</div>
|
||||
<div class="specialcondolence-card-code">工号:{{row.helpLoginName || '--'}}</div>
|
||||
</div>
|
||||
<enum-tag class="specialcondolence-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.taskName}}</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" @click="onEdit(row)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<van-icon name="edit"></van-icon>
|
||||
<span>编辑</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onRevoke(row)"
|
||||
v-if="row.canRevoke">
|
||||
<van-icon name="revoke"></van-icon>
|
||||
<span>撤回</span>
|
||||
</div>
|
||||
<div class="action-btn delete" @click="onDelete(row)"
|
||||
v-if="row.taskKey === 'startTask' || !row.instanceId">
|
||||
<van-icon name="delete-o"></van-icon>
|
||||
<span>删除</span>
|
||||
</div>
|
||||
</template>
|
||||
<template #empty>
|
||||
<div class="specialcondolence-list-empty">
|
||||
<img src="/assets/mobile/img/condolence/condolence-empty.png" alt="暂无慰问申请记录插画">
|
||||
<div class="specialcondolence-list-empty__title">暂无慰问申请记录</div>
|
||||
<div class="specialcondolence-list-empty__hint">当前筛选条件下暂时没有慰问申请</div>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
</main>
|
||||
|
||||
<info ref="infoRef" page-key="specialcondolence-mine-detail"></info>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
<!--#include('../common/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
components: {
|
||||
info: specialcondolenceInfo
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
year: new Date().getFullYear(),
|
||||
type: null
|
||||
},
|
||||
typeOptions: [],
|
||||
skeletonLoading: true,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// state.initial 表示当前查询前列表为空,仅此阶段使用整组卡片骨架屏。
|
||||
handleListLoadingChange(state) {
|
||||
if (state.initial) this.$set(this, "skeletonLoading", state.loading)
|
||||
},
|
||||
onReady() {
|
||||
this.querySpecialCondolenceType()
|
||||
.then((typeList) => {
|
||||
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()
|
||||
}
|
||||
})
|
||||
},
|
||||
onRevoke(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要撤回吗?"
|
||||
}).then(() => {
|
||||
this.$axios.post("/flow/common/revokeTask", { taskId: row.startTaskId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.infoRef.onOpen(row, "慰问详情")
|
||||
},
|
||||
onEdit(row) {
|
||||
this.$pjaxReplace("/platform/special_condolence/apply/h5?taskId=" + (row.startTaskId || "") + "&bizId=" + row.id)
|
||||
},
|
||||
onDelete(row) {
|
||||
this.$dialog.confirm({
|
||||
title: "提示",
|
||||
message: "您确定要删除吗?"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/special_condolence/mine/delete", { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$toast.fail(res.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
return this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType', {}, {h5SkeletonLoading: true})
|
||||
.then((res) => res.data || [])
|
||||
},
|
||||
doSearch() {
|
||||
this.$nextTick(() => {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.$refs.tableListRef.doSearch()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
#app { --color-primary: #1989fa; }
|
||||
.specialcondolence-list-page { min-height: 100vh; padding-bottom: calc(24px + env(safe-area-inset-bottom)); box-sizing: border-box; background: #f3f7fd; }
|
||||
.specialcondolence-list-page .van-nav-bar, .specialcondolence-list-page .van-sticky--fixed { background: #fff; }
|
||||
.specialcondolence-list-page .van-nav-bar__title { color: #172033; font-size: 16px; font-weight: 600; }
|
||||
.specialcondolence-list-page .van-nav-bar .van-icon, .specialcondolence-list-page .van-nav-bar__text { color: #1989fa; }
|
||||
.specialcondolence-list-sticky { padding: 22px 12px 1px; box-sizing: border-box; background: #f3f7fd; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-search .van-search__content { height: 42px; padding-left: 12px; align-items: center; border-radius: 12px; background: #fff; }
|
||||
.specialcondolence-list-search .van-field__control { color: #263548; font-size: 14px; }
|
||||
.specialcondolence-list-search .van-field__control::placeholder { color: #a7b0bf; }
|
||||
.specialcondolence-list-filter { margin-bottom: 8px; overflow: hidden; border-radius: 10px; box-shadow: 0 5px 16px rgba(43, 73, 112, .08); }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__bar { height: 44px; box-shadow: none; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item, .specialcondolence-list-filter .van-dropdown-menu__title { height: 44px; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item { align-items: center; justify-content: center; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title { display: inline-flex; align-items: center; line-height: 20px; color: #66758a; font-size: 14px; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title--active, .specialcondolence-list-filter .van-dropdown-item__option--active, .specialcondolence-list-filter .van-dropdown-item__option--active .van-dropdown-item__icon { color: #1989fa; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-filter .van-dropdown-item__option { display: flex; min-height: 48px; padding: 0 16px; align-items: center; color: #46566c; font-size: 14px; }
|
||||
.specialcondolence-list-filter .van-dropdown-item__option .van-cell__title { display: flex; min-height: 20px; align-items: center; line-height: 20px; }
|
||||
.specialcondolence-list-content { padding: 0 12px; }
|
||||
.specialcondolence-list-skeleton { padding-top: 2px; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton { padding: 0; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__title { width: 42%; height: 18px; margin-bottom: 18px; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row { height: 14px; margin-top: 12px; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:nth-child(2n) { width: 72% !important; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:last-child { width: 34% !important; margin-top: 18px; margin-left: auto; }
|
||||
.specialcondolence-list-page .table-list-container { margin-top: 0; padding-bottom: 2px; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-card-header { display: flex; margin-bottom: 8px; align-items: flex-start; justify-content: space-between; }
|
||||
.specialcondolence-card-heading { min-width: 0; padding-right: 10px; flex: 1; }
|
||||
.specialcondolence-card-title { overflow: hidden; color: #253247; font-size: 15px; font-weight: 600; line-height: 22px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.specialcondolence-card-code { margin-top: 1px; color: #9ba6b6; font-size: 12px; line-height: 18px; }
|
||||
.specialcondolence-card-status { display: inline-flex; flex: none; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .item-actions { margin-top: 10px; padding-top: 10px; border-top-color: #edf1f6; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn.delete { color: #f04444; background: #fff0f0; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn i { margin-right: 5px; font-size: 13px; }
|
||||
.specialcondolence-list-page .empty-state { padding: 0; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-empty img { display: block; width: 86%; max-width: 290px; height: auto; object-fit: contain; }
|
||||
.specialcondolence-list-empty__title { margin-top: 14px; color: #50627a; font-size: 15px; font-weight: 600; line-height: 22px; }
|
||||
.specialcondolence-list-empty__hint { margin-top: 5px; color: #9aa7b8; font-size: 12px; line-height: 18px; }
|
||||
</style>
|
||||
|
||||
<style id="style-specialcondolence-info-h5">
|
||||
<!--#include("../common/info.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<div class="specialcondolence-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="specialcondolence-list-sticky">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
class="specialcondolence-list-search"
|
||||
placeholder="请输入姓名或者工号搜索"
|
||||
shape="round"
|
||||
clearable
|
||||
@search="doSearch"
|
||||
@clear="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu class="specialcondolence-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="specialcondolence-list-content">
|
||||
<div class="specialcondolence-list-skeleton" v-if="skeletonLoading">
|
||||
<div class="specialcondolence-list-skeleton__card" v-for="index in 3" :key="'school-principal-approval-skeleton-' + index">
|
||||
<van-skeleton title :row="5" animated></van-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<table-list api="/platform/special_condolence/schoolPrincipalApproval/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="specialcondolence-card-header">
|
||||
<div class="specialcondolence-card-heading">
|
||||
<div class="specialcondolence-card-title">{{row.helpUserName || '--'}}</div>
|
||||
<div class="specialcondolence-card-code">工号:{{row.helpLoginName || '--'}}</div>
|
||||
</div>
|
||||
<enum-tag class="specialcondolence-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="specialcondolence-list-empty">
|
||||
<img src="/assets/mobile/img/condolence/condolence-empty.png" alt="暂无慰问审核记录插画">
|
||||
<div class="specialcondolence-list-empty__title">暂无慰问审核记录</div>
|
||||
<div class="specialcondolence-list-empty__hint">当前筛选条件下暂时没有慰问申请</div>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
</main>
|
||||
|
||||
<info ref="infoRef" page-key="specialcondolence-school-principal-detail">
|
||||
<div v-if="showApprovalForm">
|
||||
<section class="specialcondolence-info-card">
|
||||
<h2 class="specialcondolence-info-card__title">
|
||||
审批意见<span class="specialcondolence-audit-card__required">*</span>
|
||||
</h2>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
class="specialcondolence-audit-field"
|
||||
name="tf_opinion"
|
||||
type="textarea"
|
||||
rows="6"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
<h2 class="specialcondolence-info-card__title">
|
||||
审批签字<span class="specialcondolence-audit-card__required">*</span>
|
||||
</h2>
|
||||
<van-field name="tf_sign" :value="formData.tf_sign" :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="specialcondolence-popup-actions">
|
||||
<van-button class="specialcondolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button class="specialcondolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(2)">不同意</van-button>
|
||||
<van-button class="specialcondolence-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: specialcondolenceInfo
|
||||
},
|
||||
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.querySpecialCondolenceType()
|
||||
},
|
||||
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("specialcondolence-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/special_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("specialcondolence-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("specialcondolence-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)
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType', {}, {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("specialcondolence-action-confirm"))
|
||||
}))
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (typeof this.historyLayerUnsubscribe === "function") this.historyLayerUnsubscribe()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
+350
@@ -0,0 +1,350 @@
|
||||
<!--#
|
||||
layout("/layouts/platform_h5.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
#app { --color-primary: #1989fa; }
|
||||
.specialcondolence-list-page { min-height: 100vh; padding-bottom: calc(24px + env(safe-area-inset-bottom)); box-sizing: border-box; background: #f3f7fd; }
|
||||
.specialcondolence-list-page .van-nav-bar, .specialcondolence-list-page .van-sticky--fixed { background: #fff; }
|
||||
.specialcondolence-list-page .van-nav-bar__title { color: #172033; font-size: 16px; font-weight: 600; }
|
||||
.specialcondolence-list-page .van-nav-bar .van-icon, .specialcondolence-list-page .van-nav-bar__text { color: #1989fa; }
|
||||
.specialcondolence-list-sticky { padding: 22px 12px 1px; box-sizing: border-box; background: #f3f7fd; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-search .van-search__content { height: 42px; padding-left: 12px; align-items: center; border-radius: 12px; background: #fff; }
|
||||
.specialcondolence-list-search .van-field__control { color: #263548; font-size: 14px; }
|
||||
.specialcondolence-list-search .van-field__control::placeholder { color: #a7b0bf; }
|
||||
.specialcondolence-list-filter { margin-bottom: 8px; overflow: hidden; border-radius: 10px; box-shadow: 0 5px 16px rgba(43, 73, 112, .08); }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__bar { height: 44px; box-shadow: none; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item, .specialcondolence-list-filter .van-dropdown-menu__title { height: 44px; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__item { align-items: center; justify-content: center; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title { display: inline-flex; align-items: center; line-height: 20px; color: #66758a; font-size: 14px; }
|
||||
.specialcondolence-list-filter .van-dropdown-menu__title--active, .specialcondolence-list-filter .van-dropdown-item__option--active, .specialcondolence-list-filter .van-dropdown-item__option--active .van-dropdown-item__icon { color: #1989fa; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-filter .van-dropdown-item__option { display: flex; min-height: 48px; padding: 0 16px; align-items: center; color: #46566c; font-size: 14px; }
|
||||
.specialcondolence-list-filter .van-dropdown-item__option .van-cell__title { display: flex; min-height: 20px; align-items: center; line-height: 20px; }
|
||||
.specialcondolence-list-content { padding: 0 12px; }
|
||||
.specialcondolence-list-skeleton { padding-top: 2px; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton { padding: 0; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__title { width: 42%; height: 18px; margin-bottom: 18px; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row { height: 14px; margin-top: 12px; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:nth-child(2n) { width: 72% !important; }
|
||||
.specialcondolence-list-skeleton__card .van-skeleton__row:last-child { width: 34% !important; margin-top: 18px; margin-left: auto; }
|
||||
.specialcondolence-list-page .table-list-container { margin-top: 0; padding-bottom: 2px; }
|
||||
.specialcondolence-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); }
|
||||
.specialcondolence-card-header { display: flex; margin-bottom: 8px; align-items: flex-start; justify-content: space-between; }
|
||||
.specialcondolence-card-heading { min-width: 0; padding-right: 10px; flex: 1; }
|
||||
.specialcondolence-card-title { overflow: hidden; color: #253247; font-size: 15px; font-weight: 600; line-height: 22px; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.specialcondolence-card-code { margin-top: 1px; color: #9ba6b6; font-size: 12px; line-height: 18px; }
|
||||
.specialcondolence-card-status { display: inline-flex; flex: none; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .item-actions { margin-top: 10px; padding-top: 10px; border-top-color: #edf1f6; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn.delete { color: #f04444; background: #fff0f0; }
|
||||
.specialcondolence-list-page .table-list-container .table-list-item .action-btn i { margin-right: 5px; font-size: 13px; }
|
||||
.specialcondolence-list-page .empty-state { padding: 0; }
|
||||
.specialcondolence-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; }
|
||||
.specialcondolence-list-empty img { display: block; width: 86%; max-width: 290px; height: auto; object-fit: contain; }
|
||||
.specialcondolence-list-empty__title { margin-top: 14px; color: #50627a; font-size: 15px; font-weight: 600; line-height: 22px; }
|
||||
.specialcondolence-list-empty__hint { margin-top: 5px; color: #9aa7b8; font-size: 12px; line-height: 18px; }
|
||||
</style>
|
||||
|
||||
<style id="style-specialcondolence-info-h5">
|
||||
<!--#include("../common/info.css"){}#-->
|
||||
</style>
|
||||
|
||||
<div id="app">
|
||||
<div class="specialcondolence-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="specialcondolence-list-sticky">
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
class="specialcondolence-list-search"
|
||||
placeholder="请输入姓名或者工号搜索"
|
||||
shape="round"
|
||||
clearable
|
||||
@search="doSearch"
|
||||
@clear="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu class="specialcondolence-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="specialcondolence-list-content">
|
||||
<div class="specialcondolence-list-skeleton" v-if="skeletonLoading">
|
||||
<div class="specialcondolence-list-skeleton__card" v-for="index in 3" :key="'school-union-approval-skeleton-' + index">
|
||||
<van-skeleton title :row="5" animated></van-skeleton>
|
||||
</div>
|
||||
</div>
|
||||
<table-list api="/platform/special_condolence/schoolUnionApproval/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="specialcondolence-card-header">
|
||||
<div class="specialcondolence-card-heading">
|
||||
<div class="specialcondolence-card-title">{{row.helpUserName || '--'}}</div>
|
||||
<div class="specialcondolence-card-code">工号:{{row.helpLoginName || '--'}}</div>
|
||||
</div>
|
||||
<enum-tag class="specialcondolence-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="specialcondolence-list-empty">
|
||||
<img src="/assets/mobile/img/condolence/condolence-empty.png" alt="暂无慰问审核记录插画">
|
||||
<div class="specialcondolence-list-empty__title">暂无慰问审核记录</div>
|
||||
<div class="specialcondolence-list-empty__hint">当前筛选条件下暂时没有慰问申请</div>
|
||||
</div>
|
||||
</template>
|
||||
</table-list>
|
||||
</main>
|
||||
|
||||
<info ref="infoRef" page-key="specialcondolence-school-union-detail">
|
||||
<div v-if="showApprovalForm">
|
||||
<section class="specialcondolence-info-card">
|
||||
<h2 class="specialcondolence-info-card__title">
|
||||
审批意见<span class="specialcondolence-audit-card__required">*</span>
|
||||
</h2>
|
||||
<van-form ref="formRef">
|
||||
<van-field
|
||||
v-model="formData.tf_opinion"
|
||||
class="specialcondolence-audit-field"
|
||||
name="tf_opinion"
|
||||
type="textarea"
|
||||
rows="6"
|
||||
placeholder="请输入审批意见"
|
||||
:rules="[{ required: true, message: '请填写审批意见' }]"
|
||||
maxlength="100"
|
||||
show-word-limit
|
||||
></van-field>
|
||||
<h2 class="specialcondolence-info-card__title">
|
||||
审批签字<span class="specialcondolence-audit-card__required">*</span>
|
||||
</h2>
|
||||
<van-field name="tf_sign" :value="formData.tf_sign" :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="specialcondolence-popup-actions">
|
||||
<van-button class="specialcondolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(6)">退回</van-button>
|
||||
<van-button class="specialcondolence-action-danger" type="danger" block :loading="formLoading" @click="handleTaskAction(2)">不同意</van-button>
|
||||
<van-button class="specialcondolence-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: specialcondolenceInfo
|
||||
},
|
||||
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.querySpecialCondolenceType()
|
||||
},
|
||||
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("specialcondolence-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/special_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("specialcondolence-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("specialcondolence-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)
|
||||
})
|
||||
},
|
||||
querySpecialCondolenceType() {
|
||||
this.$axios.post('/platform/special_condolence/type/querySpecialCondolenceType', {}, {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("specialcondolence-action-confirm"))
|
||||
}))
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (typeof this.historyLayerUnsubscribe === "function") this.historyLayerUnsubscribe()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
Reference in New Issue
Block a user