2 Commits
Author SHA1 Message Date
c-chenxs1 81fd5cb773 feat: 特殊慰问表单优化2 2026-10-30 20:30:12 +08:00
c-chenxs1 efad953710 feat: 特殊慰问表单优化 2026-10-30 19:35:39 +08:00
25 changed files with 302 additions and 175 deletions
@@ -6,17 +6,14 @@ 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.flow.enums.ProcessInstanceStateEnum;
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.condolence.model.Condolence;
import com.budwk.app.zhgh.staffbenefit.condolence.service.CondolenceService;
import io.swagger.annotations.Api;
@@ -94,6 +91,7 @@ public class CondolenceReadController {
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode());
cnd.andEX("info.type", "=", type);
cnd.andEX("YEAR(info.createTime)", "=", year);
cnd.andEX("info.applyUnionId", "=", unionId);
@@ -106,9 +104,6 @@ public class CondolenceReadController {
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");
@@ -142,20 +137,17 @@ public class CondolenceReadController {
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and(ProcessInstance::getState, "=", ProcessTaskStateEnum.FINISHED.getCode());
cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode());
cnd.andEX("con.type", "=", type);
cnd.andEX("YEAR(info.createTime)", "=", year);
cnd.andEX("YEAR(con.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() + "%");
seg.or("con.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%");
seg.or("con.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 = condolenceService.listMap(sql);
@@ -11,6 +11,7 @@ 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.base.utils.SysOfficeTemplateUtil;
import com.budwk.app.flow.constant.FlowConst;
import com.budwk.app.flow.engine.FlowEngine;
import com.budwk.app.flow.entity.ProcessInstance;
@@ -62,6 +63,8 @@ public class SpecialCondolenceApplyController {
private SpecialCondolenceService specialcondolenceService;
@Inject
private FlowCommonService flowCommonService;
@Inject
private SysOfficeTemplateUtil sysOfficeTemplateUtil;
@At("/")
@Ok("beetl:/platform/zhgh/staffbenefit/specialcondolence/apply/index.html")
@@ -181,9 +184,10 @@ public class SpecialCondolenceApplyController {
@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);
String templateCode = "special_condolence_import";
try (java.io.InputStream input = sysOfficeTemplateUtil.getTemplate(templateCode)) {
com.budwk.app.base.utils.CommonDownloadUtil.download(
sysOfficeTemplateUtil.getTemplateFileName(templateCode), input.readAllBytes(), response);
}
}
@@ -6,17 +6,14 @@ 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.flow.enums.ProcessInstanceStateEnum;
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;
@@ -94,6 +91,7 @@ public class SpecialCondolenceReadController {
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode());
cnd.andEX("info.type", "=", type);
cnd.andEX("YEAR(info.createTime)", "=", year);
cnd.andEX("info.applyUnionId", "=", unionId);
@@ -106,9 +104,6 @@ public class SpecialCondolenceReadController {
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");
@@ -133,40 +128,47 @@ public class SpecialCondolenceReadController {
//查询审核通过的数据
Sql sql = Sqls.create("""
select
con.*,
type.name as typeName
con.subject,
case when recipient.id is null then con.helpUserName else recipient.helpUserName end as helpUserName,
case when recipient.id is null then con.helpLoginName else recipient.helpLoginName end as helpLoginName,
con.applyUserName,
con.helpUnionName,
con.helpUnitName,
case when recipient.id is null then type.name else recipient.typeName end as typeName,
case when recipient.id is null then con.money else recipient.money end as money,
con.remark
from
special_condolence con
left join special_condolence_recipient recipient on recipient.applyId = con.id and recipient.delFlag = false
left join wf_process_instance ins on ins.businessNo = con.id
left join special_condolence_type type on type.id = con.type
$condition
order by con.createTime desc, con.id, recipient.sortNum, recipient.id
""");
Cnd cnd = Cnd.NEW();
cnd.and(ProcessInstance::getState, "=", ProcessTaskStateEnum.FINISHED.getCode());
cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode());
cnd.andEX("con.type", "=", type);
cnd.andEX("YEAR(info.createTime)", "=", year);
cnd.andEX("YEAR(con.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() + "%");
seg.or("con.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%");
seg.or("con.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("事项", "subject", 30));
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("慰问金额", "money", 20));
exportEntities.add(new ExcelExportEntity("申请理由", "remark", 20));
ExportParams exportParams = new ExportParams();
@@ -30,6 +30,12 @@ public class SpecialCondolence extends BaseModel {
@PrevInsert(uu32 = true)
private String id;
@Column
@Comment("事项")
@ColDefine(type = ColType.VARCHAR, width = 200)
private String subject;
@Column
@Comment("申请人ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
@@ -14,6 +14,8 @@ public final class SpecialCondolenceRecipients {
private SpecialCondolenceRecipients() {}
public static void prepare(SpecialCondolence info, Dao dao) {
if (info.getSubject() == null || info.getSubject().trim().isEmpty() || info.getSubject().trim().length() > 200) throw new BaseException("请填写200字以内的事项");
info.setSubject(info.getSubject().trim());
List<JSONObject> rows = info.getRecipients();
if (rows == null || rows.isEmpty()) throw new BaseException("请添加慰问对象");
if (rows.size() > 1000) throw new BaseException("每次申请最多1000人");
@@ -2,6 +2,7 @@
-- 表已存在时不执行本文件中的建表语句;本文件不复制数据、不配置角色授权和工作流。
CREATE TABLE `special_condolence` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`subject` varchar(255) DEFAULT NULL COMMENT '事项',
`applyUserId` varchar(32) DEFAULT NULL COMMENT '申请人ID',
`applyUserName` varchar(100) DEFAULT NULL COMMENT '申请人姓名',
`applyLoginName` varchar(120) DEFAULT NULL COMMENT '申请人工号',
@@ -185,6 +186,7 @@ VALUES ('7f4a820d5a394bb8a0a92d6699afe7c8', '42b4b5f54593cf023961ad1c9ce36f53'),
INSERT INTO sys_role_menu (roleId, menuId)
VALUES
('494ac71eb8b44d0e99e19b7fde6bd469', '4c46696d75ff0eddf5cb57fac3e5d06d'),
('494ac71eb8b44d0e99e19b7fde6bd469', '8d5ebaa091eee01abb33e89e3dcc92f8'),
('494ac71eb8b44d0e99e19b7fde6bd469', '7f66eb63b6ebd81c5eee9c5c2de2ed98');
-- 特殊慰问 h5
@@ -198,6 +200,7 @@ VALUES
INSERT INTO sys_role_menu (roleId, menuId)
VALUES
('6aece46b946e4fb9ac4cb15c0cd8c3e6', '4c46696d75ff0eddf5cb57fac3e5d06d'),
('6aece46b946e4fb9ac4cb15c0cd8c3e6', '8d5ebaa091eee01abb33e89e3dcc92f8'),
('6aece46b946e4fb9ac4cb15c0cd8c3e6', 'b24a5bef9ccbf7241c5bb85e80352f8f');
-- 特殊慰问 h5
@@ -211,6 +214,7 @@ VALUES
INSERT INTO sys_role_menu (roleId, menuId)
VALUES
('b3854469e6f44901b22bb791cb538431', '4c46696d75ff0eddf5cb57fac3e5d06d'),
('b3854469e6f44901b22bb791cb538431', '8d5ebaa091eee01abb33e89e3dcc92f8'),
('b3854469e6f44901b22bb791cb538431', '9c37242f50c5fb4a9c1b2b9b9dd0e2fd');
-- 特殊慰问 h5
@@ -0,0 +1,17 @@
<el-descriptions-item label="慰问类型" :span="2">
<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="慰问金额" :span="2">
<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="慰问时间" :span="2">
<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>
@@ -10,25 +10,27 @@ layout("/layouts/platform.html"){
<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-tabs v-model="activeApplicationTab">
<el-tab-pane label="基础信息" name="form">
<el-descriptions :column="6" border size="small">
<el-descriptions-item label="事项" :span="2"><el-form-item prop="subject" label="事项"><el-input v-model="formData.subject" maxlength="200" show-word-limit placeholder="请输入特殊慰问事项"></el-input></el-form-item></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-descriptions-item label="申请人姓名" :span="2">{{formData.applyUserName}}</el-descriptions-item>
<el-descriptions-item label="申请人工号" :span="2">{{formData.applyLoginName}}</el-descriptions-item>
<!--#include('config.html'){}#-->
<el-descriptions-item label="申请人单位" :span="2">{{formData.applyUnitName}}</el-descriptions-item>
<el-descriptions-item label="申请人工会" :span="2">{{formData.applyUnionName}}</el-descriptions-item>
<el-descriptions-item label="" :span="2"><span></span></el-descriptions-item>
<el-descriptions-item label="申请事由" :span="6">
<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">
<el-descriptions-item :span="6" v-if="chooseType.isUploadFile === true">
<template slot="label">
附件
<el-tooltip class="item" effect="dark" :content="'上传附件说明:' + chooseType.uploadFileDesc"
@@ -48,12 +50,17 @@ layout("/layouts/platform.html"){
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="签字" :span="3">
<el-descriptions-item label="签字" :span="6">
<el-form-item prop="signature" label="签字">
<pc-signature v-model="formData.signature"></pc-signature>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="慰问对象" name="recipients" :lazy="false">
<!--#include('recipients.html'){}#-->
</el-tab-pane>
</el-tabs>
</el-form>
<el-row type="flex" justify="end" class="special-condolence-actions">
<el-button type="primary" plain @click="onSave">保存申请</el-button>
@@ -84,7 +91,8 @@ layout("/layouts/platform.html"){
taskId: GetQueryString("taskId"),
formData: { recipients: [] },
formRules: {
recipients: [{ validator: (rule, value, callback) => callback(value && value.length ? undefined : new Error("请添加慰问对象")), trigger: "change" }],
subject: [{ required: true, whitespace: true, message: "请填写事项", trigger: ["blur", "change"] }, { max: 200, message: "事项最多200字", trigger: "blur" }],
recipients: [{ validator: (rule, value, callback) => callback(Array.isArray(value) && value.length > 0 ? 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"] }],
@@ -197,8 +205,8 @@ layout("/layouts/platform.html"){
}
},
onSave() {
this.$refs.formRef.validate((valid) => {
if (!valid) return
this.$refs.formRef.validate((valid, invalidFields) => {
if (!valid) { this.showInvalidApplicationTab(invalidFields); return }
this.$confirm("您确定保存吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
@@ -214,7 +222,9 @@ layout("/layouts/platform.html"){
})
},
onSubmit() {
this.$refs.formRef.validate((valid) => {
if (!this.ensureApplicationRecipients()) return
this.$refs.formRef.validate((valid, invalidFields) => {
if (!valid) { this.showInvalidApplicationTab(invalidFields); return }
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
@@ -234,7 +244,9 @@ layout("/layouts/platform.html"){
})
},
onFinishTask() {
this.$refs.formRef.validate((valid) => {
if (!this.ensureApplicationRecipients()) return
this.$refs.formRef.validate((valid, invalidFields) => {
if (!valid) { this.showInvalidApplicationTab(invalidFields); return }
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
confirmButtonText: "确定",
@@ -12,8 +12,8 @@
.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-recipients { margin: 0; }
.special-condolence-apply .special-condolence-toolbar { display: flex; justify-content: flex-end; align-items: center; flex-wrap: wrap; gap: 14px; padding: 0 0 12px; }
.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; }
@@ -28,7 +28,7 @@
.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-table-footer { display: flex; justify-content: flex-end; 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; }
@@ -1,36 +1,12 @@
<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 ref="recipientTableRef" :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" 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 || '') + ')'" @selected="(user, id) => recipientUserChange(s.row, s.$index, id, user)"></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>
@@ -42,7 +18,6 @@
</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>
@@ -1,6 +1,6 @@
const specialCondolenceRecipients = {
data() {
return { recipientRules: this.createRecipientRules(), importVisible: false, importLoading: false }
return { activeApplicationTab: 'form', recipientRules: this.createRecipientRules(), importVisible: false, importLoading: false }
},
computed: {
recipientCount() {
@@ -13,10 +13,34 @@ const specialCondolenceRecipients = {
}
},
watch: {
activeApplicationTab() {
this.$nextTick(() => {
if (this.$refs.recipientTableRef) this.$refs.recipientTableRef.doLayout()
})
},
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: {
showInvalidApplicationTab(errors) {
const fields = Array.isArray(errors) ? errors.map(error => error.name || '') : Object.keys(errors || {})
if (!fields.length) return
this.activeApplicationTab = fields.some(field => !field.startsWith('recipients')) ? 'form' : 'recipients'
if (this.activeApplicationTab === 'recipients') this.notifyRecipientError('请完善慰问对象的必填信息')
},
notifyRecipientError(message) {
if (this.$toast && this.$toast.fail) this.$toast.fail(message)
else this.$message.error(message)
},
ensureApplicationRecipients() {
const rows = this.formData.recipients
if (!Array.isArray(rows) || rows.length === 0 || rows.some(row => !row || !String(row.helpUserId || '').trim())) {
this.activeApplicationTab = 'recipients'
this.notifyRecipientError('请先选择慰问对象,并填写完整信息')
return false
}
return true
},
createRecipientRules() {
const required = label => ({ required: true, whitespace: true, message: '请填写' + label, trigger: ['blur', 'change'] })
return {
@@ -1,20 +1,44 @@
const specialcondolenceInfo = {
template: /*language=HTML*/ `
<div>
<el-tabs v-model="activeInfoTab">
<el-tab-pane label="基础信息" name="form">
<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>
<el-descriptions :column="6" border size="small" :label-style="{ width: '130px', minWidth: '130px', maxWidth: '130px', fontSize: '14px', fontWeight: 400, lineHeight: '32px', padding: '8px 12px' }" :content-style="{ fontSize: '14px', fontWeight: 400, lineHeight: '32px', padding: '8px 12px' }">
<el-descriptions-item label="事项" :span="2">{{ viewData.subject || '--' }}</el-descriptions-item>
<el-descriptions-item label="申请人姓名" :span="2">{{ viewData.applyUserName }}</el-descriptions-item>
<el-descriptions-item label="申请人工号" :span="2">{{ viewData.applyLoginName }}</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>
<el-descriptions-item label="慰问类型" :span="2">{{ viewData.typeName }}</el-descriptions-item>
<el-descriptions-item label="每人慰问金额" :span="2">{{ viewData.perMoney }} 元</el-descriptions-item>
<el-descriptions-item label="慰问时间" :span="2">{{ viewData.occurTime }}</el-descriptions-item>
</template>
<el-descriptions-item label="申请人单位" :span="2">{{ viewData.applyUnitName }}</el-descriptions-item>
<el-descriptions-item label="申请人工会" :span="2">{{ viewData.applyUnionName }}</el-descriptions-item>
<el-descriptions-item label="" :span="2"><span></span></el-descriptions-item>
<el-descriptions-item label="申请事由" :span="6">
<div style="white-space: pre-line">{{ viewData.remark }}</div>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="6">
<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="6">
<el-image :src="viewData.signature"
v-if="viewData.signature"
class="signature-image"></el-image>
<span v-else>暂无签字</span>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="慰问对象" name="recipients">
<el-descriptions v-if="!viewData.recipients || !viewData.recipients.length" :column="3" border>
<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>-->
@@ -32,27 +56,13 @@ const specialcondolenceInfo = {
</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>慰问对象明细</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 ref="recipientInfoTableRef" 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>
@@ -61,6 +71,9 @@ const specialcondolenceInfo = {
<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>
</el-tab-pane>
<el-tab-pane label="审核记录" name="records">
<div v-if="!doneTasks.length" style="padding:32px;text-align:center;color:#909399">暂无审核记录</div>
<template v-for="task in doneTasks">
<div class="mt10">
<div class="process-title">{{ task.displayName }}</div>
@@ -94,6 +107,8 @@ const specialcondolenceInfo = {
</el-descriptions>
</div>
</template>
</el-tab-pane>
</el-tabs>
<slot></slot>
<snaker-chart ref="snakerChartRef"></snaker-chart>
</div>
@@ -102,12 +117,20 @@ const specialcondolenceInfo = {
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
data() {
return {
activeInfoTab: 'form',
visible: false,
viewData: {},
doneTasks: [],
row: null
}
},
watch: {
activeInfoTab() {
this.$nextTick(() => {
if (this.$refs.recipientInfoTableRef) this.$refs.recipientInfoTableRef.doLayout()
})
}
},
computed: {
detailTotal() {
const cents = (this.viewData.recipients || []).reduce((sum, row) => {
@@ -119,6 +142,7 @@ const specialcondolenceInfo = {
},
methods: {
onOpen(row) {
this.activeInfoTab = 'form'
this.row = row
this.visible = true
this.getInfo()
@@ -134,7 +134,7 @@ layout("/layouts/platform.html"){
},
typeOptions: [],
tableColumns: [
{prop: 'helpUserName', label: '慰问对象'},
{prop: 'subject', label: '事项'},
{prop: 'applyUserName', label: '申请人'},
{prop: 'applyUnionName', label: '所属工会'},
{prop: 'applyUnitName', label: '所属单位'},
@@ -92,7 +92,7 @@ layout("/layouts/platform.html"){
typeOptions: [],
pageDataUrl: "/platform/special_condolence/mine/pageData",
tableColumns: [
{prop: 'helpUserName', label: '慰问对象'},
{prop: 'subject', label: '事项'},
{prop: 'applyUserName', label: '申请人'},
{prop: 'applyUnionName', label: '所属工会'},
{prop: 'applyUnitName', label: '所属单位'},
@@ -105,8 +105,7 @@ layout("/layouts/platform.html"){
return {
typeOptions: [],
tableColumns: [
{prop: 'helpUserName', label: '慰问对象'},
{prop: 'helpLoginName', label: '慰问对象工号'},
{prop: 'subject', label: '事项'},
{prop: 'applyUserName', label: '申请人'},
{prop: 'applyUnionName', label: '所属工会'},
{prop: 'applyUnitName', label: '所属单位'},
@@ -134,7 +134,7 @@ layout("/layouts/platform.html"){
},
typeOptions: [],
tableColumns: [
{prop: 'helpUserName', label: '慰问对象'},
{prop: 'subject', label: '事项'},
{prop: 'applyUserName', label: '申请人'},
{prop: 'applyUnionName', label: '所属工会'},
{prop: 'applyUnitName', label: '所属单位'},
@@ -134,7 +134,7 @@ layout("/layouts/platform.html"){
},
typeOptions: [],
tableColumns: [
{prop: 'helpUserName', label: '慰问对象'},
{prop: 'subject', label: '事项'},
{prop: 'applyUserName', label: '申请人'},
{prop: 'applyUnionName', label: '所属工会'},
{prop: 'applyUnitName', label: '所属单位'},
@@ -30,11 +30,15 @@ layout("/layouts/platform_h5.html"){
background: #f3f7fc;
}
.specialcondolence-apply-form > .van-tabs > .van-tabs__content {
padding-top: 11px;
}
.specialcondolence-apply-form .form-section {
margin-bottom: 11px;
overflow: hidden;
border: 1px solid #e9eff7;
border-radius: 10px;
border-radius: 0;
background: #fff;
box-shadow: 0 3px 11px rgba(51, 87, 126, 0.08);
}
@@ -173,12 +177,15 @@ layout("/layouts/platform_h5.html"){
placeholder></van-nav-bar>
<!-- 表单容器 -->
<van-form ref="formRef" class="form-container specialcondolence-apply-form">
<van-form ref="formRef" class="form-container specialcondolence-apply-form" :show-error="true" :show-error-message="true">
<van-tabs v-model="activeApplicationTab" :lazy-render="false">
<van-tab title="基础信息" name="form">
<!-- 基本信息 -->
<section class="form-section">
<h2 class="specialcondolence-card__title">基本信息</h2>
<van-cell-group :border="false">
<van-field v-model="formData.subject" name="subject" label="事项" maxlength="200" required placeholder="请输入特殊慰问事项" :rules="[{ validator: value => !!String(value || '').trim() && String(value).length <= 200, message: '请填写200字以内的事项' }]"></van-field>
<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
@@ -192,18 +199,7 @@ layout("/layouts/platform_h5.html"){
<van-popup v-model="showTypePicker" position="bottom" round get-container="body"><van-picker :columns="typeColumns" :default-index="typeDefaultIndex" show-toolbar @confirm="onTypeConfirm" @cancel="showTypePicker = false"></van-picker></van-popup>
<van-field v-model="formData.perMoney" name="perMoney" label="每人金额" type="number" required :rules="[{ validator: validateMoney, message: '金额须大于0且不超过10000元,最多两位小数' }]"></van-field>
<van-field v-model="formData.occurTime" name="occurTime" label="慰问时间" readonly clickable is-link placeholder="请选择慰问时间" required :rules="[{ validator: value => $moment(value, 'YYYY-MM-DD', true).isValid(), message: '请选择有效慰问时间' }]" @click="showTimePickerClick"></van-field>
<van-popup v-model="showTimePicker" position="bottom" round get-container="body"><van-datetime-picker v-model="formData.occurDate" type="date" :min-date="minDate" :max-date="new Date(2100, 11, 31)" title="请选择慰问时间" @confirm="confirmOccurTime" @cancel="showTimePicker = false"></van-datetime-picker></van-popup>
<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>
<h5-user-select v-model="person.helpUserId" :display-name="person.helpUserName" api="/platform/special_condolence/apply/listUser" label="慰问对象" placeholder="点击选择本工会人员" required :name="'recipients.' + index + '.helpUserId'" :rules="mobileRecipientRules('helpUserId', person)" @selected="(user, id) => recipientUserChange(person, index, id, user)"></h5-user-select>
<van-field v-model="person.helpLoginName" label="工号" readonly placeholder="选人后带出,劳务派遣可空" :required="person.personType !== '劳务派遣人员'" :name="'recipients.' + index + '.helpLoginName'" :rules="mobileRecipientRules('helpLoginName', person)"></van-field>
<van-field v-model="person.idCard" label="身份证号码" maxlength="18" required :name="'recipients.' + index + '.idCard'" :rules="mobileRecipientRules('idCard', person)"></van-field>
<van-field v-model="person.bankOfDeposit" label="开户行" maxlength="100" required :name="'recipients.' + index + '.bankOfDeposit'" :rules="mobileRecipientRules('bankOfDeposit', person)"></van-field>
<van-field v-model="person.bankUserName" label="户名" maxlength="100" required :name="'recipients.' + index + '.bankUserName'" :rules="mobileRecipientRules('bankUserName', person)"></van-field>
<van-field v-model="person.bankCardNumber" label="收款账户" maxlength="30" required :name="'recipients.' + index + '.bankCardNumber'" :rules="mobileRecipientRules('bankCardNumber', person)"></van-field>
</div>
<van-field name="recipients" :value="recipientCount" :rules="[{ validator: value => Number(value) > 0, message: '请至少添加一位慰问对象' }]"><template #input><van-button native-type="button" size="small" type="info" plain @click="formData.recipients.push(newRecipient())">增加一行</van-button></template></van-field>
<van-cell title="慰问金额合计" :value="'¥ ' + recipientTotal + '(' + recipientCount + '人)'"></van-cell>
<van-popup v-model="showTimePicker" position="bottom" round get-container="body"><van-datetime-picker v-if="showTimePicker" v-model="formData.occurDate" type="date" :min-date="minDate" :max-date="maxDate" title="请选择慰问时间" @confirm="confirmOccurTime" @cancel="showTimePicker = false"></van-datetime-picker></van-popup>
<van-field
v-model="formData.remark"
name="remark"
@@ -254,6 +250,26 @@ layout("/layouts/platform_h5.html"){
</van-cell-group>
</section>
</van-tab>
<van-tab title="慰问对象" name="recipients">
<section class="form-section">
<h2 class="specialcondolence-card__title">慰问对象</h2>
<van-cell-group :border="false">
<div v-for="(person, index) in formData.recipients" :key="index">
<van-cell :title="'慰问对象 ' + (index + 1)" :title-style="{ fontWeight: 'bold' }"><van-button native-type="button" size="mini" @click="formData.recipients.splice(index, 1)">删除</van-button></van-cell>
<h5-user-select v-model="person.helpUserId" :display-name="person.helpUserName" api="/platform/special_condolence/apply/listUser" label="慰问对象" placeholder="点击选择本工会人员" required :name="'recipients.' + index + '.helpUserId'" :rules="mobileRecipientRules('helpUserId', person)" @selected="(user, id) => recipientUserChange(person, index, id, user)"></h5-user-select>
<van-field v-model="person.helpLoginName" label="工号" readonly placeholder="选人后带出,劳务派遣可空" :required="person.personType !== '劳务派遣人员'" :name="'recipients.' + index + '.helpLoginName'" :rules="mobileRecipientRules('helpLoginName', person)"></van-field>
<van-field v-model="person.idCard" label="身份证号码" maxlength="18" required :name="'recipients.' + index + '.idCard'" :rules="mobileRecipientRules('idCard', person)"></van-field>
<van-field v-model="person.bankOfDeposit" label="开户行" maxlength="100" required :name="'recipients.' + index + '.bankOfDeposit'" :rules="mobileRecipientRules('bankOfDeposit', person)"></van-field>
<van-field v-model="person.bankUserName" label="户名" maxlength="100" required :name="'recipients.' + index + '.bankUserName'" :rules="mobileRecipientRules('bankUserName', person)"></van-field>
<van-field v-model="person.bankCardNumber" label="收款账户" maxlength="30" required :name="'recipients.' + index + '.bankCardNumber'" :rules="mobileRecipientRules('bankCardNumber', person)"></van-field>
</div>
<van-field name="recipients" :value="recipientCount" :rules="[{ validator: value => Number(value) > 0, message: '请至少添加一位慰问对象' }]"><template #input><van-button native-type="button" size="small" type="info" plain @click="formData.recipients.push(newRecipient())">增加一行</van-button></template></van-field>
<van-cell title="慰问金额合计" :value="'¥ ' + recipientTotal + '(' + recipientCount + '人)'"></van-cell>
</van-cell-group>
</section>
</van-tab>
</van-tabs>
<!-- 提交按钮 -->
<div class="form-actions specialcondolence-apply-actions">
<van-button native-type="button" @click="onSave" round type="info" plain>保存申请</van-button>
@@ -276,7 +292,7 @@ layout("/layouts/platform_h5.html"){
return {
bizId: GetQueryString("bizId"),
taskId: GetQueryString("taskId"),
formData: { recipients: [] },
formData: { recipients: [this.newRecipient()], occurTime: this.$moment().format('YYYY-MM-DD') },
chooseType: {},
userOptions: [],
@@ -298,13 +314,30 @@ layout("/layouts/platform_h5.html"){
showHospitalizationTimePicker: false,
showLeaveHospitalTimePicker: false,
minDate: new Date(2024, 0, 1),
maxDate: new Date(),
maxDate: new Date(2100, 11, 31),
typeDefaultIndex: 0
}
},
watch: {
'$store.state.user'(user) {
if (user && !this.bizId && !this.formData.applyUserId) this.init()
}
},
methods: {
showInvalidApplicationTab(errors) {
if (!Array.isArray(errors) || !errors.length) return
const error = errors[0]
const name = String(error.name || '')
const recipient = name.match(/^recipients\.(\d+)\./)
this.activeApplicationTab = name.startsWith('recipients') ? 'recipients' : 'form'
const message = error.message || '请完善必填信息'
this.$toast.fail(recipient ? '第' + (Number(recipient[1]) + 1) + '位慰问对象:' + message : message)
this.$nextTick(() => {
this.$refs.formRef.scrollToField(error.name)
})
},
mobileRecipientRules(field, person) {
const names = { helpUserId: '慰问对象', helpLoginName: '工号', idCard: '身份证号码', bankOfDeposit: '开户行', bankUserName: '户名', bankCardNumber: '收款账户' }
if (field === 'helpLoginName') return [{ validator: value => person.personType === '劳务派遣人员' || !!String(value || '').trim(), message: '普通人员工号不能为空' }]
@@ -443,7 +476,7 @@ layout("/layouts/platform_h5.html"){
}
})
})
}).catch(() => {})
}).catch(errors => this.showInvalidApplicationTab(errors))
},
async onSubmit() {
this.$refs.formRef.validate().then(() => {
@@ -462,7 +495,7 @@ layout("/layouts/platform_h5.html"){
}
})
})
})
}).catch(errors => this.showInvalidApplicationTab(errors))
},
async onFinishTask() {
this.$refs.formRef.validate().then(() => {
@@ -484,7 +517,7 @@ layout("/layouts/platform_h5.html"){
}
})
})
})
}).catch(errors => this.showInvalidApplicationTab(errors))
},
init() {
if (this.bizId) {
@@ -496,11 +529,10 @@ layout("/layouts/platform_h5.html"){
}
})
} 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'),
const user = this.$store.state.user
if (!user) return
const { username, loginname, id, unit, union, mobile } = user
this.formData = Object.assign({}, this.formData, {
applyUserName: username,
applyLoginName: loginname,
applyUserId: id,
@@ -508,7 +540,7 @@ layout("/layouts/platform_h5.html"){
applyUnitName: unit?.name,
applyUnionId: union?.id,
applyUnionName: union?.name
}
})
}
},
querySpecialCondolenceType() {
@@ -36,11 +36,15 @@
padding: 12px 15px calc(18px + env(safe-area-inset-bottom));
}
.specialcondolence-info-main > .van-tabs > .van-tabs__content {
padding-top: 11px;
}
.specialcondolence-info-card {
margin-bottom: 11px;
overflow: hidden;
border: 1px solid #e9eff7;
border-radius: 10px;
border-radius: 0;
background: #fff;
box-shadow: 0 3px 11px rgba(51, 87, 126, .08);
}
@@ -79,7 +83,7 @@
padding: 12px;
box-sizing: border-box;
border: 1px solid #c9d5e5;
border-radius: 10px;
border-radius: 0;
background: #f7f9fd;
}
@@ -17,9 +17,12 @@ const specialcondolenceInfo = {
></van-nav-bar>
<div class="specialcondolence-full-popup__scroll">
<main class="specialcondolence-info-main">
<van-tabs v-model="activeInfoTab" :lazy-render="false">
<van-tab title="基础信息" name="form">
<section class="specialcondolence-info-card">
<h2 class="specialcondolence-info-card__title">基本信息</h2>
<van-cell-group :border="false">
<van-cell title="事项">{{ viewData.subject || '--' }}</van-cell>
<van-cell title="申请人姓名">{{ viewData.applyUserName || '--' }}</van-cell>
<van-cell title="申请人工号">{{ viewData.applyLoginName || '--' }}</van-cell>
<van-cell title="申请人单位">{{ viewData.applyUnitName || '--' }}</van-cell>
@@ -29,8 +32,30 @@ const specialcondolenceInfo = {
<van-cell title="每人慰问金额" :value="viewData.perMoney"></van-cell>
<van-cell title="慰问时间" :value="viewData.occurTime"></van-cell>
</template>
<van-cell title="申请事由">{{ viewData.remark || '暂无' }}</van-cell>
<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>
</van-tab>
<van-tab title="慰问对象" name="recipients">
<section class="specialcondolence-info-card">
<h2 class="specialcondolence-info-card__title">慰问对象</h2>
<van-cell-group :border="false">
<template v-for="(person, index) in viewData.recipients">
<van-cell :title="'慰问对象 ' + (index + 1)" :value="person.helpUserName"></van-cell>
<van-cell :title="'慰问对象 ' + (index + 1)" :title-style="{ fontWeight: 'bold' }" :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>
@@ -53,25 +78,12 @@ const specialcondolenceInfo = {
<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>
</van-cell-group>
</section>
</van-tab>
<van-tab title="审核记录" name="records">
<van-empty v-if="!doneTasks.length" description="暂无审核记录"></van-empty>
<section
v-for="(task, index) in doneTasks"
:key="task.id || index"
@@ -110,6 +122,8 @@ const specialcondolenceInfo = {
</van-cell-group>
</section>
</van-tab>
</van-tabs>
<slot></slot>
</main>
</div>
@@ -125,6 +139,7 @@ const specialcondolenceInfo = {
},
data() {
return {
activeInfoTab: 'form',
visible: false,
popupTitle: "慰问详情",
viewData: {},
@@ -144,6 +159,7 @@ const specialcondolenceInfo = {
* row 传列表当前行,title 传顶部导航标题;无返回值。
*/
onOpen(row, title = "慰问详情") {
this.activeInfoTab = 'form'
this.$set(this, "row", row)
this.$set(this, "popupTitle", title)
this.$set(this, "viewData", {})
@@ -90,14 +90,13 @@ layout("/layouts/platform_h5.html"){
<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-title">{{row.subject || '--'}}</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.applyUserName}}</table-column>
<table-column label="所属工会">{{row.applyUnionName}}</table-column>
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
@@ -135,7 +134,7 @@ layout("/layouts/platform_h5.html"){
<h2 class="specialcondolence-info-card__title">
审批意见<span class="specialcondolence-audit-card__required">*</span>
</h2>
<van-form ref="formRef">
<van-form ref="formRef" :show-error="true" :show-error-message="true">
<van-field
v-model="formData.tf_opinion"
class="specialcondolence-audit-field"
@@ -143,7 +142,7 @@ layout("/layouts/platform_h5.html"){
type="textarea"
rows="6"
placeholder="请输入审批意见"
:rules="[{ required: true, message: '请填写审批意见' }]"
:rules="[{ validator: value => !!String(value || '').trim(), message: '请填写审批意见' }]"
maxlength="100"
show-word-limit
></van-field>
@@ -263,7 +262,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("specialcondolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {
@@ -327,14 +327,13 @@ layout("/layouts/platform_h5.html"){
<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-title">{{row.subject || '--'}}</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.applyUserName}}</table-column>
<table-column label="所属工会">{{row.applyUnionName}}</table-column>
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
@@ -90,14 +90,13 @@ layout("/layouts/platform_h5.html"){
<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-title">{{row.subject || '--'}}</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.applyUserName}}</table-column>
<table-column label="所属工会">{{row.applyUnionName}}</table-column>
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
@@ -135,7 +134,7 @@ layout("/layouts/platform_h5.html"){
<h2 class="specialcondolence-info-card__title">
审批意见<span class="specialcondolence-audit-card__required">*</span>
</h2>
<van-form ref="formRef">
<van-form ref="formRef" :show-error="true" :show-error-message="true">
<van-field
v-model="formData.tf_opinion"
class="specialcondolence-audit-field"
@@ -143,7 +142,7 @@ layout("/layouts/platform_h5.html"){
type="textarea"
rows="6"
placeholder="请输入审批意见"
:rules="[{ required: true, message: '请填写审批意见' }]"
:rules="[{ validator: value => !!String(value || '').trim(), message: '请填写审批意见' }]"
maxlength="100"
show-word-limit
></van-field>
@@ -246,7 +245,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("specialcondolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {
@@ -90,14 +90,13 @@ layout("/layouts/platform_h5.html"){
<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-title">{{row.subject || '--'}}</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.applyUserName}}</table-column>
<table-column label="所属工会">{{row.applyUnionName}}</table-column>
<table-column label="所属单位">{{row.applyUnitName}}</table-column>
@@ -135,7 +134,7 @@ layout("/layouts/platform_h5.html"){
<h2 class="specialcondolence-info-card__title">
审批意见<span class="specialcondolence-audit-card__required">*</span>
</h2>
<van-form ref="formRef">
<van-form ref="formRef" :show-error="true" :show-error-message="true">
<van-field
v-model="formData.tf_opinion"
class="specialcondolence-audit-field"
@@ -143,7 +142,7 @@ layout("/layouts/platform_h5.html"){
type="textarea"
rows="6"
placeholder="请输入审批意见"
:rules="[{ required: true, message: '请填写审批意见' }]"
:rules="[{ validator: value => !!String(value || '').trim(), message: '请填写审批意见' }]"
maxlength="100"
show-word-limit
></van-field>
@@ -246,7 +245,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("specialcondolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {