Author SHA1 Message Date
c-chenxs1 d889fd3e28 Merge branch 'release_20261030问题整改' of http://gitea.dd3skj.com/c-hongqw1/zhgh_cqgmy into release_20261030问题整改 2026-11-02 11:17:45 +08:00
c-chenxs1 0cd4f52b30 fix: 修复文化活动表单交互并统一流程图布局
- 修复活动列表插槽渲染异常及字段回显问题
- 修复选择联系人时的报错和手机号回填逻辑
- 暂时注释报名表单及设计入口
- 统一社团、分工会文化活动新建和编辑页的流程图布局
- 隐藏社团文化活动进入审核后的编辑入口
2026-11-02 11:15:47 +08:00
c-chengc1 0085385701 Merge remote-tracking branch 'refs/remotes/origin/fix_经费提案' into release_20261030问题整改 2026-11-02 11:14:33 +08:00
c-chengc1 46ddfd0942 Merge remote-tracking branch 'origin/feature_民主管理、人员管理' into release_20261030问题整改
# Conflicts:
#	src/main/resources/views/platform/zhgh/activity/culture/common/applyActivity.js
2026-11-02 11:06:34 +08:00
c-chenxs1 365c812c6c fix: 完善年度考核签字展示及文化活动编辑与权限处理
- 补充年度考核审核记录的签字结果展示,兼容历史记录
- 修复文化活动编辑时联系人为空导致加载中断的问题
- 修复活动列表异步组件挂载时的节点查询异常
- 修正全局 jQuery 请求回调的错误提示
- 增加人员范围设置及人员调整的入口权限校验
- 修复设置活动人员失败后错误未提示、持续加载的问题
2026-11-02 10:52:00 +08:00
c-hongqw1 4271924a2f 首页待办顶部对齐,活动管理整改,职工福利复测整改 2026-11-02 10:49:42 +08:00
c-chenxs1 12448bee0d feat: 困难帮扶优化3 2026-10-31 18:42:11 +08:00
c-chenxs1 81a1432702 feat: 困难帮扶优化2 标签 2026-10-31 18:30:38 +08:00
c-zhouhf1 637fe6f838 整改民主管理测试---芳姐 2026-10-31 18:04:30 +08:00
c-chenxs1 a1fa323420 feat: 困难帮扶优化2 2026-10-31 17:48:30 +08:00
c-chenxs1 7b7f1f61f9 feat: 困难帮扶优化 2026-10-31 17:13:47 +08:00
c-chenxs1 f30dbcaa21 feat: 特殊慰问-职工慰问优化4 2026-10-31 16:38:27 +08:00
c-chenxs1 42c5f4acd7 feat: 特殊慰问-职工慰问优化3 2026-10-31 15:21:01 +08:00
51 changed files with 716 additions and 402 deletions
@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.exception.BaseException; import com.budwk.app.base.exception.BaseException;
import com.budwk.app.sys.models.Sys_file; import com.budwk.app.sys.models.Sys_file;
import com.budwk.app.sys.models.Sys_office_template; import com.budwk.app.sys.models.Sys_office_template;
import com.budwk.app.sys.services.SysFileService;
import com.budwk.app.sys.utils.SysFileMinIoUtil; import com.budwk.app.sys.utils.SysFileMinIoUtil;
import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.Configure;
@@ -22,6 +23,7 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@@ -39,6 +41,9 @@ public class SysOfficeTemplateUtil {
@Inject @Inject
private Dao dao; private Dao dao;
@Inject
private SysFileService sysFileService;
public String getTemplateFileName(String templateCode) { public String getTemplateFileName(String templateCode) {
Sys_office_template officeTemplate = dao.fetch(Sys_office_template.class, Cnd.where(Sys_office_template::getTemplateCode, "=", templateCode)); Sys_office_template officeTemplate = dao.fetch(Sys_office_template.class, Cnd.where(Sys_office_template::getTemplateCode, "=", templateCode));
if (ObjectUtil.isNull(officeTemplate)) { if (ObjectUtil.isNull(officeTemplate)) {
@@ -70,7 +75,16 @@ public class SysOfficeTemplateUtil {
if (ObjectUtil.isEmpty(sysFile)) { if (ObjectUtil.isEmpty(sysFile)) {
throw new BaseException("模板文件不存在"); throw new BaseException("模板文件不存在");
} }
byte[] fileBytes = SysFileMinIoUtil.getFileBytes(sysFile.getBucket(), sysFile.getStoragePath()); byte[] fileBytes;
try {
fileBytes = sysFileService.download(id);
} catch (IOException e) {
log.error("模板文件读取失败,templateCode={},fileId={}", templateCode, id, e);
throw new BaseException("模板 {} 的文件读取失败:{}", templateCode, e.getMessage());
}
if (fileBytes == null || fileBytes.length == 0) {
throw new BaseException("模板 {} 的文件为空或读取失败,文件名:{}", templateCode, sysFile.getName());
}
return new ByteArrayInputStream(fileBytes); return new ByteArrayInputStream(fileBytes);
} }
@@ -57,6 +57,8 @@ public class SysV4ServController {
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
// 先取每个流程的最新定义,再判断是否启用,避免最新版本停用后回退展示旧版本。
cnd.and("t.state", "=", 1);
if (StrUtil.isNotBlank(keyword)) { if (StrUtil.isNotBlank(keyword)) {
cnd.where().andLike("t.disPlayName", keyword); cnd.where().andLike("t.disPlayName", keyword);
} }
@@ -620,6 +620,27 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
continue; continue;
} }
// 以系统人员档案为准校验男女分组,不能用 Excel 性别绕过限制;校验失败时保留已有报名。
Integer isMenWomen = activityEvent.getIsMenWomen();
if (Integer.valueOf(1).equals(isMenWomen) || Integer.valueOf(2).equals(isMenWomen)) {
String sex = normalizeText(sysUser.getSex());
boolean male = "男".equals(sex) || "男性".equals(sex);
boolean female = "女".equals(sex) || "女性".equals(sex);
String errorMessage = null;
if (!male && !female) {
errorMessage = "系统人员档案性别为空或无法识别,请维护后重新导入";
} else if (Integer.valueOf(1).equals(isMenWomen) && !male) {
errorMessage = "该项目为男子组,系统人员档案性别为女,不能报名";
} else if (Integer.valueOf(2).equals(isMenWomen) && !female) {
errorMessage = "该项目为女子组,系统人员档案性别为男,不能报名";
}
if (errorMessage != null) {
importTemp.setNotes(errorMessage);
errorList.add(importTemp);
continue;
}
}
activitySchoolApply.setEventId(schoolEvent.getEventId()); activitySchoolApply.setEventId(schoolEvent.getEventId());
activitySchoolApply.setAwardsMode(activityEvent.getProjectType()); activitySchoolApply.setAwardsMode(activityEvent.getProjectType());
if ("2".equals(activityEvent.getProjectType())) { if ("2".equals(activityEvent.getProjectType())) {
@@ -101,7 +101,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
if (identity.equals("主任")) { if (identity.equals("主任")) {
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR); sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR);
} else if (identity.equals("成员")) { } else if (identity.equals("委员")) {
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER); sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER);
} }
if (sysRole == null) { if (sysRole == null) {
@@ -148,7 +148,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
if (institutionUser.getIdentity().equals("主任")) { if (institutionUser.getIdentity().equals("主任")) {
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR); sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_DIRECTOR);
} else if (institutionUser.getIdentity().equals("成员")) { } else if (institutionUser.getIdentity().equals("委员")) {
sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER); sysRole = sysRoleService.getByCode(RoleConstant.TEACHER_CONGRESS_PREPARATION_LEADERSHIP_GROUP_MEMBER);
} }
if (sysRole == null) { if (sysRole == null) {
@@ -172,16 +172,16 @@ public class CondolenceReadController {
} }
private void applyReadScope(Cnd cnd, String alias) { private void applyReadScope(Cnd cnd, String alias) {
if (AuthUtil.hasPermission("all_school")) { if (AuthUtil.hasPermission("condolence_all_school")) {
return; return;
} }
if (AuthUtil.hasPermission("branch_union")) { if (AuthUtil.hasPermission("condolence_branch_union")) {
String unionId = SecurityUtil.getUnionId(); String unionId = SecurityUtil.getUnionId();
if (StrUtil.isNotBlank(unionId)) { if (StrUtil.isNotBlank(unionId)) {
cnd.and(alias + ".applyUnionId", "=", unionId); cnd.and(alias + ".applyUnionId", "=", unionId);
return; return;
} }
} else if (AuthUtil.hasPermission("self")) { } else if (AuthUtil.hasPermission("condolence_self")) {
cnd.and(alias + ".createdBy", "=", SecurityUtil.getUserId()); cnd.and(alias + ".createdBy", "=", SecurityUtil.getUserId());
return; return;
} }
@@ -1,10 +1,10 @@
package com.budwk.app.zhgh.staffbenefit.difficulthelp.controller; package com.budwk.app.zhgh.staffbenefit.difficulthelp.controller;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.lang.Dict; import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.annotation.SLog; 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.page.Pagination;
import com.budwk.app.base.result.Result; import com.budwk.app.base.result.Result;
import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.constant.FlowConst;
@@ -112,7 +112,7 @@ public class DifficultHelpApplyController {
@SaCheckPermission("member.apply.submit") @SaCheckPermission("member.apply.submit")
@SLog(tag = "困难补助申请", msg = "保存申请,填写人: ${args[0].proxyUserName}") @SLog(tag = "困难补助申请", msg = "保存申请,填写人: ${args[0].proxyUserName}")
public Result save(@Param("data") DifficultHelpInfo difficultHelpInfo) { public Result save(@Param("data") DifficultHelpInfo difficultHelpInfo) {
difficultHelpCommonService.validateApplyUser(difficultHelpInfo); difficultHelpCommonService.validateApplyUser(difficultHelpInfo, false);
difficultHelpInfo.setApplyTime(ObjectUtil.defaultIfNull(difficultHelpInfo.getApplyTime(), new Date())); difficultHelpInfo.setApplyTime(ObjectUtil.defaultIfNull(difficultHelpInfo.getApplyTime(), new Date()));
difficultHelpCommonService.refreshApplyCount(difficultHelpInfo); difficultHelpCommonService.refreshApplyCount(difficultHelpInfo);
if (difficultHelpCommonService.hasAppliedInYear(difficultHelpInfo.getUserId(), difficultHelpInfo.getApplyTime(), difficultHelpInfo.getId())) { if (difficultHelpCommonService.hasAppliedInYear(difficultHelpInfo.getUserId(), difficultHelpInfo.getApplyTime(), difficultHelpInfo.getId())) {
@@ -177,12 +177,13 @@ public class DifficultHelpApplyController {
@At @At
@ApiOperation("获取受助人") @ApiOperation("获取受助人")
@SaCheckPermission("difficultHelp.apply") @SaCheckPermission(value = {"difficultHelp.apply", "h5.difficultHelp.apply"}, mode = SaMode.OR)
public Result queryRecipients(String key){ public Result queryRecipients(String key){
if (!AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) { boolean schoolScope = AuthUtil.hasPermission("difficult_assistance_school");
return Result.error("只有分工会主席可以替他人申请"); if (!schoolScope && !AuthUtil.hasPermission("difficult_assistance_union")) {
return Result.error("没有代申请权限");
} }
if (Strings.isBlank(SecurityUtil.getUnionId())) { if (!schoolScope && Strings.isBlank(SecurityUtil.getUnionId())) {
return Result.error("当前用户未设置所属分工会"); return Result.error("当前用户未设置所属分工会");
} }
Sql sql = Sqls.create(""" Sql sql = Sqls.create("""
@@ -193,6 +194,10 @@ public class DifficultHelpApplyController {
birthday, birthday,
mobile, mobile,
sex, sex,
idCard,
position,
professionalTitle AS officialCapacity,
(SELECT u.homeAddress FROM sys_user u WHERE u.id = vw_user.id) AS homeAddress,
unitName, unitName,
unionName, unionName,
unionId, unionId,
@@ -203,7 +208,9 @@ public class DifficultHelpApplyController {
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
cnd.and("id", "<>", SecurityUtil.getUserId()); cnd.and("id", "<>", SecurityUtil.getUserId());
cnd.and("unionid", "=", SecurityUtil.getUnionId()); if (!schoolScope) {
cnd.and("unionid", "=", SecurityUtil.getUnionId());
}
if (Strings.isNotBlank(key)) { if (Strings.isNotBlank(key)) {
SqlExpressionGroup group = new SqlExpressionGroup(); SqlExpressionGroup group = new SqlExpressionGroup();
@@ -43,6 +43,7 @@ public class DifficultHelpApprovalController {
} }
ProcessTask task = dao.fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY)); ProcessTask task = dao.fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY));
if (task == null) throw new BaseException("审批任务不存在"); if (task == null) throw new BaseException("审批任务不存在");
boolean actualAmountApproval = "e405f96c-5fc0-4f63-b323-e69dfe853253".equals(task.getTaskName());
boolean amountApproval = "715ece82-4ae3-433c-ad18-ed875f45d1e3".equals(task.getTaskName()); boolean amountApproval = "715ece82-4ae3-433c-ad18-ed875f45d1e3".equals(task.getTaskName());
if (!amountApproval && !"36ebafda-44c2-4bd3-bd7f-10839a575a0d".equals(task.getTaskName()) if (!amountApproval && !"36ebafda-44c2-4bd3-bd7f-10839a575a0d".equals(task.getTaskName())
&& !"e405f96c-5fc0-4f63-b323-e69dfe853253".equals(task.getTaskName())) { && !"e405f96c-5fc0-4f63-b323-e69dfe853253".equals(task.getTaskName())) {
@@ -56,6 +57,7 @@ public class DifficultHelpApprovalController {
args.remove("level"); args.remove("level");
args.remove("tf_level"); args.remove("tf_level");
args.remove("tf_actualMoney");
Double money = amountApproval ? args.getDouble("money") : null; Double money = amountApproval ? args.getDouble("money") : null;
if (amountApproval) { if (amountApproval) {
if (money == null || !Double.isFinite(money) || money < 0) { if (money == null || !Double.isFinite(money) || money < 0) {
@@ -65,6 +67,10 @@ public class DifficultHelpApprovalController {
} else { } else {
args.remove("money"); args.remove("money");
args.remove("tf_money"); args.remove("tf_money");
if (actualAmountApproval && info.getMoney() != null) {
args.put("tf_money", info.getMoney());
args.put("tf_actualMoney", info.getMoney());
}
} }
// 参与者权限由流程引擎校验,业务入口不接受客户端指定管理员代办。 // 参与者权限由流程引擎校验,业务入口不接受客户端指定管理员代办。
args.remove(FlowConst.EXT_ENABLE_OPERATOR); args.remove(FlowConst.EXT_ENABLE_OPERATOR);
@@ -78,6 +78,7 @@ public class DifficultHelpFirstApprovalController {
info.subsidyStandards, info.subsidyStandards,
LEFT(info.applyTime, 10) AS applyTime, LEFT(info.applyTime, 10) AS applyTime,
info.applyCount, info.applyCount,
info.applyMoney,
info.mobile, info.mobile,
ins.id AS instanceId, ins.id AS instanceId,
ins.businessNo, ins.businessNo,
@@ -2,7 +2,6 @@ package com.budwk.app.zhgh.staffbenefit.difficulthelp.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckLogin; import cn.dev33.satoken.annotation.SaCheckLogin;
@@ -10,7 +9,6 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel; import com.alibaba.excel.EasyExcel;
import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination; import com.budwk.app.base.page.Pagination;
@@ -154,7 +152,7 @@ public class DifficultHelpReadingController {
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
cnd.and("ins.state", "=", 20); cnd.and("ins.state", "=", 20);
pageParam.buildSearch(cnd, "info.", false); pageParam.buildReadingSearch(cnd, "info.");
cnd.groupBy("info.id"); cnd.groupBy("info.id");
sql.setCondition(cnd); sql.setCondition(cnd);
Pagination<NutMap> pagination = difficultHelpCommonService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql); Pagination<NutMap> pagination = difficultHelpCommonService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
@@ -269,7 +267,7 @@ public class DifficultHelpReadingController {
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.", false); pageParam.buildReadingSearch(cnd, "info.");
cnd.groupBy("info.id"); cnd.groupBy("info.id");
sql.setCondition(cnd); sql.setCondition(cnd);
List<NutMap> list = difficultHelpCommonService.listMap(sql); List<NutMap> list = difficultHelpCommonService.listMap(sql);
@@ -282,42 +280,14 @@ public class DifficultHelpReadingController {
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
NutMap record = list.get(i); NutMap record = list.get(i);
HashMap<String, Object> docData = new HashMap<>(); DifficultHelpInfo difficultHelp = difficultHelpCommonService.fetch(record.getString("id"));
docData.put("unionName", record.getString("unitName")); if (difficultHelp == null) {
docData.put("proxyUserName", record.getString("proxyUserName")); throw new IllegalStateException("待导出的申请记录不存在:" + record.getString("id"));
docData.put("sex", record.getString("sex"));
docData.put("loginName", record.getString("loginName"));
docData.put("unitName", record.getString("unitName"));
docData.put("homeIncome", record.getDouble("homeIncome"));
docData.put("homeNumber", record.getInt("homeNumber"));
docData.put("position", record.getString("position"));
docData.put("officialCapacity", record.getString("officialCapacity"));
docData.put("mobile", record.getString("mobile"));
docData.put("userName", record.getString("userName"));
docData.put("homeAddress", record.getString("homeAddress"));
docData.put("bankOfDeposit", record.getString("bankOfDeposit"));
docData.put("bankCardNum", record.getString("bankCardNum"));
docData.put("reason", record.getString("reason"));
docData.put("applyTime", DateUtil.format(DateUtil.parse(record.getString("applyTime")), "yyyy年MM月dd日"));
docData.put("schoolname", "中国地质大学(武汉)");
docData.put("year", DateUtil.format(DateUtil.parse(record.getString("applyTime")), "yyyy"));
String familyListStr = record.getString("familyList");
if (StrUtil.isNotBlank(familyListStr)) {
docData.put("familyList", JSONUtil.toList(familyListStr, Object.class));
} else {
docData.put("familyList", new ArrayList<>());
} }
byte[] bytes = renderApplyDocument(difficultHelp, false);
String fileName = (i + 1) + record.getString("userName") + "申请表.docx"; String fileName = (i + 1) + difficultHelp.getUserName() + "申请表.docx";
zipOutputStream.putNextEntry(new ZipEntry(fileName)); zipOutputStream.putNextEntry(new ZipEntry(fileName));
zipOutputStream.write(bytes);
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
Configure config = Configure.builder().bind("familyList", policy).build();
try (InputStream input = sysOfficeTemplateUtil.getTemplate("difficulty_apply")) {
zipOutputStream.write(sysOfficeTemplateUtil.renderTemplate(input, docData, config, false, "difficulthelp:batch:" + record.getString("id")));
}
zipOutputStream.closeEntry(); zipOutputStream.closeEntry();
} }
zipOutputStream.flush(); zipOutputStream.flush();
@@ -327,11 +297,41 @@ public class DifficultHelpReadingController {
@At @At
@Ok("void") @Ok("void")
@SaCheckPermission("difficultHelp.reading")
public void exportReadingApply(String id, DifficultHelpPageParam pageParam, HttpServletResponse response, Boolean print) throws Exception {
Cnd cnd = Cnd.where("id", "=", id);
pageParam.buildReadingSearch(cnd, "");
if (difficultHelpCommonService.count(cnd) == 0) {
throw new RuntimeException("该记录不在当前可查看的范围内,无法导出");
}
doExportApply(id, response, print);
}
@At
@Ok("void")
@SaCheckLogin
public void doExportApply(String id, HttpServletResponse response, Boolean print) throws Exception { public void doExportApply(String id, HttpServletResponse response, Boolean print) throws Exception {
DifficultHelpInfo difficultHelp = difficultHelpCommonService.fetch(id); DifficultHelpInfo difficultHelp = difficultHelpCommonService.fetch(id);
if (difficultHelp == null) { if (difficultHelp == null) {
throw new RuntimeException("该条记录不存在"); throw new RuntimeException("该条记录不存在");
} }
boolean ownApply = AuthUtil.hasPermission("difficultHelp.mine")
&& SecurityUtil.getUserId().equals(difficultHelp.getCreatedBy());
if (!ownApply) {
Cnd cnd = Cnd.where("id", "=", id);
new DifficultHelpPageParam().buildReadingSearch(cnd, "");
if (!AuthUtil.hasPermission("difficultHelp.reading") || difficultHelpCommonService.count(cnd) == 0) {
throw new RuntimeException("该记录不在当前可查看的范围内,无法导出");
}
}
boolean pdf = Boolean.TRUE.equals(print);
String fileName = FileUtil.mainName(sysOfficeTemplateUtil.getTemplateFileName("difficulty_apply")) + "_" + difficultHelp.getUserName() + "_" +
DateUtil.format(difficultHelp.getApplyTime(), "yyyyMMdd") + (pdf ? ".pdf" : ".docx");
byte[] bytes = renderApplyDocument(difficultHelp, pdf);
CommonDownloadUtil.download(fileName, bytes, response);
}
private byte[] renderApplyDocument(DifficultHelpInfo difficultHelp, boolean pdf) throws Exception {
HashMap<String, Object> docData = new HashMap<>(); HashMap<String, Object> docData = new HashMap<>();
docData.put("unionName", difficultHelp.getUnitName()); docData.put("unionName", difficultHelp.getUnitName());
@@ -364,10 +364,8 @@ public class DifficultHelpReadingController {
docData.put("applyMoney", difficultHelp.getApplyMoney()); docData.put("applyMoney", difficultHelp.getApplyMoney());
docData.put("money", difficultHelp.getMoney()); docData.put("money", difficultHelp.getMoney());
fillApplyApprovals(docData, difficultHelp.getId()); fillApplyApprovals(docData, difficultHelp.getId());
if (print) { try (InputStream input = getApplyTemplate(templateName)) {
exportAsPDF(templateName, docData, config, difficultHelp, response); return sysOfficeTemplateUtil.renderTemplate(input, docData, config, pdf, "difficulthelp:" + difficultHelp.getId());
} else {
exportAsWord(templateName, docData, config, difficultHelp,response);
} }
} }
@@ -444,30 +442,6 @@ public class DifficultHelpReadingController {
return new ByteArrayInputStream(templateBytes); return new ByteArrayInputStream(templateBytes);
} }
@At
private void exportAsPDF(String templateName, HashMap<String, Object> docData,Configure config,
DifficultHelpInfo difficultHelp, HttpServletResponse response) throws Exception {
String fileName = FileUtil.mainName(sysOfficeTemplateUtil.getTemplateFileName(templateName)) + "_" + difficultHelp.getUserName() + "_" +
DateUtil.format(difficultHelp.getApplyTime(), "yyyyMMdd") + ".pdf";
try (InputStream input = getApplyTemplate(templateName)) {
byte[] bytes = sysOfficeTemplateUtil.renderTemplate(input, docData, config, true, "difficulthelp:" + difficultHelp.getId());
CommonDownloadUtil.download(fileName, bytes, response);
}
}
@At
private void exportAsWord(String templateName, HashMap<String, Object> docData,Configure config,
DifficultHelpInfo difficultHelp, HttpServletResponse response) throws Exception {
String fileName = FileUtil.mainName(sysOfficeTemplateUtil.getTemplateFileName(templateName)) + "_" + difficultHelp.getUserName() + "_" +
DateUtil.format(difficultHelp.getApplyTime(), "yyyyMMdd") + ".docx";
try (InputStream input = getApplyTemplate(templateName)) {
byte[] bytes = sysOfficeTemplateUtil.renderTemplate(input, docData, config, false, "difficulthelp:" + difficultHelp.getId());
CommonDownloadUtil.download(fileName, bytes, response);
}
}
@At @At
@Ok("void") @Ok("void")
@SaCheckPermission("difficultHelp.reading") @SaCheckPermission("difficultHelp.reading")
@@ -493,6 +467,7 @@ public class DifficultHelpReadingController {
info.subsidyStandards, info.subsidyStandards,
info.bankOfDeposit, info.bankOfDeposit,
info.bankCardNum, info.bankCardNum,
info.money,
info.applyCount info.applyCount
FROM FROM
difficult_help_info info difficult_help_info info
@@ -500,16 +475,44 @@ public class DifficultHelpReadingController {
$condition $condition
"""); """);
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.", false); pageParam.buildReadingSearch(cnd, "info.");
cnd.groupBy("info.id"); cnd.groupBy("info.id");
sql.setCondition(cnd); sql.setCondition(cnd);
List<NutMap> list = difficultHelpCommonService.listMap(sql); List<NutMap> list = difficultHelpCommonService.listMap(sql);
Sys_user user = sysUserService.fetch(SecurityUtil.getUserId());
for (int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
list.get(i).put("index", (i + 1)); list.get(i).put("index", (i + 1));
} }
String fileName = "困难慰问汇总表_" + DateUtil.format(new Date(), "yyyyMMdd");
if ("xlsx".equals(flag)) {
String[][] columns = {
{"序号", "index"}, {"姓名", "userName"}, {"工号", "loginName"},
{"性别", "sex"}, {"身份证号", "idCard"}, {"年龄", "age"},
{"职务", "position"}, {"职称", "officialCapacity"}, {"所属单位", "unitName"},
{"手机号码", "mobile"}, {"生活致困原因", "reason"}, {"级别", "level"},
{"家庭年总收入", "homeIncome"}, {"家庭人数", "homeNumber"},
{"困难类型", "subsidyStandards"}, {"开户行", "bankOfDeposit"},
{"银行卡号", "bankCardNum"}, {"实际金额(元)", "money"}, {"申请次数", "applyCount"}
};
List<ExcelExportEntity> entities = new ArrayList<>();
for (String[] column : columns) {
entities.add(new ExcelExportEntity(column[0], column[1], 20));
}
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
exportParams.setTitle("困难帮扶汇总表");
exportParams.setSheetName("汇总数据");
try (Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list)) {
CommonDownloadUtil.download(fileName + ".xlsx", workbook, response);
} catch (Exception e) {
log.error("导出Excel汇总表失败", e);
throw new RuntimeException("导出Excel汇总表失败:" + e.getMessage(), e);
}
return;
}
Sys_user user = sysUserService.fetch(SecurityUtil.getUserId());
result.put("schoolName", "中国地址大学(武汉)"); result.put("schoolName", "中国地址大学(武汉)");
result.put("year", DateUtil.format(new Date(), "yyyy")); result.put("year", DateUtil.format(new Date(), "yyyy"));
result.put("applyTime", DateUtil.format(new Date(), "yyyy年MM月dd日")); result.put("applyTime", DateUtil.format(new Date(), "yyyy年MM月dd日"));
@@ -517,32 +520,12 @@ public class DifficultHelpReadingController {
result.put("mobile", user.getMobile()); result.put("mobile", user.getMobile());
result.put("da", list); result.put("da", list);
String resource; String resource = "difficulty_summary";
if ("xlsx".equals(flag)) { if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
resource = "difficulty_summary_xlsx"; resource = "difficulty_summary_school";
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
resource = "difficulty_summary_school_xlsx";
}
} else {
resource = "difficulty_summary";
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
resource = "difficulty_summary_school";
}
} }
String fileName = "困难慰问汇总表_" + DateUtil.format(new Date(), "yyyyMMdd"); if ("docx".equals(flag)) {
if ("xlsx".equals(flag)) {
try {
InputStream is = sysOfficeTemplateUtil.getTemplate(resource);
TemplateExportParams exportParams = new TemplateExportParams(is, null);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, result);
CommonDownloadUtil.download(fileName + ".xlsx", workbook, response);
} catch (Exception e) {
log.error("导出Excel汇总表失败", e);
throw new RuntimeException("导出Excel汇总表失败:" + e.getMessage());
}
} else if ("docx".equals(flag)) {
try (InputStream input = sysOfficeTemplateUtil.getTemplate(resource)) { try (InputStream input = sysOfficeTemplateUtil.getTemplate(resource)) {
Configure config = Configure.builder() Configure config = Configure.builder()
.bind("da", new LoopRowTableRenderPolicy()) .bind("da", new LoopRowTableRenderPolicy())
@@ -79,6 +79,7 @@ public class DifficultHelpSecondApprovalController {
info.subsidyStandards, info.subsidyStandards,
LEFT(info.applyTime, 10) AS applyTime, LEFT(info.applyTime, 10) AS applyTime,
info.applyCount, info.applyCount,
info.applyMoney,
info.mobile, info.mobile,
ins.id AS instanceId, ins.id AS instanceId,
ins.businessNo, ins.businessNo,
@@ -82,6 +82,8 @@ public class DifficultHelpThirdApprovalController {
info.subsidyStandards, info.subsidyStandards,
LEFT(info.applyTime, 10) AS applyTime, LEFT(info.applyTime, 10) AS applyTime,
info.applyCount, info.applyCount,
info.applyMoney,
info.money,
info.mobile, info.mobile,
ins.id AS instanceId, ins.id AS instanceId,
ins.businessNo, ins.businessNo,
@@ -21,6 +21,8 @@ public interface DifficultHelpCommonService extends BaseService<DifficultHelpInf
void validateApplyUser(DifficultHelpInfo difficultHelpInfo); void validateApplyUser(DifficultHelpInfo difficultHelpInfo);
void validateApplyUser(DifficultHelpInfo difficultHelpInfo, boolean requireApplyMoney);
/** /**
* 导入实际金额数据处理 * 导入实际金额数据处理
* @param file 文件 * @param file 文件
@@ -4,7 +4,6 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil; import cn.hutool.json.JSONUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl; import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.exception.BaseException; import com.budwk.app.base.exception.BaseException;
import com.budwk.app.web.commons.auth.utils.AuthUtil; import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil; import com.budwk.app.web.commons.auth.utils.SecurityUtil;
@@ -56,6 +55,11 @@ public class DifficultHelpCommonServiceImpl extends BaseServiceImpl<DifficultHel
@Override @Override
public void validateApplyUser(DifficultHelpInfo difficultHelpInfo) { public void validateApplyUser(DifficultHelpInfo difficultHelpInfo) {
validateApplyUser(difficultHelpInfo, true);
}
@Override
public void validateApplyUser(DifficultHelpInfo difficultHelpInfo, boolean requireApplyMoney) {
if (difficultHelpInfo == null || StrUtil.isBlank(difficultHelpInfo.getUserId())) { if (difficultHelpInfo == null || StrUtil.isBlank(difficultHelpInfo.getUserId())) {
throw new BaseException("请选择受助人"); throw new BaseException("请选择受助人");
} }
@@ -65,19 +69,29 @@ public class DifficultHelpCommonServiceImpl extends BaseServiceImpl<DifficultHel
throw new BaseException("只能查看他人代为申请的记录,不能修改或提交"); throw new BaseException("只能查看他人代为申请的记录,不能修改或提交");
} }
} }
if (difficultHelpInfo.getApplyMoney() == null || !Double.isFinite(difficultHelpInfo.getApplyMoney()) if ((requireApplyMoney || difficultHelpInfo.getApplyMoney() != null)
|| difficultHelpInfo.getApplyMoney() <= 0) { && (difficultHelpInfo.getApplyMoney() == null || !Double.isFinite(difficultHelpInfo.getApplyMoney())
|| difficultHelpInfo.getApplyMoney() <= 0)) {
throw new BaseException("请填写大于零的申请金额"); throw new BaseException("请填写大于零的申请金额");
} }
if (difficultHelpInfo.getUserId().equals(SecurityUtil.getUserId())) { if (difficultHelpInfo.getUserId().equals(SecurityUtil.getUserId())) {
if (!AuthUtil.hasPermission("difficult_assistance_self")
&& !AuthUtil.hasPermission("difficult_assistance_school")
&& !AuthUtil.hasPermission("difficult_assistance_union")) {
throw new BaseException("没有帮扶申请权限");
}
return; return;
} }
if (!AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) { boolean schoolScope = AuthUtil.hasPermission("difficult_assistance_school");
throw new BaseException("只有分工会主席可以替他人申请"); if (!schoolScope && !AuthUtil.hasPermission("difficult_assistance_union")) {
throw new BaseException("没有代申请权限");
} }
View_user recipient = dao().fetch(View_user.class, Cnd.where("id", "=", difficultHelpInfo.getUserId())); View_user recipient = dao().fetch(View_user.class, Cnd.where("id", "=", difficultHelpInfo.getUserId()));
if (recipient == null || StrUtil.isBlank(SecurityUtil.getUnionId()) if (recipient == null) {
|| !SecurityUtil.getUnionId().equals(recipient.getUnionId())) { throw new BaseException("受助人不存在");
}
if (!schoolScope && (StrUtil.isBlank(SecurityUtil.getUnionId())
|| !SecurityUtil.getUnionId().equals(recipient.getUnionId()))) {
throw new BaseException("只能替本分工会人员申请"); throw new BaseException("只能替本分工会人员申请");
} }
} }
@@ -123,10 +137,7 @@ public class DifficultHelpCommonServiceImpl extends BaseServiceImpl<DifficultHel
// 2. 查询符合条件的 DifficultHelpInfo 记录 // 2. 查询符合条件的 DifficultHelpInfo 记录
Cnd cnd = Cnd.NEW(); Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) { pageForm.buildReadingSearch(cnd, "");
cnd.and(Cnd.exps("loginName", "LIKE", "%" + pageForm.getSearchKeyword() + "%")
.or("userName", "LIKE", "%" + pageForm.getSearchKeyword() + "%"));
}
List<DifficultHelpInfo> infoList = dao().query(DifficultHelpInfo.class, cnd); List<DifficultHelpInfo> infoList = dao().query(DifficultHelpInfo.class, cnd);
// 3. 构建用户缴费索引 (userId -> year -> money) // 3. 构建用户缴费索引 (userId -> year -> money)
@@ -9,6 +9,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.util.cri.SqlExpressionGroup; import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static;
import org.nutz.lang.Lang; import org.nutz.lang.Lang;
import java.util.List; import java.util.List;
@@ -32,6 +33,29 @@ public class DifficultHelpPageParam extends PageForm {
private List<String> dateRange; private List<String> dateRange;
public void buildReadingSearch(Cnd cnd, String prefix) {
buildSearch(cnd, prefix, false);
applyReadingScope(cnd, prefix);
String recordPrefix = StrUtil.isBlank(prefix) ? "difficult_help_info." : prefix;
cnd.and(new Static("EXISTS (SELECT 1 FROM wf_process_instance reading_instance WHERE reading_instance.businessNo = "
+ recordPrefix + "id AND reading_instance.state = 20)"));
}
public void applyReadingScope(Cnd cnd, String prefix) {
if (AuthUtil.hasPermission("difficult_all_school")) {
return;
}
if (AuthUtil.hasPermission("difficult_branch_union") && StrUtil.isNotBlank(SecurityUtil.getUnionId())) {
cnd.and(prefix + "unionId", "=", SecurityUtil.getUnionId());
return;
}
if (AuthUtil.hasPermission("difficult_self") && StrUtil.isNotBlank(SecurityUtil.getUserId())) {
cnd.and(prefix + "userId", "=", SecurityUtil.getUserId());
return;
}
cnd.and("1", "=", 0);
}
public void buildSearch(Cnd cnd, String prefix){ public void buildSearch(Cnd cnd, String prefix){
buildSearch(cnd, prefix, true); buildSearch(cnd, prefix, true);
} }
@@ -1,6 +1,5 @@
package com.budwk.app.zhgh.welfare.service.impl; package com.budwk.app.zhgh.welfare.service.impl;
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
@@ -23,8 +22,12 @@ import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm; import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService; import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.nutz.dao.Cnd; import org.nutz.dao.Cnd;
import org.nutz.dao.Dao; import org.nutz.dao.Dao;
import org.nutz.dao.Sqls; import org.nutz.dao.Sqls;
@@ -246,7 +249,8 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
byte[] userSignBytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath()); byte[] userSignBytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath());
map.put("userSign", userSignBytes); map.put("userSign", userSignBytes);
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); // 下载失败时不把原文件地址写入签字单元格。
map.put("userSign", null);
log.error("下载图片失败", e); log.error("下载图片失败", e);
} }
} }
@@ -268,21 +272,66 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
optionList.forEach(option -> { optionList.forEach(option -> {
entities.add(new ExcelExportEntity(option.getOptionName(), option.getOptionName(), 20)); entities.add(new ExcelExportEntity(option.getOptionName(), option.getOptionName(), 20));
}); });
// 签字列先按空白文本导出,图片另行写入,避开 EasyPOI 对 Map 图片字段的反射。
ExcelExportEntity userSignEntity = new ExcelExportEntity("签字", "userSign", 20); ExcelExportEntity userSignEntity = new ExcelExportEntity("签字", "userSign", 20);
userSignEntity.setType(2);
userSignEntity.setExportImageType(2);
entities.add(userSignEntity); entities.add(userSignEntity);
// 导出 // 导出
Workbook workbook = new HSSFWorkbook(); Workbook workbook = new XSSFWorkbook();
listMap.forEach((k, v) -> { listMap.forEach((k, v) -> {
List<byte[]> signatures = new ArrayList<>();
v.forEach(row -> {
Object signature = row.remove("userSign");
signatures.add(signature instanceof byte[] ? (byte[]) signature : null);
});
ExcelExportService service = new ExcelExportService(); ExcelExportService service = new ExcelExportService();
ExportParams exportParams = new ExportParams(); ExportParams exportParams = new ExportParams();
exportParams.setSheetName(k); exportParams.setSheetName(k);
exportParams.setType(ExcelType.HSSF); exportParams.setType(ExcelType.XSSF);
int firstSheet = workbook.getNumberOfSheets();
service.createSheetForMap(workbook, exportParams, entities, v); service.createSheetForMap(workbook, exportParams, entities, v);
// 无标题、单层列头的数据从第二行开始;按新增 Sheet 顺序兼容 EasyPOI 自动拆表。
int signatureIndex = 0;
for (int sheetIndex = firstSheet; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {
Sheet sheet = workbook.getSheetAt(sheetIndex);
Drawing<?> drawing = sheet.createDrawingPatriarch();
for (int rowIndex = 1; rowIndex <= sheet.getLastRowNum() && signatureIndex < signatures.size(); rowIndex++) {
byte[] signature = signatures.get(signatureIndex++);
if (signature != null && signature.length > 0) {
insertReceiveSignature(workbook, sheet, drawing, rowIndex, entities.size() - 1, signature);
}
}
}
}); });
CommonDownloadUtil.download("领取表.xls", workbook, response); CommonDownloadUtil.download("领取表.xlsx", workbook, response);
}
/**
* 将签字字节数组写入领取表指定单元格。行列索引从 0 开始,图片统一转为 PNG;
* 无法解码的图片仅记录日志并保留空白签字格,不中断其他人员的导出。
*/
private void insertReceiveSignature(Workbook workbook, Sheet sheet, Drawing<?> drawing,
int rowIndex, int columnIndex, byte[] signature) {
try (ByteArrayInputStream input = new ByteArrayInputStream(signature);
ByteArrayOutputStream output = new ByteArrayOutputStream()) {
BufferedImage image = ImageIO.read(input);
if (image == null) {
log.warn("领取表签字图片无法识别,Sheet={},行={}", sheet.getSheetName(), rowIndex + 1);
return;
}
ImageIO.write(image, "png", output);
Row row = sheet.getRow(rowIndex);
row.setHeightInPoints(Math.max(row.getHeightInPoints(), 50));
ClientAnchor anchor = workbook.getCreationHelper().createClientAnchor();
anchor.setCol1(columnIndex);
anchor.setCol2(columnIndex + 1);
anchor.setRow1(rowIndex);
anchor.setRow2(rowIndex + 1);
anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
drawing.createPicture(anchor, workbook.addPicture(output.toByteArray(), Workbook.PICTURE_TYPE_PNG));
} catch (Exception e) {
log.error("领取表签字图片写入失败,Sheet={},行={}", sheet.getSheetName(), rowIndex + 1, e);
}
} }
} }
+3 -3
View File
@@ -5,7 +5,7 @@ nutz:
ignore: ^(.+[.])(jsp|png|gif|jpg|js|css|jspx|jpeg|html|mp3|mp4|ico|svg|vue)$ ignore: ^(.+[.])(jsp|png|gif|jpg|js|css|jspx|jpeg|html|mp3|mp4|ico|svg|vue)$
exclusions: /favicon/*,/assets/*,/druid/*,/upload/*,/components/* exclusions: /favicon/*,/assets/*,/druid/*,/upload/*,/components/*
server: server:
port: 8081 port: 80
host: 0.0.0.0 host: 0.0.0.0
jetty: jetty:
@@ -21,7 +21,7 @@ jetty:
#结合ftp使用,或用nginx代理ftp路径 #结合ftp使用,或用nginx代理ftp路径
#staticPath: /Users/wizzer/temp/files #staticPath: /Users/wizzer/temp/files
#开发模式静态资源 #开发模式静态资源
staticPathLocal: D:/myProject/zhgh_cqgmy/src/main/resources/static staticPathLocal: E:/projects/zhgh_cqgmy/src/main/resources/static
security: security:
tokenName: saToken tokenName: saToken
@@ -87,7 +87,7 @@ xsssql:
beetl: beetl:
RESOURCE: RESOURCE:
#本地路径,开发时设置本地路径,便于调试 #本地路径,开发时设置本地路径,便于调试
rootLocal: D:/myProject/zhgh_cqgmy/src/main/resources/views/ rootLocal: E:/projects/zhgh_cqgmy/src/main/resources/views/
root: views/ root: views/
DELIMITER_STATEMENT_START: "<!--#" DELIMITER_STATEMENT_START: "<!--#"
DELIMITER_STATEMENT_END: "#-->" DELIMITER_STATEMENT_END: "#-->"
@@ -124,7 +124,10 @@
#v4-home-app .todo-center .el-tabs__nav { display: flex; width: 100%; border-color: #e9eff6; border-radius: 6px 6px 0 0; } #v4-home-app .todo-center .el-tabs__nav { display: flex; width: 100%; border-color: #e9eff6; border-radius: 6px 6px 0 0; }
#v4-home-app .todo-center .el-tabs__item { flex: 1; min-width: 0; padding: 0 7px; font-size: 12px; height: 36px; line-height: 36px; text-align: center; } #v4-home-app .todo-center .el-tabs__item { flex: 1; min-width: 0; padding: 0 7px; font-size: 12px; height: 36px; line-height: 36px; text-align: center; }
#v4-home-app .todo-center .el-tabs__item.is-active { border-bottom: 2px solid #1687f5; color: #1687f5; } #v4-home-app .todo-center .el-tabs__item.is-active { border-bottom: 2px solid #1687f5; color: #1687f5; }
#v4-home-app .portal-task-list { display: flex; flex-direction: column; justify-content: space-evenly; flex: 1; min-height: 180px; } /* 任务从标签栏下方依次排列,避免单条记录被剩余高度推到中间。 */
#v4-home-app .portal-task-list { display: flex; flex-direction: column; justify-content: flex-start; flex: 1; min-height: 180px; }
/* 空数据提示独立占满列表区域,保留居中展示。 */
#v4-home-app .portal-task-list > .portal-empty { flex: 1; }
#v4-home-app .portal-task-row { display: flex; gap: 10px; align-items: center; padding: 8px 6px; border-bottom: 1px solid #eef3f8; } #v4-home-app .portal-task-row { display: flex; gap: 10px; align-items: center; padding: 8px 6px; border-bottom: 1px solid #eef3f8; }
#v4-home-app .portal-task-row:last-child { border-bottom: 0; } #v4-home-app .portal-task-row:last-child { border-bottom: 0; }
#v4-home-app .portal-task-row:hover { background: #f7fbff; } #v4-home-app .portal-task-row:hover { background: #f7fbff; }
@@ -11,25 +11,25 @@
$.ajaxSetup({ $.ajaxSetup({
contentType: "application/x-www-form-urlencoded;charset=utf-8", contentType: "application/x-www-form-urlencoded;charset=utf-8",
success: function (response, textStatus, jqXHR) { success: function (response, textStatus, jqXHR) {
if (response.code !== 0) { if (response && typeof response === "object" && response.code !== undefined && response.code !== 0) {
this.$message.error(response.msg) Vue.prototype.$message.error(response.msg)
} else { } else {
return response return response
} }
}, },
error: function (v1) { error: function (v1) {
this.$message.error(v1.status + " " + v1.statusText) Vue.prototype.$message.error(v1.status + " " + v1.statusText)
}, },
complete: function (XMLHttpRequest, textStatus) { complete: function (XMLHttpRequest, textStatus) {
var sessionstatus = XMLHttpRequest.getResponseHeader("loginStatus") //通过XMLHttpRequest取得响应头,sessionstatus, var sessionstatus = XMLHttpRequest.getResponseHeader("loginStatus") //通过XMLHttpRequest取得响应头,sessionstatus,
if (sessionstatus == "accessDenied") { if (sessionstatus == "accessDenied") {
this.$message({ Vue.prototype.$message({
message: "\u767b\u5f55\u5931\u6548\uff0c\u8bf7\u5237\u65b0\u9875\u9762\u91cd\u65b0\u767b\u5f55", message: "\u767b\u5f55\u5931\u6548\uff0c\u8bf7\u5237\u65b0\u9875\u9762\u91cd\u65b0\u767b\u5f55",
type: "error" type: "error"
}) })
} }
if (sessionstatus == "unauthorized") { if (sessionstatus == "unauthorized") {
this.$message({ Vue.prototype.$message({
message: "\u6ca1\u6709\u6743\u9650", message: "\u6ca1\u6709\u6743\u9650",
type: "error" type: "error"
}) })
@@ -4,7 +4,7 @@
<div style="padding: 0px 16px" class="clearfix"> <div style="padding: 0px 16px" class="clearfix">
<el-button icon="el-icon-back" style="font-size: 16px" type="text" @click="userScopeDialog = false">返回</el-button> <el-button icon="el-icon-back" style="font-size: 16px" type="text" @click="userScopeDialog = false">返回</el-button>
</div> </div>
<el-tabs tab-position="top" v-model="activeName" @tab-click="handleClick" style="margin: 20px"> <el-tabs tab-position="top" v-model="activeName" @tab-click="handleClick" :before-leave="beforeTabLeave" style="margin: 20px">
<el-tab-pane label="人员设置" name="1"> <el-tab-pane label="人员设置" name="1">
<template> <template>
<user-scope ref="userScope" @group_change="group_change" :group_id.sync="groupId"></user-scope> <user-scope ref="userScope" @group_change="group_change" :group_id.sync="groupId"></user-scope>
@@ -12,7 +12,7 @@
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="人员调整" name="2"> <el-tab-pane label="人员调整" name="2">
<user-data-scope @group_change="group_change" ref="userDataScope"></user-data-scope> <user-data-scope v-if="activeName === '2'" @group_change="group_change" ref="userDataScope"></user-data-scope>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-drawer> </el-drawer>
@@ -32,9 +32,19 @@ module.exports = {
} }
}, },
methods: { methods: {
beforeTabLeave(name) {
const permission = name === "2" ? "activity.basic.user" : "activity.basic.scope"
if (!this.$auth.hasRole("SYSADMIN") && !this.$auth.hasPermission(permission)) {
this.$message.error("无此权限:" + permission)
return false
}
return true
},
handleClick() { handleClick() {
if (this.activeName === "2") { if (this.activeName === "2") {
this.$refs.userDataScope.getActivityGroup() if (this.$refs.userDataScope) {
this.$refs.userDataScope.getActivityGroup()
}
} else { } else {
this.$refs.userScope.getActivityGroup() this.$refs.userScope.getActivityGroup()
} }
@@ -680,6 +680,10 @@ module.exports = {
} }
}, },
doSetActivityUser() { doSetActivityUser() {
if (!this.$auth.hasRole("SYSADMIN") && !this.$auth.hasPermission("activity.basic.scope")) {
this.$message.error("无此权限:activity.basic.scope")
return
}
// 方法级状态保护与整页遮罩共同阻止慢请求期间的重复确认。 // 方法级状态保护与整页遮罩共同阻止慢请求期间的重复确认。
if (this.settingLoading) { if (this.settingLoading) {
return return
@@ -711,11 +715,15 @@ module.exports = {
spinner: "el-icon-loading", spinner: "el-icon-loading",
background: "rgba(255, 255, 255, 0.65)" background: "rgba(255, 255, 255, 0.65)"
}) })
const pageForm = this.normalizePageForm(this.pageForm) Promise.resolve().then(() => {
Object.assign(pageForm, this.formData) const pageForm = this.normalizePageForm(this.pageForm)
Object.assign(pageForm, this.formData)
$.post("/platform/activity/basic/scope/doSetActivityUser", { return $.ajax({
data: JSON.stringify(pageForm) url: "/platform/activity/basic/scope/doSetActivityUser",
type: "POST",
data: { data: JSON.stringify(pageForm) },
success: () => {}
})
}).then((resp) => { }).then((resp) => {
if (resp.code !== 0) { if (resp.code !== 0) {
// 将后端业务错误转入统一失败分支,直接展示接口返回的真实原因。 // 将后端业务错误转入统一失败分支,直接展示接口返回的真实原因。
@@ -741,7 +749,7 @@ module.exports = {
? error.message ? error.message
: "设置活动人员失败" : "设置活动人员失败"
this.$message.error(errorMessage) this.$message.error(errorMessage)
}).always(() => { }).finally(() => {
this.settingLoading = false this.settingLoading = false
loading.close() loading.close()
}) })
@@ -25,10 +25,7 @@ module.exports = {
watch: { watch: {
value: { value: {
handler(val) { handler(val) {
if (val) { this.signatureContent = val || null
this.signatureContent = val
this.$emit("input", this.signatureContent)
}
}, },
immediate: true immediate: true
} }
@@ -62,8 +59,11 @@ module.exports = {
if (res.code !== 0) { if (res.code !== 0) {
throw new Error("签字信息加载失败") throw new Error("签字信息加载失败")
} }
this.signatureContent = res.data && res.data.signature // 已保存的业务签字或刚收到的扫码签字优先,默认签名仅补充空值。
this.$emit("input", this.signatureContent) if (!this.value && !this.signatureContent && res.data && res.data.signature) {
this.signatureContent = res.data.signature
this.$emit("input", this.signatureContent)
}
}) })
}, },
// 返回等待完成的 Promise;连接成功、等待30秒或组件销毁时结束等待。 // 返回等待完成的 Promise;连接成功、等待30秒或组件销毁时结束等待。
@@ -181,7 +181,7 @@ layout("/layouts/v4/baseLayout.html"){
</style> </style>
<link rel="stylesheet" href="${base!}/assets/platform/css/home-portal.css?v=20261030-1" /> <link rel="stylesheet" href="${base!}/assets/platform/css/home-portal.css?v=20261102-1" />
<!-- 登录资料仅在 HTML 属性中输出并转义;放在 Vue 挂载区域外,避免名称被当作模板表达式解析。 --> <!-- 登录资料仅在 HTML 属性中输出并转义;放在 Vue 挂载区域外,避免名称被当作模板表达式解析。 -->
<div id="v4-home-profile-data" hidden <div id="v4-home-profile-data" hidden
@@ -3,8 +3,12 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
<div> <div>
<template> <template>
<el-card shadow="never"> <el-card shadow="never">
<snaker-start slot="header" label="文化活动申报" define_key="WHHD" <div slot="header" v-if="activity_type===40002||activity_type===40003"
v-if="activity_type===40002||activity_type===40003"></snaker-start> style="display: flex; align-items: center; justify-content: space-between; width: 100%">
<h3 style="color: var(--color-primary); margin: 0">文化活动申报</h3>
<el-link type="primary" @click="$refs.activityChartRef.onOpen('WHHD')">流程图</el-link>
</div>
<snaker-chart v-if="activity_type===40002||activity_type===40003" ref="activityChartRef"></snaker-chart>
<el-form :model="formData" :rules="formRules" label-suffix=":" label-width="170px" <el-form :model="formData" :rules="formRules" label-suffix=":" label-width="170px"
ref="addForm" v-loading="formLoading"> ref="addForm" v-loading="formLoading">
<el-tabs tab-position="top" v-model="activeName"> <el-tabs tab-position="top" v-model="activeName">
@@ -171,7 +175,7 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
</div> </div>
<div> <div>
<el-button <el-button
@click="$refs.drawerUserScope.userScopeDialog = true" @click="openUserScope"
type="primary">设置 type="primary">设置
</el-button> </el-button>
</div> </div>
@@ -370,12 +374,14 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
</el-form-item> </el-form-item>
</el-col> </el-col>
<!--
<el-col :span="24"> <el-col :span="24">
<el-form-item label="报名表单" prop="formConfig" <el-form-item label="报名表单" prop="formConfig"
v-if="formData.isEnrollSystem&&formData.signUpMethod===1"> v-if="formData.isEnrollSystem&&formData.signUpMethod===1">
<custom-form-field v-model="formData.formConfig"></custom-form-field> <custom-form-field v-model="formData.formConfig"></custom-form-field>
</el-form-item> </el-form-item>
</el-col> </el-col>
-->
<el-col :span="24" v-if="formData.signUpMethod!=null&&formData.isEnrollSystem"> <el-col :span="24" v-if="formData.signUpMethod!=null&&formData.isEnrollSystem">
<el-form-item label="封面图" prop="cover"> <el-form-item label="封面图" prop="cover">
@@ -977,13 +983,20 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
this.$set(this.formData, "time", val) this.$set(this.formData, "time", val)
}, },
userChang(id) { userChang(id) {
const userList = this.$refs.userData.options const user = (this.userList || []).find((v) => v.userId === id)
this.$set(this.formData, "mobile", id ? userList.find((v) => v.id === id).mobile : null) this.$set(this.formData, "mobile", id && user ? user.mobile : null)
}, },
async getActivityTwoLevelType(code) { async getActivityTwoLevelType(code) {
const {data} = await this.$axios.post("/platform/activity/basic/settings/getActivityTwoLevelType", {code: code}) const {data} = await this.$axios.post("/platform/activity/basic/settings/getActivityTwoLevelType", {code: code})
return data return data
}, },
openUserScope() {
if (!this.$auth.hasRole("SYSADMIN") && !this.$auth.hasPermission("activity.basic.scope")) {
this.$message.error("无此权限:activity.basic.scope")
return
}
this.$refs.drawerUserScope.userScopeDialog = true
},
async getActivityGroup() { async getActivityGroup() {
const {data} = await this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup") const {data} = await this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup")
this.activityGroupList = data this.activityGroupList = data
@@ -1048,9 +1061,16 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
async findOne(id) { async findOne(id) {
const {data, code, msg} = await this.$axios.post("/platform/activity/culture/infoManage/findOne", {id}) const {data, code, msg} = await this.$axios.post("/platform/activity/culture/infoManage/findOne", {id})
if (code === 0) { if (code === 0) {
this.userList = []
if (data.userId) { if (data.userId) {
const user = await this.queryUserByIds([data.userId]) let loginName = data.loginname
await this.remoteMethod(user[0].loginname) if (!loginName) {
const users = await this.queryUserByIds([data.userId])
loginName = users && users.length > 0 ? users[0].loginname : null
}
if (loginName) {
await this.remoteMethod(loginName)
}
} }
if (data.goods) data.goods = JSON.parse(data.goods) if (data.goods) data.goods = JSON.parse(data.goods)
if (data.billFiles && data.billFiles.length > 0) data.billFiles = JSON.parse(data.billFiles) if (data.billFiles && data.billFiles.length > 0) data.billFiles = JSON.parse(data.billFiles)
@@ -3,7 +3,7 @@
const ACTIVITY_CULTURE_INFO_MANAGE = { const ACTIVITY_CULTURE_INFO_MANAGE = {
template: /*language=HTML*/` template: /*language=HTML*/`
<guava ref="guava"> <guava ref="guava" @hook:mounted="initTableResize">
<template> <template>
<div class="culture-info-manage-layout"> <div class="culture-info-manage-layout">
<el-card class="culture-info-query-card" shadow="never"> <el-card class="culture-info-query-card" shadow="never">
@@ -55,45 +55,49 @@ const ACTIVITY_CULTURE_INFO_MANAGE = {
show-overflow-tooltip show-overflow-tooltip
v-for="column in tableColumns"> v-for="column in tableColumns">
<template scope="{row}" v-if="column.prop=='time2'"> <template slot-scope="{row}">
{{row.applyStartTime}}-{{row.applyEndTime}} <template v-if="column.prop=='time2'">
</template> {{row.applyStartTime}}-{{row.applyEndTime}}
</template>
<template scope="{row}" v-else-if="column.prop=='projectTypeName'">
{{row.projectTypeName}}({{row.projectTypeCode}}) <template v-else-if="column.prop=='projectTypeName'">
</template> {{row.projectTypeName}}({{row.projectTypeCode}})
</template>
<template scope="{row}" v-else-if="column.prop=='tussueName'"> <template v-else-if="column.prop=='tussueName'">
<span v-if="row.activity_type==40002">{{row.unionname?row.unionname:'暂无'}}</span> <span v-if="row.activity_type==40002">{{row.unionname?row.unionname:'暂无'}}</span>
<span v-if="row.activity_type==40003">{{row.clubName?row.clubName:'暂无'}}</span> <span v-if="row.activity_type==40003">{{row.clubName?row.clubName:'暂无'}}</span>
<span v-if="row.activity_type==40001">校工会</span> <span v-if="row.activity_type==40001">校工会</span>
</template>
<template v-else-if="column.prop=='isUnseal'">
<el-switch
@change="(val)=>{activityStatusChange(row.id,row.isUnseal)}"
active-color="#13ce66"
:disabled="isUnsealDisabled(row)"
inactive-color="#ff4949"
v-model="row.isUnseal">
</el-switch>
</template>
<template v-else-if="column.prop=='taskName'">
<span v-if="row.activity_type==40002 || row.activity_type==40003">
{{row.taskName}}
</span>
<span v-else>-</span>
</template>
<template v-else-if="column.prop=='instanceState'">
<span v-if="row.activity_type==40002 || row.activity_type==40003">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</span>
<span v-else>-</span>
</template>
<template v-else>{{ row[column.prop] }}</template>
</template> </template>
<template scope="{row}" v-else-if="column.prop=='isUnseal'">
<el-switch
@change="(val)=>{activityStatusChange(row.id,row.isUnseal)}"
active-color="#13ce66"
:disabled="isUnsealDisabled(row)"
inactive-color="#ff4949"
v-model="row.isUnseal">
</el-switch>
</template>
<template scope="{row}" v-else-if="column.prop=='taskName'">
<span v-if="row.activity_type==40002 || row.activity_type==40003">
{{row.taskName}}
</span>
<span v-else>-</span>
</template>
<template scope="{row}" v-else-if="column.prop=='instanceState'">
<span v-if="row.activity_type==40002 || row.activity_type==40003">
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
size="small"></enum-tag>
</span>
<span v-else>-</span>
</template>
</el-table-column> </el-table-column>
<el-table-column align="center" header-align="center" label="操作" <el-table-column align="center" header-align="center" label="操作"
@@ -110,7 +114,7 @@ const ACTIVITY_CULTURE_INFO_MANAGE = {
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item :command="{type:'edit',row}" <el-dropdown-item :command="{type:'edit',row}"
> v-if="activity_type !== 40003 || !row.instanceId || row.taskKey === 'startTask'">
编辑 编辑
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item u <el-dropdown-item u
@@ -214,6 +218,19 @@ const ACTIVITY_CULTURE_INFO_MANAGE = {
"activity-culture-info-activity": ACTIVITY_CULTURE_INFO_ACTIVITY "activity-culture-info-activity": ACTIVITY_CULTURE_INFO_ACTIVITY
}, },
methods: { methods: {
initTableResize() {
if (!this.isTemplateManagedActivity) {
return
}
const listCardBody = this.$refs.guava.$el.querySelector(".culture-info-list-card > .el-card__body")
if (listCardBody && window.ResizeObserver) {
// 查询区换行、页签权限或窗口变化时同步调整表格内部滚动区域。
this.tableResizeObserver = new ResizeObserver(this.updateTableHeight)
this.tableResizeObserver.observe(listCardBody)
}
this.updateTableHeight()
window.addEventListener("resize", this.updateTableHeight)
},
activityStatusChange(id, isUnseal) { activityStatusChange(id, isUnseal) {
this.$axios.post("/platform/activity/culture/infoManage/activityStatusChange", { this.$axios.post("/platform/activity/culture/infoManage/activityStatusChange", {
id: id, id: id,
@@ -264,7 +281,11 @@ const ACTIVITY_CULTURE_INFO_MANAGE = {
return return
} }
this.$nextTick(() => { this.$nextTick(() => {
const cardBody = this.$el.querySelector(".culture-info-list-card > .el-card__body") const root = this.$refs.guava && this.$refs.guava.$el
if (!root || typeof root.querySelector !== "function") {
return
}
const cardBody = root.querySelector(".culture-info-list-card > .el-card__body")
if (!cardBody || cardBody.clientHeight <= 0) { if (!cardBody || cardBody.clientHeight <= 0) {
return return
} }
@@ -408,19 +429,6 @@ const ACTIVITY_CULTURE_INFO_MANAGE = {
} }
this.pageData() this.pageData()
}, },
mounted() {
if (!this.isTemplateManagedActivity) {
return
}
const listCardBody = this.$el.querySelector(".culture-info-list-card > .el-card__body")
if (listCardBody && window.ResizeObserver) {
// 查询区换行、页签权限或窗口变化时同步调整表格内部滚动区域。
this.tableResizeObserver = new ResizeObserver(this.updateTableHeight)
this.tableResizeObserver.observe(listCardBody)
}
this.updateTableHeight()
window.addEventListener("resize", this.updateTableHeight)
},
beforeDestroy() { beforeDestroy() {
if (this.tableResizeObserver) { if (this.tableResizeObserver) {
this.tableResizeObserver.disconnect() this.tableResizeObserver.disconnect()
@@ -113,6 +113,9 @@
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" <dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="task.ext.submitType"></dict-tag> :value="task.ext.submitType"></dict-tag>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="审批签字" :span="3" v-if="task.taskFormData && (task.taskFormData.userSign || task.taskFormData.tf_userSign)">
<el-image :src="task.taskFormData.userSign || task.taskFormData.tf_userSign" style="height: 80px" fit="contain"></el-image>
</el-descriptions-item>
<el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{ <el-descriptions-item label="办理意见" v-if="!task.ext.isFirstTaskNode">{{
getTaskFormValue(task, "opinion", "tf_opinion") }} getTaskFormValue(task, "opinion", "tf_opinion") }}
</el-descriptions-item> </el-descriptions-item>
@@ -126,6 +129,9 @@
<el-descriptions-item label="办理用户">{{ record.userName }}({{ record.loginName }})</el-descriptions-item> <el-descriptions-item label="办理用户">{{ record.userName }}({{ record.loginName }})</el-descriptions-item>
<el-descriptions-item label="办理时间">{{ record.auditTime }}</el-descriptions-item> <el-descriptions-item label="办理时间">{{ record.auditTime }}</el-descriptions-item>
<el-descriptions-item label="办理结果">{{ getLegacyAuditResult(record) }}</el-descriptions-item> <el-descriptions-item label="办理结果">{{ getLegacyAuditResult(record) }}</el-descriptions-item>
<el-descriptions-item label="审批签字" :span="3" v-if="record.auditSign">
<el-image :src="record.auditSign" style="height: 80px" fit="contain"></el-image>
</el-descriptions-item>
<el-descriptions-item label="办理意见" span="3">{{ record.auditOpinion }}</el-descriptions-item> <el-descriptions-item label="办理意见" span="3">{{ record.auditOpinion }}</el-descriptions-item>
</el-descriptions> </el-descriptions>
</div> </div>
@@ -21,14 +21,29 @@ const PROPOSAL_INFO = {
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="提案类别"> <el-descriptions-item label="提案类别">
{{viewData.typeName}} {{viewData.typeName}}
</el-descriptions-item><!-- </el-descriptions-item>
<!-- 提案方式和联系电话来自提案详情,未填写时显示占位符。 -->
<el-descriptions-item label="提案方式">
<dict-tag v-if="viewData.source" :options="dict.type.PROPOSAL_SOURCE"
:value="viewData.source"></dict-tag>
<span v-else>--</span>
</el-descriptions-item>
<el-descriptions-item label="联系电话">{{ viewData.mobile || '--' }}</el-descriptions-item><!--
<el-descriptions-item label="建议承办单位"> <el-descriptions-item label="建议承办单位">
{{viewData.suggestUnits}} {{viewData.suggestUnits}}
</el-descriptions-item>--> </el-descriptions-item>-->
<el-descriptions-item label="立案结果" :span="2"> <!-- 立案结果和类型尚未填写时仍显示字段,并以双横线表示空值。 -->
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" <el-descriptions-item label="立案结果">
<dict-tag v-if="viewData.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="viewData.caseFilingResult"></dict-tag> :value="viewData.caseFilingResult"></dict-tag>
<span v-else>--</span>
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="立案类型">
<dict-tag v-if="viewData.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="viewData.caseFilingType"></dict-tag>
<span v-else>--</span>
</el-descriptions-item>
<el-descriptions-item></el-descriptions-item>
<!--<el-descriptions-item label="调研情况" :span="3"> <!--<el-descriptions-item label="调研情况" :span="3">
<div class="text-left">{{viewData.researchFindings}}</div> <div class="text-left">{{viewData.researchFindings}}</div>
</el-descriptions-item>--> </el-descriptions-item>-->
@@ -82,18 +97,22 @@ const PROPOSAL_INFO = {
{{row.commissionerName}}({{row.commissionerLoginName}}) {{row.commissionerName}}({{row.commissionerLoginName}})
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="立案结果" prop="caseFilingType"> <!-- 委员意见分别展示立案结果和类型,未填写时显示双横线。 -->
<el-table-column label="立案结果" prop="caseFilingResult">
<template slot-scope="{row}"> <template slot-scope="{row}">
<div style="display: flex;justify-content: center"> <div style="display: flex;justify-content: center">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" <dict-tag v-if="row.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="row.caseFilingResult"></dict-tag> :value="row.caseFilingResult"></dict-tag>
<!-- 普通提案/重点提案暂不展示,历史数据仍保留。 --> <span v-else>--</span>
<template v-if="false"> </div>
( </template>
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE" </el-table-column>
:value="row.caseFilingType"></dict-tag> <el-table-column label="立案类型" prop="caseFilingType">
) <template slot-scope="{row}">
</template> <div style="display: flex;justify-content: center">
<dict-tag v-if="row.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="row.caseFilingType"></dict-tag>
<span v-else>--</span>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
@@ -124,117 +143,125 @@ const PROPOSAL_INFO = {
</span> </span>
</div> </div>
</template> </template>
<!--同一提案可能存在多个承办单位答复任务,查看时合并为一个流程节点,节点内保留每条答复。--> <!--同一提案可能存在多个承办单位答复任务,查看时合并为一个流程节点,节点内保留每条答复。-->
<template v-if="task.replyTasks"> <template v-if="task.replyTasks">
<el-descriptions v-for="replyTask in task.replyTasks" border class="flow-task-form" <el-descriptions v-for="replyTask in task.replyTasks" border class="flow-task-form"
:column="3" :key="replyTask.id"> :column="3" :key="replyTask.id">
<el-descriptions-item label="承办单位" :span="3"> <el-descriptions-item label="承办单位" :span="3">
{{replyTask.ext.underTakeName}} {{replyTask.ext.underTakeName}}
</el-descriptions-item>
<el-descriptions-item label="办理用户">
{{replyTask.taskFormData.userName}}({{replyTask.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{replyTask.finishTime}}</el-descriptions-item>
<el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="replyTask.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" :span="3">
<div v-html="replyTask.taskFormData.tf_opinion"></div>
</el-descriptions-item>
</el-descriptions>
</template>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-else-if="task.ext.isFirstTaskNode">
<el-descriptions-item label="申请用户">{{ task.ext.initiatorName
}}({{task.ext.initiatorAccount}})
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="办理用户"> <el-descriptions-item label="申请时间">{{ task.finishTime }}</el-descriptions-item>
{{replyTask.taskFormData.userName}}({{replyTask.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间">{{replyTask.finishTime}}</el-descriptions-item>
<el-descriptions-item label="办理结果"> <el-descriptions-item label="办理结果">
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" <dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
:value="replyTask.ext.submitType"></dict-tag> :value="task.ext.submitType"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="办理意见" :span="3">
<div v-html="replyTask.taskFormData.tf_opinion"></div>
</el-descriptions-item> </el-descriptions-item>
</el-descriptions> </el-descriptions>
</template>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-else-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" <el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-else-if="task.taskName === 'invite'"> v-else-if="task.taskName === 'invite'">
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName <el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}}) }}({{task.taskFormData.loginName}})
</el-descriptions-item>
<el-descriptions-item label="办理时间" :span="2">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="附议人" :span="3" v-if="task.taskName === 'invite'">
<el-table v-loading="tableLoading" :data="task?.taskFormData?.seconder">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="联系方式" prop="mobile"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
</el-table>
</el-descriptions-item>
</el-descriptions>
<!--提案委员会立案-->
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-else-if="task.taskName === 'committee'||task.taskName === 'committeeFilingUnit'">
<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="立案结果">
<div style="display: flex;justify-content: center">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="task.ext.tf_caseFilingResult"></dict-tag>
<!-- 普通提案/重点提案暂不展示,历史流程变量仍保留。 -->
<template v-if="false">
(
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="task.ext.tf_caseFilingType"></dict-tag>
)
</template>
</div>
</el-descriptions-item>
<template v-if="['CONFIRM_FILING','SUGGESTION'].includes(task.ext.tf_caseFilingResult)">
<el-descriptions-item v-if="task.ext.tf_caseFilingResult === 'SUGGESTION'" label="承办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr || task?.ext?.tf_slaveUnitNameStr}}
</el-descriptions-item> </el-descriptions-item>
<template v-else> <el-descriptions-item label="办理时间" :span="2">{{ task.finishTime }}
<el-descriptions-item label="主办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr}} </el-descriptions-item>
</el-descriptions-item> <el-descriptions-item label="附议人" :span="3" v-if="task.taskName === 'invite'">
<el-descriptions-item label="协办单位" :span="3">{{task?.ext?.tf_slaveUnitNameStr}} <el-table v-loading="tableLoading" :data="task?.taskFormData?.seconder">
<el-table-column label="姓名" prop="userName"></el-table-column>
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="性别" prop="sex"></el-table-column>
<el-table-column label="联系方式" prop="mobile"></el-table-column>
<el-table-column label="单位" prop="unitName"></el-table-column>
<el-table-column label="分工会" prop="unionName"></el-table-column>
<el-table-column label="代表团" prop="delegationName"></el-table-column>
</el-table>
</el-descriptions-item>
</el-descriptions>
<!--提案委员会立案-->
<el-descriptions border class="flow-task-form" :column="3" :key="task.id"
v-else-if="task.taskName === 'committee'||task.taskName === 'committeeFilingUnit'">
<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="立案结果">
<div style="display: flex;justify-content: center">
<dict-tag v-if="task.ext.tf_caseFilingResult"
:options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="task.ext.tf_caseFilingResult"></dict-tag>
<span v-else>--</span>
</div>
</el-descriptions-item>
<el-descriptions-item label="立案类型">
<div style="display: flex;justify-content: center">
<dict-tag v-if="task.ext.tf_caseFilingType"
:options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="task.ext.tf_caseFilingType"></dict-tag>
<span v-else>--</span>
</div>
</el-descriptions-item>
<template v-if="['CONFIRM_FILING','SUGGESTION'].includes(task.ext.tf_caseFilingResult)">
<el-descriptions-item v-if="task.ext.tf_caseFilingResult === 'SUGGESTION'"
label="承办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr ||
task?.ext?.tf_slaveUnitNameStr}}
</el-descriptions-item> </el-descriptions-item>
<template v-else>
<el-descriptions-item label="主办单位" :span="3">{{task?.ext?.tf_masterUnitNameStr}}
</el-descriptions-item>
<el-descriptions-item label="协办单位" :span="3">{{task?.ext?.tf_slaveUnitNameStr}}
</el-descriptions-item>
</template>
</template> </template>
</template> <el-descriptions-item label="办理意见" :span="3">
<el-descriptions-item label="办理意见" :span="3"> <div v-html="task.taskFormData.tf_opinion"></div>
<div v-html="task.taskFormData.tf_opinion"></div> </el-descriptions-item>
</el-descriptions-item> </el-descriptions>
</el-descriptions>
<el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else> <el-descriptions border class="flow-task-form" :column="3" :key="task.id" v-else>
<el-descriptions-item label="承办单位" <el-descriptions-item label="承办单位"
v-if="['opinion_unit_reply','unit_reply','two_unit_reply','opinion_master_reply','master_reply','slave_reply'].includes(task.taskName)" :span="3"> v-if="['opinion_unit_reply','unit_reply','two_unit_reply','opinion_master_reply','master_reply','slave_reply'].includes(task.taskName)"
{{task.ext.underTakeName}} :span="3">
</el-descriptions-item> {{task.ext.underTakeName}}
</el-descriptions-item>
<el-descriptions-item label="办理用户">{{ task.taskFormData.userName <el-descriptions-item label="办理用户">{{ task.taskFormData.userName
}}({{task.taskFormData.loginName}}) }}({{task.taskFormData.loginName}})
</el-descriptions-item> </el-descriptions-item>
<el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item> <el-descriptions-item label="办理时间">{{ task.finishTime }}</el-descriptions-item>
<el-descriptions-item label="办理评价" v-if="['feedback'].includes(task.taskName)" :span="3"> <el-descriptions-item label="办理评价" v-if="['feedback'].includes(task.taskName)"
<dict-tag :options="dict.type.PROPOSAL_FEEDBACK" :span="3">
:value="task.ext.tf_feedback"></dict-tag> <dict-tag :options="dict.type.PROPOSAL_FEEDBACK"
</el-descriptions-item> :value="task.ext.tf_feedback"></dict-tag>
<el-descriptions-item label="办理结果" v-else> </el-descriptions-item>
<dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE" <el-descriptions-item label="办理结果" v-else>
:value="task.ext.submitType"></dict-tag> <dict-tag :options="dict.type.PROCESS_TASK_SUBMIT_TYPE"
</el-descriptions-item> :value="task.ext.submitType"></dict-tag>
<el-descriptions-item label="办理意见" :span="3" v-if="!task.ext.isFirstTaskNode"> </el-descriptions-item>
<div v-html="task.taskFormData.tf_opinion"></div> <el-descriptions-item label="办理意见" :span="3" v-if="!task.ext.isFirstTaskNode">
</el-descriptions-item> <div v-html="task.taskFormData.tf_opinion"></div>
</el-descriptions> </el-descriptions-item>
</el-descriptions>
</el-collapse-item> </el-collapse-item>
</el-collapse> </el-collapse>
</template> </template>
@@ -243,7 +270,7 @@ const PROPOSAL_INFO = {
<snaker-chart ref="snakerChartRef"></snaker-chart> <snaker-chart ref="snakerChartRef"></snaker-chart>
</div> </div>
`, `,
dicts: ["PROPOSAL_TYPE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE", "PROCESS_TASK_SUBMIT_TYPE", "PROPOSAL_FEEDBACK"], dicts: ["PROPOSAL_TYPE", "PROPOSAL_SOURCE", "PROPOSAL_CASE_FILING_RESULT", "PROPOSAL_CASE_FILING_TYPE", "PROCESS_TASK_SUBMIT_TYPE", "PROPOSAL_FEEDBACK"],
props: { props: {
hide_slave: false hide_slave: false
}, },
@@ -60,7 +60,10 @@ const USER_COMPONENT = {
}, },
filterUnit(query, item) { filterUnit(query, item) {
return item.username.indexOf(query) > -1 // 按姓名或工号筛选人员,字段为空时按空字符串处理。
const username = item.username || ""
const loginname = item.loginname || ""
return username.indexOf(query) > -1 || loginname.indexOf(query) > -1
} }
} }
} }
@@ -23,9 +23,9 @@ layout("/layouts/platform.html"){
</el-card> </el-card>
<el-card shadow="never"> <el-card shadow="never">
<table-tool :columns.sync="tableColumns"> <table-tool :columns.sync="tableColumns">
<el-button class="ml5" icon="el-icon-upload2" type="primary" size="small" <!-- <el-button class="ml5" icon="el-icon-upload2" type="primary" size="small"
@click="openImport">导入提案 @click="openImport">导入提案
</el-button> </el-button>-->
</table-tool> </table-tool>
<el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id"> <el-table v-loading="tableLoading" :data="tableData" @sort-change="pageOrder" header-align="center" style="width: 100%" row-key="id">
<el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column> <el-table-column label="序号" width="50" type="index" :index="indexMethod" fixed="left"></el-table-column>
@@ -8,7 +8,7 @@ layout("/layouts/platform.html"){
<custom-card> <custom-card>
<snaker-start slot="header" label="撰写提案" define_key="JDHTA_NC"> <snaker-start slot="header" label="撰写提案" define_key="JDHTA_NC">
<template slot="header-right-label"> <template slot="header-right-label">
<el-link type="primary" @click="openImport" v-if="!formData.id" style="margin-right: 15px">导入提案</el-link> <!-- <el-link type="primary" @click="openImport" v-if="!formData.id" style="margin-right: 15px">导入提案</el-link>-->
</template> </template>
</snaker-start> </snaker-start>
<el-form :model="formData" :rules="formRules" label-width="120px" ref="addForm"> <el-form :model="formData" :rules="formRules" label-width="120px" ref="addForm">
@@ -16,7 +16,7 @@ layout("/layouts/platform.html"){
<el-form-item prop="mode"> <el-form-item prop="mode">
<el-select v-model="formData.mode" placeholder="申请模式" @change="modeChange" style="width: 100%"> <el-select v-model="formData.mode" placeholder="申请模式" @change="modeChange" style="width: 100%">
<el-option label="本人申请" value="1"></el-option> <el-option label="本人申请" value="1"></el-option>
<el-option v-if="$auth.hasRoleOr('BRANCH_UNION_CHAIRMAN')" <el-option v-if="canApplyForOthers"
label="替他人申请" value="2"></el-option> label="替他人申请" value="2"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -366,6 +366,11 @@ layout("/layouts/platform.html"){
subsidizedList: [] subsidizedList: []
} }
}, },
computed: {
canApplyForOthers() {
return this.$auth.hasPermissionOr(['difficult_assistance_school', 'difficult_assistance_union'])
}
},
methods: { methods: {
textRules(label, max) { textRules(label, max) {
return [{required: true, whitespace: true, max, message: '请填写' + label + ',且不超过' + max + '个字符', trigger: ['blur', 'change']}] return [{required: true, whitespace: true, max, message: '请填写' + label + ',且不超过' + max + '个字符', trigger: ['blur', 'change']}]
@@ -379,9 +384,7 @@ layout("/layouts/platform.html"){
callback(valid ? undefined : new Error('申请金额须大于零,最多保留两位小数')) callback(valid ? undefined : new Error('申请金额须大于零,最多保留两位小数'))
}, },
// 保存 // 保存
async onSave() { onSave() {
const valid = await this.$refs.formRef.validate().catch(() => false)
if (!valid) return
this.$confirm("您确定保存吗?", "提示", { this.$confirm("您确定保存吗?", "提示", {
confirmButtonText: "确定", confirmButtonText: "确定",
cancelButtonText: "取消", cancelButtonText: "取消",
@@ -443,7 +446,7 @@ layout("/layouts/platform.html"){
// 查询受助人 // 查询受助人
queryRecipients(key) { queryRecipients(key) {
if (String(this.formData.mode) !== "2" || !this.$auth.hasRoleOr('BRANCH_UNION_CHAIRMAN')) { if (String(this.formData.mode) !== "2" || !this.canApplyForOthers) {
return return
} }
this.$axios.post("/platform/difficultHelp/apply/queryRecipients", { this.$axios.post("/platform/difficultHelp/apply/queryRecipients", {
@@ -478,6 +481,9 @@ layout("/layouts/platform.html"){
this.$set(this.formData, 'birthday', user.birthday) this.$set(this.formData, 'birthday', user.birthday)
this.$set(this.formData, 'mobile', user.mobile) this.$set(this.formData, 'mobile', user.mobile)
this.$set(this.formData, 'idCard', user.idCard) this.$set(this.formData, 'idCard', user.idCard)
this.$set(this.formData, 'position', user.position || '')
this.$set(this.formData, 'officialCapacity', user.officialCapacity || '')
this.$set(this.formData, 'homeAddress', user.homeAddress || '')
} else { } else {
this.$set(this.formData, 'userId', null) this.$set(this.formData, 'userId', null)
@@ -490,6 +496,10 @@ layout("/layouts/platform.html"){
this.$set(this.formData, 'unionName', null) this.$set(this.formData, 'unionName', null)
this.$set(this.formData, 'birthday', null) this.$set(this.formData, 'birthday', null)
this.$set(this.formData, 'mobile', null) this.$set(this.formData, 'mobile', null)
this.$set(this.formData, 'idCard', null)
this.$set(this.formData, 'position', '')
this.$set(this.formData, 'officialCapacity', '')
this.$set(this.formData, 'homeAddress', '')
} }
}, },
// 申请模式 // 申请模式
@@ -514,6 +524,8 @@ layout("/layouts/platform.html"){
this.$set(this.formData, 'idCard', user.idCard) this.$set(this.formData, 'idCard', user.idCard)
this.$set(this.formData, 'mobile', user.mobile) this.$set(this.formData, 'mobile', user.mobile)
this.$set(this.formData, 'homeAddress', user.homeAddress) this.$set(this.formData, 'homeAddress', user.homeAddress)
this.$set(this.formData, 'position', user.position || '')
this.$set(this.formData, 'officialCapacity', user.professionalTitle || '')
this.$set(this.formData, 'subsidyStandards', null) this.$set(this.formData, 'subsidyStandards', null)
this.$set(this.formData, 'reason', null) this.$set(this.formData, 'reason', null)
this.$set(this.formData, 'remarks', null) this.$set(this.formData, 'remarks', null)
@@ -624,7 +636,7 @@ layout("/layouts/platform.html"){
return this.$axios.post('/platform/difficultHelp/apply/getIsCanPlay').then(res => { return this.$axios.post('/platform/difficultHelp/apply/getIsCanPlay').then(res => {
if (res.code === 0) { if (res.code === 0) {
// 新增申请进入页面时,优先校验当前登录人本年度是否已经申请过,已申请则直接拦截新增。 // 新增申请进入页面时,优先校验当前登录人本年度是否已经申请过,已申请则直接拦截新增。
if (!this.bizId && res.data.hasCurrentYearApply && !this.$auth.hasRoleOr('BRANCH_UNION_CHAIRMAN')) { if (!this.bizId && res.data.hasCurrentYearApply && !this.canApplyForOthers) {
this.isShow = false this.isShow = false
this.$set(this, 'blockMessage', '抱歉,您本年度已申请困难帮扶,不能重复申请。') this.$set(this, 'blockMessage', '抱歉,您本年度已申请困难帮扶,不能重复申请。')
} else { } else {
@@ -42,7 +42,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt10"> <el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表"> <table-tool :app="this" label="审批列表">
<el-button type="primary" size="small" @click="allAudit" :disabled="pageForm.audit === 'true'">一键审核</el-button> <!-- <el-button type="primary" size="small" @click="allAudit" :disabled="pageForm.audit === 'true'">一键审核</el-button> -->
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit"> <el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<el-radio-button label="true">已审核</el-radio-button> <el-radio-button label="true">已审核</el-radio-button>
<el-radio-button label="false">未审核</el-radio-button> <el-radio-button label="false">未审核</el-radio-button>
@@ -145,7 +145,7 @@ layout("/layouts/platform.html"){
{ prop: "mobile", label: "联系方式", sortable: true }, { prop: "mobile", label: "联系方式", sortable: true },
{ prop: "subsidyStandards", label: "困难类型", sortable: true }, { prop: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true }, { prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "applyCount", label: "申请次数", sortable: true }, { prop: "applyMoney", label: "申请金额(元)", sortable: true },
{ prop: "curTaskName", label: "当前节点" }, { prop: "curTaskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" } { prop: "instanceState", label: "流程状态" }
], ],
@@ -8,6 +8,7 @@ const INFO = {
<el-descriptions-item label="填写人姓名">{{ viewData.proxyUserName }}</el-descriptions-item> <el-descriptions-item label="填写人姓名">{{ viewData.proxyUserName }}</el-descriptions-item>
<el-descriptions-item label="申请金额(元)">{{ viewData.applyMoney }}</el-descriptions-item> <el-descriptions-item label="申请金额(元)">{{ viewData.applyMoney }}</el-descriptions-item>
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item> <el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
<el-descriptions-item label="身份证号">{{ viewData.idCard }}</el-descriptions-item>
<el-descriptions-item label="填写人工号">{{ viewData.proxyLoginName }}</el-descriptions-item> <el-descriptions-item label="填写人工号">{{ viewData.proxyLoginName }}</el-descriptions-item>
<!--\t\t<el-descriptions-item label="申请模式">{{ viewData.mode == 1 ? '本人申请' : '替他人申请' }}</el-descriptions-item>--> <!--\t\t<el-descriptions-item label="申请模式">{{ viewData.mode == 1 ? '本人申请' : '替他人申请' }}</el-descriptions-item>-->
<el-descriptions-item label="所属单位">{{ viewData.unitName }}</el-descriptions-item> <el-descriptions-item label="所属单位">{{ viewData.unitName }}</el-descriptions-item>
@@ -25,6 +26,12 @@ const INFO = {
<el-descriptions-item label="申请次数" >{{ 1 }}</el-descriptions-item> <el-descriptions-item label="申请次数" >{{ 1 }}</el-descriptions-item>
<el-descriptions-item label="家庭住址" :span="2">{{ viewData.homeAddress }}</el-descriptions-item> <el-descriptions-item label="家庭住址" :span="2">{{ viewData.homeAddress }}</el-descriptions-item>
<el-descriptions-item label="补助类型">
<dict-tag :options="dict.type.DIFFICULT_SUBSIDY_TYPE" :value="viewData.subsidy"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="困难类型">
<dict-tag :options="dict.type.DIFFICULT_TYPE" :value="viewData.subsidyStandards"></dict-tag>
</el-descriptions-item>
<el-descriptions-item label="家庭主要成员(在一起生活的直系亲属)经济收入情况" :span="3"> <el-descriptions-item label="家庭主要成员(在一起生活的直系亲属)经济收入情况" :span="3">
@@ -90,8 +97,9 @@ const INFO = {
<template v-if="task.taskFormData.level != null"> <template v-if="task.taskFormData.level != null">
<el-descriptions-item label="审批级别">{{ task.taskFormData.level }}</el-descriptions-item> <el-descriptions-item label="审批级别">{{ task.taskFormData.level }}</el-descriptions-item>
<el-descriptions-item label="帮扶金额(元)">{{ task.taskFormData.money }}</el-descriptions-item>
</template> </template>
<el-descriptions-item v-if="task.taskFormData.money != null"
:label="task.taskFormData.actualMoney != null ? '实际审批金额(元)' : '帮扶金额(元)'">{{ task.taskFormData.money }}</el-descriptions-item>
<el-descriptions-item label="审批签字" :span="3" v-if="task.taskFormData && task.taskFormData.sign"> <el-descriptions-item label="审批签字" :span="3" v-if="task.taskFormData && task.taskFormData.sign">
@@ -110,7 +118,7 @@ const INFO = {
</div> </div>
`, `,
store, store,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"], dicts: ["PROCESS_TASK_SUBMIT_TYPE", "DIFFICULT_SUBSIDY_TYPE", "DIFFICULT_TYPE"],
data() { data() {
return { return {
viewData: {}, viewData: {},
@@ -45,8 +45,8 @@ layout("/layouts/platform.html"){
<el-button type="primary" size="small" @click="importMoney">导入实际金额</el-button> <el-button type="primary" size="small" @click="importMoney">导入实际金额</el-button>
<el-button @click="exportYearPayRecord" size="small" icon="el-icon-download" type="primary">导出补助金额</el-button> <el-button @click="exportYearPayRecord" size="small" icon="el-icon-download" type="primary">导出补助金额</el-button>
<el-button @click="exportAllApply" size="small" type="primary">导出申请表(压缩包)</el-button> <el-button @click="exportAllApply" size="small" type="primary">导出申请表(压缩包)</el-button>
<el-button @click="exportSummaryXlsx" size="small" type="primary">导出汇总表(excel)</el-button> <el-button @click="exportSummaryXlsx" size="small" type="primary">导出汇总表(Excel)</el-button>
<el-button @click="exportSummaryDocx" size="small" type="primary">导出汇总表(word)</el-button> <!-- <el-button @click="exportSummaryDocx" size="small" type="primary">导出汇总表(Word)</el-button> -->
</table-tool> </table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" <el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
@@ -195,7 +195,7 @@ layout("/layouts/platform.html"){
this.$downLoad('/platform/difficultHelp/reading/exportSummary', params) this.$downLoad('/platform/difficultHelp/reading/exportSummary', params)
}, },
doExportApply(row) { doExportApply(row) {
this.$downLoad('/platform/difficultHelp/reading/doExportApply?id=' + row.id + '&print=false') this.$downLoad('/platform/difficultHelp/reading/exportReadingApply', {...this.pageForm, id: row.id, print: false})
} }
}, },
async created() { async created() {
@@ -1,5 +1,8 @@
<div id="difficult_help_school_union_approval_form"> <div id="difficult_help_school_union_approval_form">
<el-form :model="formData" ref="formRef" label-width="100px" label-suffix=":"> <el-form :model="formData" ref="formRef" label-width="100px" label-suffix=":">
<el-form-item label="实际审批金额(元)">
<span>{{ formData.money != null ? formData.money : '--' }}</span>
</el-form-item>
<el-form-item label="审批意见" prop="tf_opinion" :rules="[{required:true,whitespace:true,message:'请填写审批意见',trigger:['change','blur']}]"> <el-form-item label="审批意见" prop="tf_opinion" :rules="[{required:true,whitespace:true,message:'请填写审批意见',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea> <user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item> </el-form-item>
@@ -15,12 +18,20 @@
el: "#difficult_help_school_union_approval_form", el: "#difficult_help_school_union_approval_form",
data() { data() {
return { return {
businessId: GetQueryString("businessId"), businessId: GetQueryString("businessId") || GetQueryString("bizId"),
formData: { formData: {
money: undefined,
tf_sign: "", tf_opinion: "", tf_sign: "", tf_opinion: "",
}, },
} }
}, },
created() {
if (this.businessId) {
this.$axios.post("/platform/difficultHelp/mine/findOne", {id: this.businessId}).then(res => {
if (res.code === 0 && res.data) this.formData.money = res.data.money
})
}
},
methods: { methods: {
async handleTaskAction(val) { async handleTaskAction(val) {
try { try {
@@ -42,7 +42,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt10"> <el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表"> <table-tool :app="this" label="审批列表">
<el-button type="primary" size="small" @click="allAudit" :disabled="pageForm.audit === 'true'">一键审核</el-button> <!-- <el-button type="primary" size="small" @click="allAudit" :disabled="pageForm.audit === 'true'">一键审核</el-button> -->
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit"> <el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<el-radio-button label="true">已审核</el-radio-button> <el-radio-button label="true">已审核</el-radio-button>
<el-radio-button label="false">未审核</el-radio-button> <el-radio-button label="false">未审核</el-radio-button>
@@ -83,6 +83,9 @@ layout("/layouts/platform.html"){
<el-dialog title="设置审核信息" :visible.sync="dialogVisible" width="30%" center> <el-dialog title="设置审核信息" :visible.sync="dialogVisible" width="30%" center>
<el-form :model="formData" ref="formData" label-width="100px"> <el-form :model="formData" ref="formData" label-width="100px">
<el-form-item label="实际审批金额(元)">
<span>{{ formData.money != null ? formData.money : '--' }}</span>
</el-form-item>
<el-form-item label="审批意见" prop="tf_opinion" :rules="[{required:true,whitespace:true,message:'请填写审批意见',trigger:['change','blur']}]"> <el-form-item label="审批意见" prop="tf_opinion" :rules="[{required:true,whitespace:true,message:'请填写审批意见',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea> <user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
</el-form-item> </el-form-item>
@@ -103,6 +106,9 @@ layout("/layouts/platform.html"){
{{formData.taskName}} {{formData.taskName}}
</div> </div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="100px" label-suffix=":"> <el-form :model="formData" ref="formRef" :rules="formRules" label-width="100px" label-suffix=":">
<el-form-item label="实际审批金额(元)">
<span>{{ formData.money != null ? formData.money : '--' }}</span>
</el-form-item>
<el-form-item label="审批意见" prop="tf_opinion" <el-form-item label="审批意见" prop="tf_opinion"
:rules="[{required:true,whitespace:true,message:'请填写审批意见',trigger:['change','blur']}]"> :rules="[{required:true,whitespace:true,message:'请填写审批意见',trigger:['change','blur']}]">
<user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea> <user-opinion-textarea v-model="formData.tf_opinion"></user-opinion-textarea>
@@ -146,7 +152,7 @@ layout("/layouts/platform.html"){
{ prop: "mobile", label: "联系方式", sortable: true }, { prop: "mobile", label: "联系方式", sortable: true },
{ prop: "subsidyStandards", label: "困难类型", sortable: true }, { prop: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true }, { prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "applyCount", label: "申请次数", sortable: true }, { prop: "applyMoney", label: "申请金额(元)", sortable: true },
{ prop: "curTaskName", label: "当前节点" }, { prop: "curTaskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" } { prop: "instanceState", label: "流程状态" }
], ],
@@ -154,6 +160,7 @@ layout("/layouts/platform.html"){
units: [], units: [],
formData: { formData: {
money: undefined,
tf_sign: "", tf_opinion: "", tf_sign: "", tf_opinion: "",
}, },
showApprovalForm: false, showApprovalForm: false,
@@ -178,6 +185,7 @@ layout("/layouts/platform.html"){
this.$message.warning('请至少选择一条记录进行审核!'); this.$message.warning('请至少选择一条记录进行审核!');
return; return;
} }
this.$set(this.formData, 'money', undefined)
this.dialogVisible = true; this.dialogVisible = true;
}, },
submitAudit() { submitAudit() {
@@ -248,6 +256,7 @@ layout("/layouts/platform.html"){
this.$refs.guava.edit(()=>{ this.$refs.guava.edit(()=>{
this.showApprovalForm = true this.showApprovalForm = true
this.formData = { this.formData = {
money: row.money,
tf_sign: "", tf_sign: "",
processTaskId: row.taskId, processTaskId: row.taskId,
taskName: row.curTaskName, taskName: row.curTaskName,
@@ -42,7 +42,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt10"> <el-card shadow="never" class="mt10">
<table-tool :app="this" label="审批列表"> <table-tool :app="this" label="审批列表">
<el-button type="primary" size="small" @click="allAudit" :disabled="pageForm.audit === 'true'">一键审核</el-button> <!-- <el-button type="primary" size="small" @click="allAudit" :disabled="pageForm.audit === 'true'">一键审核</el-button> -->
<el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit"> <el-radio-group @change="doSearch" class="mr5" size="small" v-model="pageForm.audit">
<el-radio-button label="true">已审核</el-radio-button> <el-radio-button label="true">已审核</el-radio-button>
<el-radio-button label="false">未审核</el-radio-button> <el-radio-button label="false">未审核</el-radio-button>
@@ -158,7 +158,7 @@ layout("/layouts/platform.html"){
{ prop: "mobile", label: "联系方式", sortable: true }, { prop: "mobile", label: "联系方式", sortable: true },
{ prop: "subsidyStandards", label: "困难类型", sortable: true }, { prop: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true }, { prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "applyCount", label: "申请次数", sortable: true }, { prop: "applyMoney", label: "申请金额(元)", sortable: true },
{ prop: "curTaskName", label: "当前节点" }, { prop: "curTaskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" } { prop: "instanceState", label: "流程状态" }
], ],
@@ -82,6 +82,7 @@ layout("/layouts/platform.html"){
</el-popover> </el-popover>
</table-tool> </table-tool>
<el-table <el-table
ref="memberTableRef"
:data="tableData" :data="tableData"
style="width: 100%" style="width: 100%"
stripe stripe
@@ -102,12 +103,12 @@ layout("/layouts/platform.html"){
<el-table-column <el-table-column
align="center" align="center"
header-align="center" header-align="center"
v-for="column in tableColumns" v-for="column in showColumns"
:key="column.prop"
show-overflow-tooltip show-overflow-tooltip
v-if="checkedFields.includes(column.prop)"
:label="column.label" :label="column.label"
:prop="column.prop" :prop="column.prop"
:width="column.width" :min-width="column.width || 120"
:fixed="column.fixed" :fixed="column.fixed"
:sortable="column.sortable" :sortable="column.sortable"
> >
@@ -268,6 +269,16 @@ layout("/layouts/platform.html"){
this.checkedFields = all.filter(p => !this.checkedFields.includes(p)); this.checkedFields = all.filter(p => !this.checkedFields.includes(p));
} }
}, },
watch: {
checkedFields() {
// 可见列更新后重新计算列宽,保证右侧固定操作列与表头、数据行对齐。
this.$nextTick(() => {
if (this.$refs.memberTableRef) {
this.$refs.memberTableRef.doLayout()
}
})
}
},
computed: { computed: {
showColumns() { showColumns() {
return this.tableColumns.filter(c => this.checkedFields.includes(c.prop)); return this.tableColumns.filter(c => this.checkedFields.includes(c.prop));
@@ -9,26 +9,30 @@ const PROPOSAL_INFO = {
<van-cell-group :border="false"> <van-cell-group :border="false">
<van-cell title="提案编号">{{ viewData.code || '--' }}</van-cell> <van-cell title="提案编号">{{ viewData.code || '--' }}</van-cell>
<van-cell title="提案名称">{{ viewData.name || '--' }}</van-cell> <van-cell title="提案名称">{{ viewData.name || '--' }}</van-cell>
<van-cell title="立案结果" v-if="viewData.caseFilingResult">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" <van-cell title="提案类别">{{ viewData.typeName || '--' }}</van-cell>
:value="viewData.caseFilingResult"></dict-tag>
</van-cell>
<van-cell title="立案类型" v-if="viewData.caseFilingType">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="viewData.caseFilingType"></dict-tag>
</van-cell>
<van-cell title="提案类型">{{ viewData.typeName || '--' }}</van-cell>
<van-cell title="提案方式">{{ getDictText(dict.type.PROPOSAL_SOURCE, viewData.source) }} <van-cell title="提案方式">{{ getDictText(dict.type.PROPOSAL_SOURCE, viewData.source) }}
</van-cell> </van-cell>
<van-cell title="代表姓名">{{ viewData.createUserName || '--' }}</van-cell> <van-cell title="提案人">{{ viewData.createUserName || '--' }}</van-cell>
<van-cell title="所属教代会">{{ viewData.sessionName || viewData.fullName || '--' }}</van-cell> <van-cell title="教代会届次">{{ viewData.sessionName || viewData.fullName || '--' }}</van-cell>
<van-cell :title="viewData.committeeName ? '所属委员会' : '所属代表团'"> <van-cell :title="viewData.committeeName ? '委员会名称' : '代表团名称'">
{{ viewData.committeeName || viewData.delegationName || '--' }} {{ viewData.committeeName || viewData.delegationName || '--' }}
</van-cell> </van-cell>
<van-cell title="单位">{{ viewData.unitName || '--' }}</van-cell> <van-cell title="提案人单位">{{ viewData.unitName || '--' }}</van-cell>
<van-cell title="联系电话">{{ viewData.mobile || '--' }}</van-cell> <van-cell title="联系电话">{{ viewData.mobile || '--' }}</van-cell>
<van-cell title="提案时间">{{ viewData.createTime || '--' }}</van-cell> <van-cell title="提案时间">{{ viewData.createTime || '--' }}</van-cell>
<van-cell title="案由" class="proposal-view-long-cell"> <!-- 立案结果和类型尚未填写时仍显示字段,并以双横线表示空值。 -->
<van-cell title="立案结果">
<dict-tag v-if="viewData.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="viewData.caseFilingResult"></dict-tag>
<span v-else>--</span>
</van-cell>
<van-cell title="立案类型">
<dict-tag v-if="viewData.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="viewData.caseFilingType"></dict-tag>
<span v-else>--</span>
</van-cell>
<van-cell title="提案案由" class="proposal-view-long-cell">
<div class="proposal-view-rich-value" v-html="viewData.brief || '--'"></div> <div class="proposal-view-rich-value" v-html="viewData.brief || '--'"></div>
</van-cell> </van-cell>
<van-cell title="建议措施" class="proposal-view-long-cell"> <van-cell title="建议措施" class="proposal-view-long-cell">
@@ -48,7 +52,7 @@ const PROPOSAL_INFO = {
:key="merge.id" :key="merge.id"
class="proposal-view-merge-cell" class="proposal-view-merge-cell"
:title="(index + 1) + '. ' + merge.name" :title="(index + 1) + '. ' + merge.name"
:label="'提案编号:' + merge.code + '|提案人:' + merge.createUserName + '|类别:' + merge.typeName + '|代表团:' + merge.delegationName" :label="'提案编号:' + merge.code + '|提案人:' + merge.createUserName + '|提案类别:' + merge.typeName + '|代表团:' + merge.delegationName"
is-link is-link
@click="openView(merge)"> @click="openView(merge)">
</van-cell> </van-cell>
@@ -66,13 +70,16 @@ const PROPOSAL_INFO = {
<template v-if="opinion.commissionerLoginName">({{ opinion.commissionerLoginName }}) <template v-if="opinion.commissionerLoginName">({{ opinion.commissionerLoginName }})
</template> </template>
</van-cell> </van-cell>
<!-- 委员意见分别展示立案结果和类型,未填写时显示双横线。 -->
<van-cell title="立案结果"> <van-cell title="立案结果">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" <dict-tag v-if="opinion.caseFilingResult" :options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="opinion.caseFilingResult"></dict-tag> :value="opinion.caseFilingResult"></dict-tag>
<span v-else>--</span>
</van-cell> </van-cell>
<van-cell title="立案类型" v-if="opinion.caseFilingType"> <van-cell title="立案类型">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE" <dict-tag v-if="opinion.caseFilingType" :options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="opinion.caseFilingType"></dict-tag> :value="opinion.caseFilingType"></dict-tag>
<span v-else>--</span>
</van-cell> </van-cell>
<van-cell title="意见" v-if="opinion.opinionText" class="proposal-view-long-cell"> <van-cell title="意见" v-if="opinion.opinionText" class="proposal-view-long-cell">
<div class="proposal-view-rich-value">{{ opinion.opinionText }}</div> <div class="proposal-view-rich-value">{{ opinion.opinionText }}</div>
@@ -158,13 +165,18 @@ const PROPOSAL_INFO = {
|| '--' }}) || '--' }})
</van-cell> </van-cell>
<van-cell title="办理时间">{{ selectedTask.finishTime || '--' }}</van-cell> <van-cell title="办理时间">{{ selectedTask.finishTime || '--' }}</van-cell>
<!-- 立案节点分别展示流程记录中的结果与类型,空值显示双横线。 -->
<van-cell title="立案结果"> <van-cell title="立案结果">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_RESULT" <dict-tag v-if="selectedTask.ext.tf_caseFilingResult"
:options="dict.type.PROPOSAL_CASE_FILING_RESULT"
:value="selectedTask.ext.tf_caseFilingResult"></dict-tag> :value="selectedTask.ext.tf_caseFilingResult"></dict-tag>
<span v-else>--</span>
</van-cell> </van-cell>
<van-cell title="立案类型" v-if="selectedTask.ext.tf_caseFilingType"> <van-cell title="立案类型">
<dict-tag :options="dict.type.PROPOSAL_CASE_FILING_TYPE" <dict-tag v-if="selectedTask.ext.tf_caseFilingType"
:options="dict.type.PROPOSAL_CASE_FILING_TYPE"
:value="selectedTask.ext.tf_caseFilingType"></dict-tag> :value="selectedTask.ext.tf_caseFilingType"></dict-tag>
<span v-else>--</span>
</van-cell> </van-cell>
<template <template
v-if="['CONFIRM_FILING', 'SUGGESTION'].includes(selectedTask.ext.tf_caseFilingResult)"> v-if="['CONFIRM_FILING', 'SUGGESTION'].includes(selectedTask.ext.tf_caseFilingResult)">
@@ -187,7 +199,7 @@ const PROPOSAL_INFO = {
</template> </template>
<template v-else> <template v-else>
<van-cell title="办理单位" <van-cell title="承办单位"
v-if="['opinion_unit_reply', 'unit_reply', 'two_unit_reply', 'opinion_master_reply', 'master_reply', 'slave_reply'].includes(selectedTask.taskName)"> v-if="['opinion_unit_reply', 'unit_reply', 'two_unit_reply', 'opinion_master_reply', 'master_reply', 'slave_reply'].includes(selectedTask.taskName)">
{{ selectedTask.ext.underTakeName || '--' }} {{ selectedTask.ext.underTakeName || '--' }}
</van-cell> </van-cell>
@@ -379,9 +379,6 @@ layout("/layouts/platform_h5.html"){
v-model="formData.bankOfDeposit" v-model="formData.bankOfDeposit"
label="开户行" label="开户行"
maxlength="20" maxlength="20"
type="textarea"
rows="4"
autosize
placeholder="请填写开户行" placeholder="请填写开户行"
:rules="[{ required: true }]" :rules="[{ required: true }]"
required required
@@ -247,7 +247,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true) 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() { confirmPendingAction() {
@@ -264,7 +264,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true) 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() { confirmPendingAction() {
@@ -247,7 +247,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true) 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() { confirmPendingAction() {
@@ -247,7 +247,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true) 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() { confirmPendingAction() {
@@ -327,7 +327,7 @@ layout("/layouts/platform_h5.html"){
<van-radio-group class="difficult-help-apply-mode" :value="formData.mode" @input="formData.mode !== $event && modeChange($event)" direction="horizontal" icon-size="14px"> <van-radio-group class="difficult-help-apply-mode" :value="formData.mode" @input="formData.mode !== $event && modeChange($event)" direction="horizontal" icon-size="14px">
<van-radio name="1" shape="square">本人申请</van-radio> <van-radio name="1" shape="square">本人申请</van-radio>
<van-radio <van-radio
v-if="$auth.hasRoleOr('BRANCH_UNION_CHAIRMAN')" v-if="canApplyForOthers"
name="2" shape="square">替他人申请 name="2" shape="square">替他人申请
</van-radio> </van-radio>
</van-radio-group> </van-radio-group>
@@ -723,6 +723,9 @@ layout("/layouts/platform_h5.html"){
} }
}, },
computed: { computed: {
canApplyForOthers() {
return this.$auth.hasPermissionOr(['difficult_assistance_school', 'difficult_assistance_union'])
},
canImportFamilyInfo() { canImportFamilyInfo() {
return false; return false;
} }
@@ -731,7 +734,7 @@ layout("/layouts/platform_h5.html"){
historyBack, historyBack,
// 替他人申请时由只读字段主动打开受助人选择,已有业务数据时保持原禁止更换规则。 // 替他人申请时由只读字段主动打开受助人选择,已有业务数据时保持原禁止更换规则。
openRecipientPopup() { openRecipientPopup() {
if (this.formData.mode !== "2" || this.formData.id) return if (this.formData.mode !== "2" || this.formData.id || !this.canApplyForOthers) return
this.$set(this, "recipientSearchKey", "") this.$set(this, "recipientSearchKey", "")
this.$set(this, "recipientHasSearched", false) this.$set(this, "recipientHasSearched", false)
this.$set(this, "subsidizedList", []) this.$set(this, "subsidizedList", [])
@@ -995,7 +998,7 @@ layout("/layouts/platform_h5.html"){
* recipientSearchKey 传搜索关键词;接口返回用户数组,列表仅展示姓名和单位。 * recipientSearchKey 传搜索关键词;接口返回用户数组,列表仅展示姓名和单位。
*/ */
queryRecipients() { queryRecipients() {
if (this.formData.mode !== "2") { if (this.formData.mode !== "2" || !this.canApplyForOthers) {
return return
} }
const key = (this.recipientSearchKey || "").trim() const key = (this.recipientSearchKey || "").trim()
@@ -1044,6 +1047,7 @@ layout("/layouts/platform_h5.html"){
this.$set(this.formData, "userName", null) this.$set(this.formData, "userName", null)
this.$set(this.formData, "loginName", null) this.$set(this.formData, "loginName", null)
this.$set(this.formData, "sex", null) this.$set(this.formData, "sex", null)
this.$set(this.formData, "birthday", null)
this.$set(this.formData, "unitId", null) this.$set(this.formData, "unitId", null)
this.$set(this.formData, "unitName", null) this.$set(this.formData, "unitName", null)
this.$set(this.formData, "unionId", null) this.$set(this.formData, "unionId", null)
@@ -1108,6 +1112,8 @@ layout("/layouts/platform_h5.html"){
this.$set(this.formData, 'idCard', user.idCard) this.$set(this.formData, 'idCard', user.idCard)
this.$set(this.formData, 'mobile', user.mobile) this.$set(this.formData, 'mobile', user.mobile)
this.$set(this.formData, 'homeAddress', user.homeAddress) this.$set(this.formData, 'homeAddress', user.homeAddress)
this.$set(this.formData, 'position', user.position || '')
this.$set(this.formData, 'officialCapacity', user.professionalTitle || '')
this.$set(this.formData, 'subsidyStandards', null) this.$set(this.formData, 'subsidyStandards', null)
this.$set(this.formData, 'reason', null) this.$set(this.formData, 'reason', null)
this.$set(this.formData, 'remarks', null) this.$set(this.formData, 'remarks', null)
@@ -80,6 +80,7 @@ layout("/layouts/platform_h5.html"){
<table-column label="工作单位">{{row.unitName}}</table-column> <table-column label="工作单位">{{row.unitName}}</table-column>
<table-column label="困难类型">{{row.subsidyStandards}}</table-column> <table-column label="困难类型">{{row.subsidyStandards}}</table-column>
<table-column label="填报时间">{{row.applyTime}}</table-column> <table-column label="填报时间">{{row.applyTime}}</table-column>
<table-column label="申请金额(元)">{{row.applyMoney}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column> <table-column label="当前节点">{{row.curTaskName}}</table-column>
</template> </template>
<template #actions="{index,row}"> <template #actions="{index,row}">
@@ -126,8 +127,8 @@ layout("/layouts/platform_h5.html"){
show-word-limit show-word-limit
></van-field> ></van-field>
<section class="difficult-help-info-card"> <section class="difficult-help-info-card">
<h2 class="difficult-help-info-card__title">审批签字</h2> <h2 class="difficult-help-info-card__title">审批签字<span class="difficult-help-audit-card__required">*</span></h2>
<van-field name="tf_sign" :value="formData.tf_sign" required :rules="[{required:true,message:'请完成审批签字'}]"> <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> <template #input><h5-signature v-model="formData.tf_sign" :key="formData.processTaskId"></h5-signature></template>
</van-field> </van-field>
</section> </section>
@@ -257,7 +258,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return
this.$set(this, "confirmVisible", true) 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)
})
})
}, },
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。 // 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
@@ -167,11 +167,11 @@
} }
.difficult-help-info-card .van-cell__title { .difficult-help-info-card .van-cell__title {
width: 112px; width: 102px;
color: #596779; color: #596779;
font-size: 12px; font-size: 12px;
line-height: 24px; line-height: 24px;
flex: 0 0 112px; flex: 0 0 102px;
} }
.difficult-help-info-card .van-cell__value { .difficult-help-info-card .van-cell__value {
@@ -184,16 +184,8 @@
} }
.difficult-help-info-long-cell { .difficult-help-info-long-cell {
display: block; display: flex;
} align-items: flex-start;
.difficult-help-info-long-cell .van-cell__title {
width: auto;
max-width: 100%;
}
.difficult-help-info-long-cell .van-cell__value {
margin-top: 7px;
} }
.difficult-help-info-pre-line { .difficult-help-info-pre-line {
@@ -27,6 +27,7 @@ const INFO = {
<van-cell title="填写人工号">{{ viewData.proxyLoginName || '--' }}</van-cell> <van-cell title="填写人工号">{{ viewData.proxyLoginName || '--' }}</van-cell>
<van-cell title="申请金额(元)">{{ viewData.applyMoney }}</van-cell> <van-cell title="申请金额(元)">{{ viewData.applyMoney }}</van-cell>
<van-cell title="性别">{{ viewData.sex || '--' }}</van-cell> <van-cell title="性别">{{ viewData.sex || '--' }}</van-cell>
<van-cell title="身份证号">{{ viewData.idCard || '--' }}</van-cell>
<van-cell title="受助人"> <van-cell title="受助人">
{{ viewData.userName || '--' }}{{ viewData.loginName ? '(' + viewData.loginName + ')' : '' }} {{ viewData.userName || '--' }}{{ viewData.loginName ? '(' + viewData.loginName + ')' : '' }}
</van-cell> </van-cell>
@@ -195,7 +196,7 @@ const INFO = {
<van-cell v-if="task.taskFormData && task.taskFormData.level != null" title="审批级别"> <van-cell v-if="task.taskFormData && task.taskFormData.level != null" title="审批级别">
{{ task.taskFormData.level }} {{ task.taskFormData.level }}
</van-cell> </van-cell>
<van-cell v-if="task.taskFormData && task.taskFormData.money != null" title="帮扶金额(元)"> <van-cell v-if="task.taskFormData && task.taskFormData.money != null" :title="task.taskFormData.actualMoney != null ? '实际审批金额(元)' : '帮扶金额(元)'">
{{ task.taskFormData.money }} {{ task.taskFormData.money }}
</van-cell> </van-cell>
<van-cell title="办理结果"> <van-cell title="办理结果">
@@ -318,7 +318,7 @@ layout("/layouts/platform_h5.html"){
</style> </style>
<div id="app"> <div id="app">
<div class="difficult-help-list-page"> <div class="difficult-help-list-page">
<van-nav-bar title="帮扶申请记录" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar> <van-nav-bar title="我的申请" left-text="返回" left-arrow @click-left="historyBack" placeholder fixed></van-nav-bar>
<van-sticky offset-top="46px"> <van-sticky offset-top="46px">
<div class="difficult-help-list-sticky"> <div class="difficult-help-list-sticky">
<van-search <van-search
@@ -80,6 +80,7 @@ layout("/layouts/platform_h5.html"){
<table-column label="工作单位">{{row.unitName}}</table-column> <table-column label="工作单位">{{row.unitName}}</table-column>
<table-column label="困难类型">{{row.subsidyStandards}}</table-column> <table-column label="困难类型">{{row.subsidyStandards}}</table-column>
<table-column label="填报时间">{{row.applyTime}}</table-column> <table-column label="填报时间">{{row.applyTime}}</table-column>
<table-column label="申请金额(元)">{{row.applyMoney}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column> <table-column label="当前节点">{{row.curTaskName}}</table-column>
</template> </template>
<template #actions="{index,row}"> <template #actions="{index,row}">
@@ -110,6 +111,7 @@ layout("/layouts/platform_h5.html"){
<info ref="infoRef" page-key="difficult-help-school-union-detail" full-screen> <info ref="infoRef" page-key="difficult-help-school-union-detail" full-screen>
<div v-if="showApprovalForm"> <div v-if="showApprovalForm">
<van-form ref="formRef"> <van-form ref="formRef">
<van-cell title="实际审批金额(元)">{{ formData.money != null ? formData.money : '--' }}</van-cell>
<section class="difficult-help-info-card"> <section class="difficult-help-info-card">
<h2 class="difficult-help-info-card__title"> <h2 class="difficult-help-info-card__title">
@@ -128,8 +130,8 @@ layout("/layouts/platform_h5.html"){
></van-field> ></van-field>
</section> </section>
<section class="difficult-help-info-card"> <section class="difficult-help-info-card">
<h2 class="difficult-help-info-card__title">审批签字</h2> <h2 class="difficult-help-info-card__title">审批签字<span class="difficult-help-audit-card__required">*</span></h2>
<van-field name="tf_sign" :value="formData.tf_sign" required :rules="[{required:true,message:'请完成审批签字'}]"> <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> <template #input><h5-signature v-model="formData.tf_sign" :key="formData.processTaskId"></h5-signature></template>
</van-field> </van-field>
</section> </section>
@@ -234,6 +236,7 @@ layout("/layouts/platform_h5.html"){
onApproval(row) { onApproval(row) {
this.$set(this, "showApprovalForm", true) this.$set(this, "showApprovalForm", true)
this.$set(this, "formData", { this.$set(this, "formData", {
money: row.money,
processTaskId: row.taskId, processTaskId: row.taskId,
taskName: row.curTaskName, taskName: row.curTaskName,
id: row.id, id: row.id,
@@ -251,7 +254,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return
this.$set(this, "confirmVisible", true) 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)
})
})
}, },
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。 // 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
@@ -80,6 +80,7 @@ layout("/layouts/platform_h5.html"){
<table-column label="工作单位">{{row.unitName}}</table-column> <table-column label="工作单位">{{row.unitName}}</table-column>
<table-column label="困难类型">{{row.subsidyStandards}}</table-column> <table-column label="困难类型">{{row.subsidyStandards}}</table-column>
<table-column label="填报时间">{{row.applyTime}}</table-column> <table-column label="填报时间">{{row.applyTime}}</table-column>
<table-column label="申请金额(元)">{{row.applyMoney}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column> <table-column label="当前节点">{{row.curTaskName}}</table-column>
</template> </template>
<template #actions="{index,row}"> <template #actions="{index,row}">
@@ -142,8 +143,8 @@ layout("/layouts/platform_h5.html"){
></van-field> ></van-field>
</section> </section>
<section class="difficult-help-info-card"> <section class="difficult-help-info-card">
<h2 class="difficult-help-info-card__title">审批签字</h2> <h2 class="difficult-help-info-card__title">审批签字<span class="difficult-help-audit-card__required">*</span></h2>
<van-field name="tf_sign" :value="formData.tf_sign" required :rules="[{required:true,message:'请完成审批签字'}]"> <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> <template #input><h5-signature v-model="formData.tf_sign" :key="formData.processTaskId"></h5-signature></template>
</van-field> </van-field>
</section> </section>
@@ -265,7 +266,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return
this.$set(this, "confirmVisible", true) 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)
})
})
}, },
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。 // 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
@@ -328,7 +328,7 @@ layout("/layouts/platform_h5.html"){
methods: { methods: {
showInvalidApplicationTab(errors) { showInvalidApplicationTab(errors) {
if (!Array.isArray(errors) || !errors.length) return if (!Array.isArray(errors) || !errors.length) return
const error = errors[0] const error = errors.find(item => !String(item.name || '').startsWith('recipients')) || errors[0]
const name = String(error.name || '') const name = String(error.name || '')
const recipient = name.match(/^recipients\.(\d+)\./) const recipient = name.match(/^recipients\.(\d+)\./)
this.activeApplicationTab = name.startsWith('recipients') ? 'recipients' : 'form' this.activeApplicationTab = name.startsWith('recipients') ? 'recipients' : 'form'