43 changed files with 394 additions and 146 deletions
@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.exception.BaseException;
import com.budwk.app.sys.models.Sys_file;
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.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
@@ -22,6 +23,7 @@ import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedHashSet;
@@ -39,6 +41,9 @@ public class SysOfficeTemplateUtil {
@Inject
private Dao dao;
@Inject
private SysFileService sysFileService;
public String getTemplateFileName(String templateCode) {
Sys_office_template officeTemplate = dao.fetch(Sys_office_template.class, Cnd.where(Sys_office_template::getTemplateCode, "=", templateCode));
if (ObjectUtil.isNull(officeTemplate)) {
@@ -70,7 +75,16 @@ public class SysOfficeTemplateUtil {
if (ObjectUtil.isEmpty(sysFile)) {
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);
}
@@ -14,6 +14,8 @@ import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
import com.budwk.app.sys.param.SysMsgSummaryPageForm;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.staffbenefit.condolence.model.Condolence;
import com.budwk.app.zhgh.staffbenefit.condolence.service.CondolenceService;
import io.swagger.annotations.Api;
@@ -96,6 +98,7 @@ public class CondolenceReadController {
cnd.andEX("YEAR(info.createTime)", "=", year);
cnd.andEX("info.applyUnionId", "=", unionId);
cnd.andEX("info.applyUnitId", "=", unitId);
applyReadScope(cnd, "info");
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
@@ -142,6 +145,7 @@ public class CondolenceReadController {
cnd.andEX("YEAR(con.createTime)", "=", year);
cnd.andEX("con.applyUnionId", "=", unionId);
cnd.andEX("con.applyUnitId", "=", unitId);
applyReadScope(cnd, "con");
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.or("con.helpUserName", "like", "%" + pageForm.getSearchKeyword() + "%");
@@ -166,4 +170,21 @@ public class CondolenceReadController {
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
CommonDownloadUtil.download("申报人汇总.xlsx", workbook, response);
}
private void applyReadScope(Cnd cnd, String alias) {
if (AuthUtil.hasPermission("condolence_all_school")) {
return;
}
if (AuthUtil.hasPermission("condolence_branch_union")) {
String unionId = SecurityUtil.getUnionId();
if (StrUtil.isNotBlank(unionId)) {
cnd.and(alias + ".applyUnionId", "=", unionId);
return;
}
} else if (AuthUtil.hasPermission("condolence_self")) {
cnd.and(alias + ".createdBy", "=", SecurityUtil.getUserId());
return;
}
cnd.and("1", "=", 0);
}
}
@@ -1,10 +1,10 @@
package com.budwk.app.zhgh.staffbenefit.difficulthelp.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.constant.FlowConst;
@@ -112,7 +112,7 @@ public class DifficultHelpApplyController {
@SaCheckPermission("member.apply.submit")
@SLog(tag = "困难补助申请", msg = "保存申请,填写人: ${args[0].proxyUserName}")
public Result save(@Param("data") DifficultHelpInfo difficultHelpInfo) {
difficultHelpCommonService.validateApplyUser(difficultHelpInfo);
difficultHelpCommonService.validateApplyUser(difficultHelpInfo, false);
difficultHelpInfo.setApplyTime(ObjectUtil.defaultIfNull(difficultHelpInfo.getApplyTime(), new Date()));
difficultHelpCommonService.refreshApplyCount(difficultHelpInfo);
if (difficultHelpCommonService.hasAppliedInYear(difficultHelpInfo.getUserId(), difficultHelpInfo.getApplyTime(), difficultHelpInfo.getId())) {
@@ -177,12 +177,13 @@ public class DifficultHelpApplyController {
@At
@ApiOperation("获取受助人")
@SaCheckPermission("difficultHelp.apply")
@SaCheckPermission(value = {"difficultHelp.apply", "h5.difficultHelp.apply"}, mode = SaMode.OR)
public Result queryRecipients(String key){
if (!AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
return Result.error("只有分工会主席可以替他人申请");
boolean schoolScope = AuthUtil.hasPermission("difficult_assistance_school");
if (!schoolScope && !AuthUtil.hasPermission("difficult_assistance_union")) {
return Result.error("没有代申请权限");
}
if (Strings.isBlank(SecurityUtil.getUnionId())) {
if (!schoolScope && Strings.isBlank(SecurityUtil.getUnionId())) {
return Result.error("当前用户未设置所属分工会");
}
Sql sql = Sqls.create("""
@@ -193,6 +194,10 @@ public class DifficultHelpApplyController {
birthday,
mobile,
sex,
idCard,
position,
professionalTitle AS officialCapacity,
(SELECT u.homeAddress FROM sys_user u WHERE u.id = vw_user.id) AS homeAddress,
unitName,
unionName,
unionId,
@@ -203,7 +208,9 @@ public class DifficultHelpApplyController {
""");
Cnd cnd = Cnd.NEW();
cnd.and("id", "<>", SecurityUtil.getUserId());
cnd.and("unionid", "=", SecurityUtil.getUnionId());
if (!schoolScope) {
cnd.and("unionid", "=", SecurityUtil.getUnionId());
}
if (Strings.isNotBlank(key)) {
SqlExpressionGroup group = new SqlExpressionGroup();
@@ -43,7 +43,8 @@ public class DifficultHelpApprovalController {
}
ProcessTask task = dao.fetch(ProcessTask.class, args.getLong(FlowConst.PROCESS_TASK_ID_KEY));
if (task == null) throw new BaseException("审批任务不存在");
boolean amountApproval = "715ece82-4ae3-433c-ad18-ed875f45d1e3".equals(task.getTaskName());
boolean actualAmountApproval = "e405f96c-5fc0-4f63-b323-e69dfe853253".equals(task.getTaskName());
boolean amountApproval = "715ece82-4ae3-433c-ad18-ed875f45d1e3".equals(task.getTaskName()) || actualAmountApproval;
if (!amountApproval && !"36ebafda-44c2-4bd3-bd7f-10839a575a0d".equals(task.getTaskName())
&& !"e405f96c-5fc0-4f63-b323-e69dfe853253".equals(task.getTaskName())) {
throw new BaseException("当前任务不是困难帮扶审批任务");
@@ -56,12 +57,17 @@ public class DifficultHelpApprovalController {
args.remove("level");
args.remove("tf_level");
args.remove("tf_actualMoney");
Double money = amountApproval ? args.getDouble("money") : null;
if (amountApproval) {
if (money == null || !Double.isFinite(money) || money < 0) {
throw new BaseException("请填写有效的帮扶金额");
throw new BaseException(actualAmountApproval ? "请填写有效的实际审批金额" : "请填写有效的帮扶金额");
}
if (actualAmountApproval && java.math.BigDecimal.valueOf(money).stripTrailingZeros().scale() > 2) {
throw new BaseException("实际审批金额最多保留两位小数");
}
args.put("tf_money", money);
if (actualAmountApproval) args.put("tf_actualMoney", money);
} else {
args.remove("money");
args.remove("tf_money");
@@ -78,6 +78,7 @@ public class DifficultHelpFirstApprovalController {
info.subsidyStandards,
LEFT(info.applyTime, 10) AS applyTime,
info.applyCount,
info.applyMoney,
info.mobile,
ins.id AS instanceId,
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.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckLogin;
@@ -154,7 +153,7 @@ public class DifficultHelpReadingController {
""");
Cnd cnd = Cnd.NEW();
cnd.and("ins.state", "=", 20);
pageParam.buildSearch(cnd, "info.", false);
pageParam.buildReadingSearch(cnd, "info.");
cnd.groupBy("info.id");
sql.setCondition(cnd);
Pagination<NutMap> pagination = difficultHelpCommonService.listPageMap(pageParam.getPageNumber(), pageParam.getPageSize(), sql);
@@ -269,7 +268,7 @@ public class DifficultHelpReadingController {
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.", false);
pageParam.buildReadingSearch(cnd, "info.");
cnd.groupBy("info.id");
sql.setCondition(cnd);
List<NutMap> list = difficultHelpCommonService.listMap(sql);
@@ -327,11 +326,33 @@ public class DifficultHelpReadingController {
@At
@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 {
DifficultHelpInfo difficultHelp = difficultHelpCommonService.fetch(id);
if (difficultHelp == null) {
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("该记录不在当前可查看的范围内,无法导出");
}
}
HashMap<String, Object> docData = new HashMap<>();
docData.put("unionName", difficultHelp.getUnitName());
@@ -493,6 +514,7 @@ public class DifficultHelpReadingController {
info.subsidyStandards,
info.bankOfDeposit,
info.bankCardNum,
info.money,
info.applyCount
FROM
difficult_help_info info
@@ -500,16 +522,44 @@ public class DifficultHelpReadingController {
$condition
""");
Cnd cnd = Cnd.NEW();
pageParam.buildSearch(cnd, "info.", false);
pageParam.buildReadingSearch(cnd, "info.");
cnd.groupBy("info.id");
sql.setCondition(cnd);
List<NutMap> list = difficultHelpCommonService.listMap(sql);
Sys_user user = sysUserService.fetch(SecurityUtil.getUserId());
for (int i = 0; i < list.size(); i++) {
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("year", DateUtil.format(new Date(), "yyyy"));
result.put("applyTime", DateUtil.format(new Date(), "yyyy年MM月dd日"));
@@ -517,32 +567,12 @@ public class DifficultHelpReadingController {
result.put("mobile", user.getMobile());
result.put("da", list);
String resource;
if ("xlsx".equals(flag)) {
resource = "difficulty_summary_xlsx";
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 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 ("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)) {
if ("docx".equals(flag)) {
try (InputStream input = sysOfficeTemplateUtil.getTemplate(resource)) {
Configure config = Configure.builder()
.bind("da", new LoopRowTableRenderPolicy())
@@ -79,6 +79,7 @@ public class DifficultHelpSecondApprovalController {
info.subsidyStandards,
LEFT(info.applyTime, 10) AS applyTime,
info.applyCount,
info.applyMoney,
info.mobile,
ins.id AS instanceId,
ins.businessNo,
@@ -82,6 +82,7 @@ public class DifficultHelpThirdApprovalController {
info.subsidyStandards,
LEFT(info.applyTime, 10) AS applyTime,
info.applyCount,
info.applyMoney,
info.mobile,
ins.id AS instanceId,
ins.businessNo,
@@ -21,6 +21,8 @@ public interface DifficultHelpCommonService extends BaseService<DifficultHelpInf
void validateApplyUser(DifficultHelpInfo difficultHelpInfo);
void validateApplyUser(DifficultHelpInfo difficultHelpInfo, boolean requireApplyMoney);
/**
* 导入实际金额数据处理
* @param file 文件
@@ -4,7 +4,6 @@ import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
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.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
@@ -56,6 +55,11 @@ public class DifficultHelpCommonServiceImpl extends BaseServiceImpl<DifficultHel
@Override
public void validateApplyUser(DifficultHelpInfo difficultHelpInfo) {
validateApplyUser(difficultHelpInfo, true);
}
@Override
public void validateApplyUser(DifficultHelpInfo difficultHelpInfo, boolean requireApplyMoney) {
if (difficultHelpInfo == null || StrUtil.isBlank(difficultHelpInfo.getUserId())) {
throw new BaseException("请选择受助人");
}
@@ -65,19 +69,29 @@ public class DifficultHelpCommonServiceImpl extends BaseServiceImpl<DifficultHel
throw new BaseException("只能查看他人代为申请的记录,不能修改或提交");
}
}
if (difficultHelpInfo.getApplyMoney() == null || !Double.isFinite(difficultHelpInfo.getApplyMoney())
|| difficultHelpInfo.getApplyMoney() <= 0) {
if ((requireApplyMoney || difficultHelpInfo.getApplyMoney() != null)
&& (difficultHelpInfo.getApplyMoney() == null || !Double.isFinite(difficultHelpInfo.getApplyMoney())
|| difficultHelpInfo.getApplyMoney() <= 0)) {
throw new BaseException("请填写大于零的申请金额");
}
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;
}
if (!AuthUtil.hasRoleOr(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
throw new BaseException("只有分工会主席可以替他人申请");
boolean schoolScope = AuthUtil.hasPermission("difficult_assistance_school");
if (!schoolScope && !AuthUtil.hasPermission("difficult_assistance_union")) {
throw new BaseException("没有代申请权限");
}
View_user recipient = dao().fetch(View_user.class, Cnd.where("id", "=", difficultHelpInfo.getUserId()));
if (recipient == null || StrUtil.isBlank(SecurityUtil.getUnionId())
|| !SecurityUtil.getUnionId().equals(recipient.getUnionId())) {
if (recipient == null) {
throw new BaseException("受助人不存在");
}
if (!schoolScope && (StrUtil.isBlank(SecurityUtil.getUnionId())
|| !SecurityUtil.getUnionId().equals(recipient.getUnionId()))) {
throw new BaseException("只能替本分工会人员申请");
}
}
@@ -123,10 +137,7 @@ public class DifficultHelpCommonServiceImpl extends BaseServiceImpl<DifficultHel
// 2. 查询符合条件的 DifficultHelpInfo 记录
Cnd cnd = Cnd.NEW();
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
cnd.and(Cnd.exps("loginName", "LIKE", "%" + pageForm.getSearchKeyword() + "%")
.or("userName", "LIKE", "%" + pageForm.getSearchKeyword() + "%"));
}
pageForm.buildReadingSearch(cnd, "");
List<DifficultHelpInfo> infoList = dao().query(DifficultHelpInfo.class, cnd);
// 3. 构建用户缴费索引 (userId -> year -> money)
@@ -9,6 +9,7 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.Cnd;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static;
import org.nutz.lang.Lang;
import java.util.List;
@@ -32,6 +33,29 @@ public class DifficultHelpPageParam extends PageForm {
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){
buildSearch(cnd, prefix, true);
}
@@ -83,7 +83,7 @@ public class SpecialCondolenceApplyController {
public Result save(@Param("data") SpecialCondolence specialcondolence) {
if(StrUtil.isBlank(specialcondolence.getId())) specialcondolence.setCreateTime(DateUtil.now());
prepareApplication(specialcondolence);
specialcondolenceService.saveApplication(specialcondolence);
specialcondolenceService.saveDraftApplication(specialcondolence);
return Result.success();
}
@@ -213,23 +213,20 @@ public class SpecialCondolenceApplyController {
for (int r = 1; r <= sheet.getLastRowNum(); r++) {
org.apache.poi.ss.usermodel.Row excelRow = sheet.getRow(r);
if (excelRow == null) continue;
String prefix = "慰问对象" + (result.size() + 1) + " ";
cn.hutool.json.JSONObject row = new cn.hutool.json.JSONObject();
boolean empty = true;
for (int c = 0; c < fields.length; c++) {
org.apache.poi.ss.usermodel.Cell cell = excelRow.getCell(c);
String value = formatter.formatCellValue(cell).trim();
if (c != 1 && cell != null && cell.getCellType() == org.apache.poi.ss.usermodel.CellType.FORMULA) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行不支持公式,请填写实际值");
if ((c == 2 || c == 5) && cell != null && cell.getCellType() == org.apache.poi.ss.usermodel.CellType.NUMERIC) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行工号、身份证和收款账户请使用文本格式,避免数字失真");
if (c != 1 && cell != null && cell.getCellType() == org.apache.poi.ss.usermodel.CellType.FORMULA) throw new com.budwk.app.base.exception.BaseException(prefix + "不支持公式,请填写实际值");
if ((c == 2 || c == 5) && cell != null && cell.getCellType() == org.apache.poi.ss.usermodel.CellType.NUMERIC) throw new com.budwk.app.base.exception.BaseException(prefix + "工号、身份证和收款账户请使用文本格式,避免数字失真");
row.set(fields[c], value);
empty = empty && value.isEmpty();
}
if (empty) continue;
for (int c = 0; c < fields.length; c++) {
if (c != 1 && row.getStr(fields[c]).isEmpty()) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行:请填写" + headers[c]);
}
if (!com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceRecipients.validIdCard(row.getStr("idCard"))) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行身份证号码格式不正确");
if (!row.getStr("bankCardNumber").matches("[0-9]{6,30}")) throw new com.budwk.app.base.exception.BaseException("第" + (r + 1) + "行收款账户格式不正确");
com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceRecipients.resolveUser(row, dao, "第" + (r + 1) + "行:");
if (!com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceRecipients.validIdCard(row.getStr("idCard"))) throw new com.budwk.app.base.exception.BaseException(prefix + "身份证号码格式不正确");
if (!row.getStr("bankCardNumber").matches("[0-9]{6,30}")) throw new com.budwk.app.base.exception.BaseException(prefix + "收款账户格式不正确");
result.add(row);
}
}
@@ -71,6 +71,7 @@ public class SpecialCondolenceReadController {
Sql sql = Sqls.create("""
SELECT
info.*,
(SELECT COUNT(*) FROM special_condolence_recipient recipient WHERE recipient.applyId = info.id AND recipient.delFlag = false) AS recipientCount,
ins.id AS instanceId,
type.name as typeName,
ins.state instanceState,
@@ -32,7 +32,7 @@ public final class SpecialCondolenceRecipients {
row.set("type", info.getType());
row.set("money", info.getPerMoney().toPlainString());
row.set("occurTime", info.getOccurTime());
resolveUser(row, dao, prefix);
if (cn.hutool.core.util.StrUtil.isNotBlank(row.getStr("helpUserId"))) resolveUser(row, dao, prefix);
String[] fields = {"helpUserName", "type", "idCard", "bankOfDeposit", "bankUserName", "bankCardNumber", "money", "occurTime"};
for (String field : fields) {
String value = row.getStr(field);
@@ -80,24 +80,27 @@ public final class SpecialCondolenceRecipients {
if (cn.hutool.core.util.StrUtil.isNotBlank(userId)) {
user = dao.fetch(com.budwk.app.sys.views.View_user.class, org.nutz.dao.Cnd.where("id", "=", userId));
} else {
org.nutz.dao.Cnd identity = org.nutz.dao.Cnd.where("unionId", "=", unionId)
.and("idCard", "=", row.getStr("idCard")).and("username", "=", row.getStr("helpUserName"));
java.util.List<com.budwk.app.sys.views.View_user> dispatched = dao.query(com.budwk.app.sys.views.View_user.class,
identity.and("personType", "=", "劳务派遣人员"));
if (dispatched.size() > 1) throw new BaseException(prefix + "劳务派遣人员身份重复,请核对档案");
if (dispatched.size() == 1) {
user = dispatched.get(0);
} else {
if (cn.hutool.core.util.StrUtil.isBlank(row.getStr("helpLoginName"))) throw new BaseException(prefix + "普通人员必须填写工号");
java.util.List<com.budwk.app.sys.views.View_user> users = dao.query(com.budwk.app.sys.views.View_user.class,
org.nutz.dao.Cnd.where("unionId", "=", unionId).and("loginname", "=", row.getStr("helpLoginName"))
.and("username", "=", row.getStr("helpUserName")).and("idCard", "=", row.getStr("idCard")));
if (users.size() != 1) throw new BaseException(prefix + "工号、姓名、身份证不匹配或不属于申请人本工会");
user = users.get(0);
java.util.List<com.budwk.app.sys.views.View_user> users = dao.query(com.budwk.app.sys.views.View_user.class,
org.nutz.dao.Cnd.where("idCard", "=", row.getStr("idCard"))
.and("username", "=", row.getStr("helpUserName")));
if (users.isEmpty()) throw new BaseException(prefix + "姓名、身份证与人员档案不匹配");
java.util.List<com.budwk.app.sys.views.View_user> members = users.stream()
.filter(member -> java.util.Objects.equals(member.getUnionId(), unionId))
.collect(java.util.stream.Collectors.toList());
if (members.isEmpty()) throw new BaseException(prefix + "只能选择申请人本工会人员");
String loginName = row.getStr("helpLoginName");
if (cn.hutool.core.util.StrUtil.isNotBlank(loginName)) {
members = members.stream().filter(member -> "劳务派遣人员".equals(member.getPersonType())
|| java.util.Objects.equals(member.getLoginname(), loginName))
.collect(java.util.stream.Collectors.toList());
}
if (members.isEmpty()) throw new BaseException(prefix + "工号与慰问对象不一致");
if (members.size() > 1) throw new BaseException(prefix + "人员身份重复,请核对档案");
user = members.get(0);
}
if (user == null) throw new BaseException(prefix + "慰问对象不存在");
if (!java.util.Objects.equals(user.getUnionId(), unionId)) throw new BaseException(prefix + "只能选择申请人本工会人员");
if (!"劳务派遣人员".equals(user.getPersonType()) && cn.hutool.core.util.StrUtil.isBlank(row.getStr("helpLoginName"))) throw new BaseException(prefix + "普通人员必须填写工号");
if (!"劳务派遣人员".equals(user.getPersonType()) && (cn.hutool.core.util.StrUtil.isBlank(row.getStr("helpLoginName")) || !java.util.Objects.equals(user.getLoginname(), row.getStr("helpLoginName")))) throw new BaseException(prefix + "工号与慰问对象不一致");
if (cn.hutool.core.util.StrUtil.isNotBlank(user.getIdCard()) && !user.getIdCard().equalsIgnoreCase(row.getStr("idCard"))) throw new BaseException(prefix + "身份证号码与所选人员不一致");
row.set("helpUserId", user.getId());
@@ -12,6 +12,7 @@ import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolence
*/
public interface SpecialCondolenceService extends BaseService<SpecialCondolence> {
void saveApplication(SpecialCondolence info);
void saveDraftApplication(SpecialCondolence info);
SpecialCondolence loadApplication(String id);
void deleteApplication(String id);
}
@@ -3,6 +3,7 @@ package com.budwk.app.zhgh.staffbenefit.specialcondolence.service.impl;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.zhgh.staffbenefit.specialcondolence.model.SpecialCondolenceRecipient;
import com.budwk.app.zhgh.staffbenefit.specialcondolence.service.SpecialCondolenceRecipients;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.nutz.ioc.aop.Aop;
@@ -35,6 +36,28 @@ public class SpecialCondolenceServiceImpl extends BaseServiceImpl<SpecialCondole
@Aop(TransAop.READ_COMMITTED)
public void saveApplication(SpecialCondolence info) {
SpecialCondolenceRecipients.prepare(info, dao());
persistApplication(info);
}
@Override
@Aop(TransAop.READ_COMMITTED)
public void saveDraftApplication(SpecialCondolence info) {
if (info.getRecipients() == null) info.setRecipients(new ArrayList<>());
info.getRecipients().removeIf(row -> row == null || java.util.stream.Stream.of(
"helpUserId", "helpUserName", "helpLoginName", "idCard", "bankOfDeposit", "bankUserName", "bankCardNumber")
.allMatch(field -> StrUtil.isBlank(row.getStr(field))));
for (JSONObject row : info.getRecipients()) {
row.set("type", info.getType());
row.set("typeCode", info.getTypeCode());
row.set("way", info.getWay());
row.set("money", info.getPerMoney());
row.set("occurTime", info.getOccurTime());
}
info.setMoney(info.getPerMoney() == null ? null : info.getPerMoney().multiply(BigDecimal.valueOf(info.getRecipients().size())).doubleValue());
persistApplication(info);
}
private void persistApplication(SpecialCondolence info) {
dao().insertOrUpdate(info);
dao().clear(SpecialCondolenceRecipient.class,
Cnd.where("applyId", "=", info.getId()));
@@ -42,20 +65,20 @@ public class SpecialCondolenceServiceImpl extends BaseServiceImpl<SpecialCondole
for (JSONObject row : info.getRecipients()) {
SpecialCondolenceRecipient person = new SpecialCondolenceRecipient();
person.setApplyId(info.getId());
person.setHelpUserName(row.getStr("helpUserName"));
person.setHelpUserId(row.getStr("helpUserId"));
person.setHelpUserName(row.getStr("helpUserName", ""));
person.setHelpUserId(row.getStr("helpUserId", ""));
person.setHelpLoginName(row.getStr("helpLoginName"));
person.setPersonType(row.getStr("personType"));
person.setType(row.getStr("type"));
person.setType(row.getStr("type", ""));
person.setTypeName(row.getStr("typeName"));
person.setTypeCode(row.getStr("typeCode"));
person.setWay(row.getStr("way"));
person.setIdCard(row.getStr("idCard"));
person.setBankOfDeposit(row.getStr("bankOfDeposit"));
person.setBankUserName(row.getStr("bankUserName"));
person.setBankCardNumber(row.getStr("bankCardNumber"));
person.setMoney(new BigDecimal(row.getStr("money")));
person.setOccurTime(row.getStr("occurTime"));
person.setIdCard(row.getStr("idCard", ""));
person.setBankOfDeposit(row.getStr("bankOfDeposit", ""));
person.setBankUserName(row.getStr("bankUserName", ""));
person.setBankCardNumber(row.getStr("bankCardNumber", ""));
person.setMoney(row.getBigDecimal("money", BigDecimal.ZERO));
person.setOccurTime(row.getStr("occurTime", ""));
person.setSortNum(sort++);
dao().insert(person);
}
@@ -0,0 +1,7 @@
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, processKey, platform, moduleId, isQuickEntry, picIcon, initialPinyinName, isRecommendApp, isRecommendService) VALUES ('184d56fd537041caa2bde800d0d32436', '90bf20d9065e4e11864952ea18544c25', '009000040003', '个人范围', null, 'data', null, null, null, false, false, 'self', null, 1027, false, '17a7f8ad3ee947b4a26175049a9c253d', 1793418331288, '17a7f8ad3ee947b4a26175049a9c253d', 1793418331288, false, null, 'PC', null, false, null, null, false, false);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, processKey, platform, moduleId, isQuickEntry, picIcon, initialPinyinName, isRecommendApp, isRecommendService) VALUES ('df87d83ed3184019b3872139c15b53ec', '90bf20d9065e4e11864952ea18544c25', '009000040002', '分工会范围', null, 'data', null, null, null, false, false, 'branch_union', null, 1026, false, '17a7f8ad3ee947b4a26175049a9c253d', 1793418331286, '17a7f8ad3ee947b4a26175049a9c253d', 1793418331286, false, null, 'PC', null, false, null, null, false, false);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, processKey, platform, moduleId, isQuickEntry, picIcon, initialPinyinName, isRecommendApp, isRecommendService) VALUES ('f2a75d2494724978b5325075815808c9', '90bf20d9065e4e11864952ea18544c25', '009000040001', '全校范围', null, 'data', null, null, null, false, false, 'all_school', null, 1025, false, '17a7f8ad3ee947b4a26175049a9c253d', 1793418331280, '17a7f8ad3ee947b4a26175049a9c253d', 1793418331280, false, null, 'PC', null, false, null, null, false, false);
INSERT INTO sys_role_menu (roleId, menuId) VALUES ('fd753e8a8c5a404e8e00ef8e0b0c69da', 'df87d83ed3184019b3872139c15b53ec');
INSERT INTO sys_role_menu (roleId, menuId) VALUES ('494ac71eb8b44d0e99e19b7fde6bd469', 'f2a75d2494724978b5325075815808c9');
INSERT INTO sys_role_menu (roleId, menuId) VALUES ('6aece46b946e4fb9ac4cb15c0cd8c3e6', 'f2a75d2494724978b5325075815808c9');
INSERT INTO sys_role_menu (roleId, menuId) VALUES ('b3854469e6f44901b22bb791cb538431', 'f2a75d2494724978b5325075815808c9');
@@ -25,10 +25,7 @@ module.exports = {
watch: {
value: {
handler(val) {
if (val) {
this.signatureContent = val
this.$emit("input", this.signatureContent)
}
this.signatureContent = val || null
},
immediate: true
}
@@ -62,8 +59,11 @@ module.exports = {
if (res.code !== 0) {
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秒或组件销毁时结束等待。
@@ -16,7 +16,7 @@ layout("/layouts/platform.html"){
<el-form-item prop="mode">
<el-select v-model="formData.mode" placeholder="申请模式" @change="modeChange" style="width: 100%">
<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>
</el-select>
</el-form-item>
@@ -366,6 +366,11 @@ layout("/layouts/platform.html"){
subsidizedList: []
}
},
computed: {
canApplyForOthers() {
return this.$auth.hasPermissionOr(['difficult_assistance_school', 'difficult_assistance_union'])
}
},
methods: {
textRules(label, max) {
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('申请金额须大于零,最多保留两位小数'))
},
// 保存
async onSave() {
const valid = await this.$refs.formRef.validate().catch(() => false)
if (!valid) return
onSave() {
this.$confirm("您确定保存吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
@@ -443,7 +446,7 @@ layout("/layouts/platform.html"){
// 查询受助人
queryRecipients(key) {
if (String(this.formData.mode) !== "2" || !this.$auth.hasRoleOr('BRANCH_UNION_CHAIRMAN')) {
if (String(this.formData.mode) !== "2" || !this.canApplyForOthers) {
return
}
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, 'mobile', user.mobile)
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 {
this.$set(this.formData, 'userId', null)
@@ -490,6 +496,10 @@ layout("/layouts/platform.html"){
this.$set(this.formData, 'unionName', null)
this.$set(this.formData, 'birthday', 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, 'mobile', user.mobile)
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, 'reason', 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 => {
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.$set(this, 'blockMessage', '抱歉,您本年度已申请困难帮扶,不能重复申请。')
} else {
@@ -42,7 +42,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt10">
<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-button label="true">已审核</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: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "applyCount", label: "申请次数", sortable: true },
{ prop: "applyMoney", label: "申请金额(元)", sortable: true },
{ prop: "curTaskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
@@ -8,6 +8,7 @@ const INFO = {
<el-descriptions-item label="填写人姓名">{{ viewData.proxyUserName }}</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.idCard }}</el-descriptions-item>
<el-descriptions-item label="填写人工号">{{ viewData.proxyLoginName }}</el-descriptions-item>
<!--\t\t<el-descriptions-item label="申请模式">{{ viewData.mode == 1 ? '本人申请' : '替他人申请' }}</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="家庭住址" :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">
@@ -90,8 +97,9 @@ const INFO = {
<template v-if="task.taskFormData.level != null">
<el-descriptions-item label="审批级别">{{ task.taskFormData.level }}</el-descriptions-item>
<el-descriptions-item label="帮扶金额(元)">{{ task.taskFormData.money }}</el-descriptions-item>
</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">
@@ -110,7 +118,7 @@ const INFO = {
</div>
`,
store,
dicts: ["PROCESS_TASK_SUBMIT_TYPE"],
dicts: ["PROCESS_TASK_SUBMIT_TYPE", "DIFFICULT_SUBSIDY_TYPE", "DIFFICULT_TYPE"],
data() {
return {
viewData: {},
@@ -45,8 +45,8 @@ layout("/layouts/platform.html"){
<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="exportAllApply" size="small" type="primary">导出申请表(压缩包)</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="exportSummaryXlsx" size="small" type="primary">导出汇总表(Excel)</el-button>
<!-- <el-button @click="exportSummaryDocx" size="small" type="primary">导出汇总表(Word)</el-button> -->
</table-tool>
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
@@ -195,7 +195,7 @@ layout("/layouts/platform.html"){
this.$downLoad('/platform/difficultHelp/reading/exportSummary', params)
},
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() {
@@ -1,5 +1,8 @@
<div id="difficult_help_school_union_approval_form">
<el-form :model="formData" ref="formRef" label-width="100px" label-suffix=":">
<el-form-item label="实际审批金额(元)" prop="money" :rules="[{required:true,type:'number',min:0,message:'请填写不小于零的实际审批金额',trigger:['change','blur']}]">
<el-input-number v-model="formData.money" :precision="2" :min="0" placeholder="请输入实际审批金额"></el-input-number>
</el-form-item>
<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>
</el-form-item>
@@ -17,6 +20,7 @@
return {
businessId: GetQueryString("businessId"),
formData: {
money: undefined,
tf_sign: "", tf_opinion: "",
},
}
@@ -42,7 +42,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt10">
<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-button label="true">已审核</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-form :model="formData" ref="formData" label-width="100px">
<el-form-item label="实际审批金额(元)" prop="money" :rules="[{required:true,type:'number',min:0,message:'请填写不小于零的实际审批金额',trigger:['change','blur']}]">
<el-input-number v-model="formData.money" :precision="2" :min="0" placeholder="请输入实际审批金额"></el-input-number>
</el-form-item>
<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>
</el-form-item>
@@ -103,6 +106,9 @@ layout("/layouts/platform.html"){
{{formData.taskName}}
</div>
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="100px" label-suffix=":">
<el-form-item label="实际审批金额(元)" prop="money" :rules="[{required:true,type:'number',min:0,message:'请填写不小于零的实际审批金额',trigger:['change','blur']}]">
<el-input-number v-model="formData.money" :precision="2" :min="0" placeholder="请输入实际审批金额"></el-input-number>
</el-form-item>
<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>
@@ -146,7 +152,7 @@ layout("/layouts/platform.html"){
{ prop: "mobile", label: "联系方式", sortable: true },
{ prop: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "applyCount", label: "申请次数", sortable: true },
{ prop: "applyMoney", label: "申请金额(元)", sortable: true },
{ prop: "curTaskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
@@ -154,6 +160,7 @@ layout("/layouts/platform.html"){
units: [],
formData: {
money: undefined,
tf_sign: "", tf_opinion: "",
},
showApprovalForm: false,
@@ -178,6 +185,7 @@ layout("/layouts/platform.html"){
this.$message.warning('请至少选择一条记录进行审核!');
return;
}
this.$set(this.formData, 'money', undefined)
this.dialogVisible = true;
},
submitAudit() {
@@ -240,7 +248,7 @@ layout("/layouts/platform.html"){
async approveSingleItem(item) {
const res = await this.$axios.post("/platform/difficultHelp/approval/executeTask", {
data: JSON.stringify({processTaskId: item.taskId, tf_opinion: this.formData.tf_opinion, tf_sign: this.formData.tf_sign, submitType: 1})
data: JSON.stringify({processTaskId: item.taskId, money: this.formData.money, tf_opinion: this.formData.tf_opinion, tf_sign: this.formData.tf_sign, submitType: 1})
})
if (res.code !== 0) throw new Error(res.msg || '审批失败')
},
@@ -248,6 +256,7 @@ layout("/layouts/platform.html"){
this.$refs.guava.edit(()=>{
this.showApprovalForm = true
this.formData = {
money: undefined,
tf_sign: "",
processTaskId: row.taskId,
taskName: row.curTaskName,
@@ -42,7 +42,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="mt10">
<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-button label="true">已审核</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: "subsidyStandards", label: "困难类型", sortable: true },
{ prop: "applyTime", label: "申请时间", sortable: true },
{ prop: "applyCount", label: "申请次数", sortable: true },
{ prop: "applyMoney", label: "申请金额(元)", sortable: true },
{ prop: "curTaskName", label: "当前节点" },
{ prop: "instanceState", label: "流程状态" }
],
@@ -7,7 +7,7 @@
</el-descriptions-item>
<el-descriptions-item label="慰问金额" :span="2">
<el-form-item label="慰问金额" prop="perMoney" :rules="recipientRules.money">
<el-input-number v-model="formData.perMoney" :precision="2" :min="0" :max="10000" :controls="false" style="width:100%" placeholder="每人慰问金额(元)"></el-input-number>
<el-input v-model="formData.perMoney" readonly style="width:100%" placeholder="根据慰问类型自动带出"></el-input>
</el-form-item>
</el-descriptions-item>
<el-descriptions-item label="慰问时间" :span="2">
@@ -51,7 +51,7 @@ layout("/layouts/platform.html"){
</el-descriptions-item>
<el-descriptions-item label="签字" :span="6">
<el-form-item prop="signature" label="签字">
<el-form-item prop="signature" label="签字" class="special-condolence-signature-item">
<pc-signature v-model="formData.signature"></pc-signature>
</el-form-item>
</el-descriptions-item>
@@ -205,8 +205,6 @@ layout("/layouts/platform.html"){
}
},
onSave() {
this.$refs.formRef.validate((valid, invalidFields) => {
if (!valid) { this.showInvalidApplicationTab(invalidFields); return }
this.$confirm("您确定保存吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
@@ -219,11 +217,23 @@ layout("/layouts/platform.html"){
}
})
})
})
},
async validateApplication(callback) {
const form = this.$refs.formRef
const fields = form.fields.filter(field => field.prop && !field.prop.startsWith('recipients'))
const results = await Promise.all(fields.map(field => new Promise(resolve => {
field.validate('', message => resolve(!message))
})))
if (results.some(valid => !valid)) {
this.activeApplicationTab = 'form'
this.$message.error('请完善基础信息的必填信息')
return
}
if (!this.ensureApplicationRecipients()) return
form.validate(callback)
},
onSubmit() {
if (!this.ensureApplicationRecipients()) return
this.$refs.formRef.validate((valid, invalidFields) => {
this.validateApplication((valid, invalidFields) => {
if (!valid) { this.showInvalidApplicationTab(invalidFields); return }
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
@@ -244,8 +254,7 @@ layout("/layouts/platform.html"){
})
},
onFinishTask() {
if (!this.ensureApplicationRecipients()) return
this.$refs.formRef.validate((valid, invalidFields) => {
this.validateApplication((valid, invalidFields) => {
if (!valid) { this.showInvalidApplicationTab(invalidFields); return }
if (valid) {
this.$confirm("您确定要提交吗?", "提示", {
@@ -275,7 +284,7 @@ layout("/layouts/platform.html"){
this.selectQueryUser(this.formData.helpLoginName, this.helpUserOptions)
this.selectQueryUser(this.formData.certifierLoginName, this.certifierUserOptions)
this.selectQueryUser(this.formData.handlerLoginName, this.handlerUserOptions)
this.chooseType = this.typeOptions.find(o => o.id === this.formData.type)
this.chooseType = this.typeOptions.find(o => o.id === this.formData.type) || {}
}
})
} else {
@@ -65,3 +65,5 @@
.special-condolence-apply .flow-task-form .el-form-item__error { color: #f56c6c !important; }
.special-condolence-apply .el-form-item.is-error .el-input__inner,
.special-condolence-apply .el-form-item.is-error .el-textarea__inner { border-color: #f56c6c; }
.special-condolence-apply .flow-task-form .special-condolence-signature-item .el-form-item__error { position: static; padding-top: 6px; line-height: 20px; white-space: normal; }
@@ -8,8 +8,8 @@
<el-form-item prop="recipients" label-width="0" class="special-condolence-table-item">
<el-table ref="recipientTableRef" :data="formData.recipients" border stripe size="small" max-height="520" empty-text="暂无慰问对象,点击新增或从 Excel 导入">
<el-table-column type="index" label="序号" width="55" align="center" fixed="left"></el-table-column>
<el-table-column label="慰问对象" width="200" fixed="left"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.helpUserId'" :rules="recipientRules.helpUserId"><user-select size="small" v-model="s.row.helpUserId" api="/platform/special_condolence/apply/listUser" api_input_key_name="keyword" :option_list="recipientOptions(s.row)" :option_label_func="item => item.userName + '(' + (item.loginName || '') + ')'" @selected="(user, id) => recipientUserChange(s.row, s.$index, id, user)"></user-select></el-form-item></template></el-table-column>
<el-table-column label="工号" min-width="150"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.helpLoginName'" :rules="[{ validator: (rule, value, cb) => cb(s.row.personType === '劳务派遣人员' || value ? undefined : new Error('普通人员工号不能为空')), trigger: 'change' }]"><el-input size="small" v-model="s.row.helpLoginName" readonly placeholder="选人后带出,劳务派遣可空"></el-input></el-form-item></template></el-table-column>
<el-table-column label="慰问对象" width="200" fixed="left"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + (s.row.helpUserId ? '.helpUserId' : '.helpUserName')" :rules="recipientRules.helpUserId"><el-input v-if="!s.row.helpUserId && s.row.helpUserName" size="small" :value="s.row.helpUserName" readonly></el-input><user-select v-else size="small" v-model="s.row.helpUserId" api="/platform/special_condolence/apply/listUser" api_input_key_name="keyword" :option_list="recipientOptions(s.row)" :option_label_func="item => item.userName + '(' + (item.loginName || '') + ')'" @selected="(user, id) => recipientUserChange(s.row, s.$index, id, user)"></user-select></el-form-item></template></el-table-column>
<el-table-column label="工号" min-width="150"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.helpLoginName'" :rules="[{ validator: (rule, value, cb) => cb(!s.row.helpUserId || s.row.personType === '劳务派遣人员' || value ? undefined : new Error('普通人员工号不能为空')), trigger: 'change' }]"><el-input size="small" v-model="s.row.helpLoginName" readonly placeholder="选人后带出,劳务派遣可空"></el-input></el-form-item></template></el-table-column>
<el-table-column label="身份证号码" min-width="205"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.idCard'" :rules="recipientRules.idCard"><el-input size="small" v-model="s.row.idCard" maxlength="18" placeholder="请输入18位身份证号"></el-input></el-form-item></template></el-table-column>
<el-table-column label="开户行" min-width="190"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.bankOfDeposit'" :rules="recipientRules.bankOfDeposit"><el-input size="small" v-model="s.row.bankOfDeposit" maxlength="100" placeholder="请输入开户银行及支行"></el-input></el-form-item></template></el-table-column>
<el-table-column label="户名" min-width="140"><template slot-scope="s"><el-form-item :prop="'recipients.' + s.$index + '.bankUserName'" :rules="recipientRules.bankUserName"><el-input size="small" v-model="s.row.bankUserName" maxlength="100" placeholder="请输入账户户名"></el-input></el-form-item></template></el-table-column>
@@ -34,7 +34,7 @@ const specialCondolenceRecipients = {
},
ensureApplicationRecipients() {
const rows = this.formData.recipients
if (!Array.isArray(rows) || rows.length === 0 || rows.some(row => !row || !String(row.helpUserId || '').trim())) {
if (!Array.isArray(rows) || rows.length === 0 || rows.some(row => !row || !String(row.helpUserId || row.helpUserName || '').trim())) {
this.activeApplicationTab = 'recipients'
this.notifyRecipientError('请先选择慰问对象,并填写完整信息')
return false
@@ -95,15 +95,18 @@ const specialCondolenceRecipients = {
try {
const data = new FormData()
data.append('file', request.file)
const result = await this.$axios.post('/platform/special_condolence/apply/importRecipients', data)
const response = await axios.post('/platform/special_condolence/apply/importRecipients', data, {
headers: { 'x-requested-with': 'XMLHttpRequest' }
})
const result = response.data
if (result.code === 0) {
const rows = this.formData.recipients.filter(r => r.helpUserName || r.type || r.idCard || r.bankCardNumber || r.bankUserName || r.bankOfDeposit || r.money)
this.$set(this.formData, 'recipients', rows.concat(result.data))
this.importVisible = false
this.$message.success('导入成功,共' + result.data.length + '人')
} else this.$message.error(result.msg || '导入失败')
} else this.$message.error('导入失败:' + (result.msg || '请检查文件内容后重试'))
} catch (error) {
this.$message.error('导入失败,请检查文件内容后重试')
this.$message.error('导入失败:' + (error.response?.data?.msg || error.msg || '请检查文件内容后重试'))
} finally {
this.importLoading = false
}
@@ -110,7 +110,7 @@ layout("/layouts/platform.html"){
{prop: 'applyUnionName', label: '所属工会'},
{prop: 'applyUnitName', label: '所属单位'},
{prop: 'typeName', label: '慰问类型'},
{prop: 'taskName', label: '当前节点'},
{prop: 'recipientCount', label: '慰问人数'},
{prop: 'instanceState', label: '流程状态'},
],
unionList: [],
@@ -379,9 +379,6 @@ layout("/layouts/platform_h5.html"){
v-model="formData.bankOfDeposit"
label="开户行"
maxlength="20"
type="textarea"
rows="4"
autosize
placeholder="请填写开户行"
:rules="[{ required: true }]"
required
@@ -247,7 +247,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {
@@ -264,7 +264,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {
@@ -247,7 +247,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {
@@ -247,7 +247,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("condolence-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
confirmPendingAction() {
@@ -327,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 name="1" shape="square">本人申请</van-radio>
<van-radio
v-if="$auth.hasRoleOr('BRANCH_UNION_CHAIRMAN')"
v-if="canApplyForOthers"
name="2" shape="square">替他人申请
</van-radio>
</van-radio-group>
@@ -723,6 +723,9 @@ layout("/layouts/platform_h5.html"){
}
},
computed: {
canApplyForOthers() {
return this.$auth.hasPermissionOr(['difficult_assistance_school', 'difficult_assistance_union'])
},
canImportFamilyInfo() {
return false;
}
@@ -731,7 +734,7 @@ layout("/layouts/platform_h5.html"){
historyBack,
// 替他人申请时由只读字段主动打开受助人选择,已有业务数据时保持原禁止更换规则。
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, "recipientHasSearched", false)
this.$set(this, "subsidizedList", [])
@@ -995,7 +998,7 @@ layout("/layouts/platform_h5.html"){
* recipientSearchKey 传搜索关键词;接口返回用户数组,列表仅展示姓名和单位。
*/
queryRecipients() {
if (this.formData.mode !== "2") {
if (this.formData.mode !== "2" || !this.canApplyForOthers) {
return
}
const key = (this.recipientSearchKey || "").trim()
@@ -1044,6 +1047,7 @@ layout("/layouts/platform_h5.html"){
this.$set(this.formData, "userName", null)
this.$set(this.formData, "loginName", null)
this.$set(this.formData, "sex", null)
this.$set(this.formData, "birthday", null)
this.$set(this.formData, "unitId", null)
this.$set(this.formData, "unitName", 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, 'mobile', user.mobile)
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, 'reason', 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.subsidyStandards}}</table-column>
<table-column label="填报时间">{{row.applyTime}}</table-column>
<table-column label="申请金额(元)">{{row.applyMoney}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column>
</template>
<template #actions="{index,row}">
@@ -257,7 +258,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
@@ -27,6 +27,7 @@ const INFO = {
<van-cell title="填写人工号">{{ viewData.proxyLoginName || '--' }}</van-cell>
<van-cell title="申请金额(元)">{{ viewData.applyMoney }}</van-cell>
<van-cell title="性别">{{ viewData.sex || '--' }}</van-cell>
<van-cell title="身份证号">{{ viewData.idCard || '--' }}</van-cell>
<van-cell title="受助人">
{{ viewData.userName || '--' }}{{ viewData.loginName ? '(' + viewData.loginName + ')' : '' }}
</van-cell>
@@ -195,7 +196,7 @@ const INFO = {
<van-cell v-if="task.taskFormData && task.taskFormData.level != null" title="审批级别">
{{ task.taskFormData.level }}
</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 }}
</van-cell>
<van-cell title="办理结果">
@@ -318,7 +318,7 @@ layout("/layouts/platform_h5.html"){
</style>
<div id="app">
<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">
<div class="difficult-help-list-sticky">
<van-search
@@ -80,6 +80,7 @@ layout("/layouts/platform_h5.html"){
<table-column label="工作单位">{{row.unitName}}</table-column>
<table-column label="困难类型">{{row.subsidyStandards}}</table-column>
<table-column label="填报时间">{{row.applyTime}}</table-column>
<table-column label="申请金额(元)">{{row.applyMoney}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column>
</template>
<template #actions="{index,row}">
@@ -110,6 +111,9 @@ layout("/layouts/platform_h5.html"){
<info ref="infoRef" page-key="difficult-help-school-union-detail" full-screen>
<div v-if="showApprovalForm">
<van-form ref="formRef">
<van-field v-model="formData.money" name="money" label="实际审批金额(元)" type="number" required
placeholder="请输入实际审批金额"
:rules="[{validator: value => /^(0|[1-9][0-9]*)(\.[0-9]{1,2})?$/.test(String(value)) && Number.isFinite(Number(value)), message:'请填写不小于零的实际审批金额,最多两位小数'}]"></van-field>
<section class="difficult-help-info-card">
<h2 class="difficult-help-info-card__title">
@@ -234,6 +238,7 @@ layout("/layouts/platform_h5.html"){
onApproval(row) {
this.$set(this, "showApprovalForm", true)
this.$set(this, "formData", {
money: undefined,
processTaskId: row.taskId,
taskName: row.curTaskName,
id: row.id,
@@ -251,7 +256,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
@@ -80,6 +80,7 @@ layout("/layouts/platform_h5.html"){
<table-column label="工作单位">{{row.unitName}}</table-column>
<table-column label="困难类型">{{row.subsidyStandards}}</table-column>
<table-column label="填报时间">{{row.applyTime}}</table-column>
<table-column label="申请金额(元)">{{row.applyMoney}}</table-column>
<table-column label="当前节点">{{row.curTaskName}}</table-column>
</template>
<template #actions="{index,row}">
@@ -265,7 +266,13 @@ layout("/layouts/platform_h5.html"){
if (window.h5HistoryLayerManager && window.h5HistoryLayerManager.open("difficult-help-action-confirm")) return
this.$set(this, "confirmVisible", true)
})
.catch(() => {})
.catch(errors => {
if (!Array.isArray(errors) || !errors.length) return
this.$toast(errors[0].message || '请完善审批信息')
this.$nextTick(() => {
this.$refs.formRef.scrollToField(errors[0].name)
})
})
},
// 确认操作时先回退确认框历史,再根据操作类型调用办理或撤回接口。
@@ -197,7 +197,7 @@ layout("/layouts/platform_h5.html"){
<van-field :value="chooseType.name || formData.typeName" name="type" label="慰问类型" readonly clickable is-link required placeholder="请选择慰问类型" :rules="[{ validator: () => !!formData.type, message: '请选择慰问类型' }]" @click="showTypePickerClick"></van-field>
<van-popup v-model="showTypePicker" position="bottom" round get-container="body"><van-picker :columns="typeColumns" :default-index="typeDefaultIndex" show-toolbar @confirm="onTypeConfirm" @cancel="showTypePicker = false"></van-picker></van-popup>
<van-field v-model="formData.perMoney" name="perMoney" label="每人金额" type="number" required :rules="[{ validator: validateMoney, message: '金额须大于0且不超过10000元,最多两位小数' }]"></van-field>
<van-field v-model="formData.perMoney" name="perMoney" label="慰问金额" type="number" readonly required :rules="[{ validator: validateMoney, message: '金额须大于0且不超过10000元,最多两位小数' }]"></van-field>
<van-field v-model="formData.occurTime" name="occurTime" label="慰问时间" readonly clickable is-link placeholder="请选择慰问时间" required :rules="[{ validator: value => $moment(value, 'YYYY-MM-DD', true).isValid(), message: '请选择有效慰问时间' }]" @click="showTimePickerClick"></van-field>
<van-popup v-model="showTimePicker" position="bottom" round get-container="body"><van-datetime-picker v-if="showTimePicker" v-model="formData.occurDate" type="date" :min-date="minDate" :max-date="maxDate" title="请选择慰问时间" @confirm="confirmOccurTime" @cancel="showTimePicker = false"></van-datetime-picker></van-popup>
<van-field
@@ -258,7 +258,7 @@ layout("/layouts/platform_h5.html"){
<div v-for="(person, index) in formData.recipients" :key="index">
<van-cell :title="'慰问对象 ' + (index + 1)" :title-style="{ fontWeight: 'bold' }"><van-button native-type="button" size="mini" @click="formData.recipients.splice(index, 1)">删除</van-button></van-cell>
<h5-user-select v-model="person.helpUserId" :display-name="person.helpUserName" api="/platform/special_condolence/apply/listUser" label="慰问对象" placeholder="点击选择本工会人员" required :name="'recipients.' + index + '.helpUserId'" :rules="mobileRecipientRules('helpUserId', person)" @selected="(user, id) => recipientUserChange(person, index, id, user)"></h5-user-select>
<van-field v-model="person.helpLoginName" label="工号" readonly placeholder="选人后带出,劳务派遣可空" :required="person.personType !== '劳务派遣人员'" :name="'recipients.' + index + '.helpLoginName'" :rules="mobileRecipientRules('helpLoginName', person)"></van-field>
<van-field v-model="person.helpLoginName" label="工号" readonly placeholder="选人后带出,劳务派遣可空" :required="!!person.helpUserId && person.personType !== '劳务派遣人员'" :name="'recipients.' + index + '.helpLoginName'" :rules="mobileRecipientRules('helpLoginName', person)"></van-field>
<van-field v-model="person.idCard" label="身份证号码" maxlength="18" required :name="'recipients.' + index + '.idCard'" :rules="mobileRecipientRules('idCard', person)"></van-field>
<van-field v-model="person.bankOfDeposit" label="开户行" maxlength="100" required :name="'recipients.' + index + '.bankOfDeposit'" :rules="mobileRecipientRules('bankOfDeposit', person)"></van-field>
<van-field v-model="person.bankUserName" label="户名" maxlength="100" required :name="'recipients.' + index + '.bankUserName'" :rules="mobileRecipientRules('bankUserName', person)"></van-field>
@@ -328,7 +328,7 @@ layout("/layouts/platform_h5.html"){
methods: {
showInvalidApplicationTab(errors) {
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 recipient = name.match(/^recipients\.(\d+)\./)
this.activeApplicationTab = name.startsWith('recipients') ? 'recipients' : 'form'
@@ -340,8 +340,8 @@ layout("/layouts/platform_h5.html"){
},
mobileRecipientRules(field, person) {
const names = { helpUserId: '慰问对象', helpLoginName: '工号', idCard: '身份证号码', bankOfDeposit: '开户行', bankUserName: '户名', bankCardNumber: '收款账户' }
if (field === 'helpLoginName') return [{ validator: value => person.personType === '劳务派遣人员' || !!String(value || '').trim(), message: '普通人员工号不能为空' }]
if (field === 'helpUserId') return [{ validator: () => !!person.helpUserId, message: '请选择慰问对象' }]
if (field === 'helpLoginName') return [{ validator: value => !person.helpUserId || person.personType === '劳务派遣人员' || !!String(value || '').trim(), message: '请完善慰问对象信息(工号不能为空)' }]
if (field === 'helpUserId') return [{ validator: () => !!(person.helpUserId || person.helpUserName), message: '请选择慰问对象' }]
const rules = [{ validator: value => !!String(value || '').trim(), message: '请填写' + names[field] }]
if (field === 'idCard') rules.push({ validator: value => this.validRecipientIdCard(value), message: '身份证号码不正确' })
if (field === 'bankCardNumber') rules.push({ pattern: /^[0-9]{6,30}$/, message: '收款账户须为6至30位数字' })
@@ -464,7 +464,6 @@ layout("/layouts/platform_h5.html"){
this.showTypePicker = false
},
onSave() {
this.$refs.formRef.validate().then(() => {
this.$dialog.confirm({
title: "提示",
message: "您确定保存吗?"
@@ -476,7 +475,6 @@ layout("/layouts/platform_h5.html"){
}
})
})
}).catch(errors => this.showInvalidApplicationTab(errors))
},
async onSubmit() {
this.$refs.formRef.validate().then(() => {