会员入会流程
This commit is contained in:
+45
@@ -1,6 +1,8 @@
|
||||
package com.budwk.app.zhgh.staffmanage.member.controller.apply;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
@@ -24,6 +26,49 @@ public class MemberApplyCommonController {
|
||||
@Inject
|
||||
private MemberApplyRecordService memberApplyRecordService;
|
||||
|
||||
/**
|
||||
* PC、手机端按申请记录查看当次填写的资料。
|
||||
*
|
||||
* @param recordId member_apply_record 的记录 ID,不是会员 userId 或流程任务 ID
|
||||
* @return Result,data 为申请快照,包含申请人资料及 applyDateTime 申请时间
|
||||
*/
|
||||
@At
|
||||
@SaCheckLogin
|
||||
@SaCheckPermission(value = {"member.apply.mine", "member.apply.branchUnionAudit", "member.apply.schoolUnionAudit",
|
||||
"h5.member.apply.mine", "h5.member.apply.branch", "h5.member.apply.school"}, mode = SaMode.OR)
|
||||
public Result findApplyRecord(@Valid String recordId) {
|
||||
return Result.success(memberApplyRecordService.findApplyRecordForView(recordId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前申请的提交和审核历史。
|
||||
*
|
||||
* @param recordId 申请记录 ID,不是会员 ID
|
||||
* @return Result.data 为记录列表,每项含 nodeCode、nodeName、operatorName、operatorLoginName、
|
||||
* handledAt、result、originalResult、opinion、signature;撤回后的原审核仍保留办理内容
|
||||
*/
|
||||
@At
|
||||
@SaCheckLogin
|
||||
@SaCheckPermission(value = {"member.apply.mine", "member.apply.branchUnionAudit", "member.apply.schoolUnionAudit",
|
||||
"h5.member.apply.mine", "h5.member.apply.branch", "h5.member.apply.school"}, mode = SaMode.OR)
|
||||
public Result approvalRecords(@Valid String recordId) {
|
||||
return Result.success(memberApplyRecordService.listApplyApprovalRecords(recordId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为两端入会查看页面提供同一份资料变更信息。
|
||||
*
|
||||
* @param recordId 申请记录 ID
|
||||
* @return Result.data 为变更项列表,name 为字段标题,value 为原值,newValue 为申请值
|
||||
*/
|
||||
@At
|
||||
@SaCheckLogin
|
||||
@SaCheckPermission(value = {"member.apply.mine", "member.apply.branchUnionAudit", "member.apply.schoolUnionAudit",
|
||||
"h5.member.apply.mine", "h5.member.apply.branch", "h5.member.apply.school"}, mode = SaMode.OR)
|
||||
public Result findApplyChanges(@Valid String recordId) {
|
||||
return Result.success(memberApplyRecordService.findApplyChangesForView(recordId));
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckLogin
|
||||
public Result findOne(@Valid String id) {
|
||||
|
||||
+13
@@ -58,6 +58,17 @@ public class MemberApplyController {
|
||||
public void index() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询当前用户能否新建入会申请,供 PC 入口和 H5 申请页共用。
|
||||
*
|
||||
* @return Result.data 为 Boolean;true 表示可新建,false 表示已有进行中的申请
|
||||
*/
|
||||
@At
|
||||
@SaCheckPermission(value = {"member.apply.submit", "h5.member.apply.submit"}, mode = SaMode.OR)
|
||||
public Result canStartNewApply() {
|
||||
return Result.success(memberApplyRecordService.canStartNewApply());
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission(value = {"member.apply.submit","member.branchUnion.record","member.schoolUnion.record"}, mode = SaMode.OR)
|
||||
@@ -77,6 +88,7 @@ public class MemberApplyController {
|
||||
@SaCheckPermission("member.apply.submit")
|
||||
@SLog(tag = "会员管理-入会申请-保存申请", msg = "保存申请")
|
||||
public Result doSave(MemberApplyRecord record){
|
||||
memberApplyRecordService.checkCanSaveOrSubmit(record.getId());
|
||||
record.setMember(true);
|
||||
record.setUserId(SecurityUtil.getUserId());
|
||||
record.setChangeOrigin(MemberChangeOrigin.PERSONAL.name());
|
||||
@@ -98,6 +110,7 @@ public class MemberApplyController {
|
||||
@SaCheckPermission("member.apply.submit")
|
||||
@SLog(tag = "会员管理-入会申请-提交申请", msg = "提交申请")
|
||||
public Object doSubmit(MemberApplyRecord record) {
|
||||
memberApplyRecordService.checkCanSaveOrSubmit(record.getId());
|
||||
record.setMember(true);
|
||||
record.setUserId(SecurityUtil.getUserId());
|
||||
record.setChangeType(MemberChangeType.RESTORE.name());
|
||||
|
||||
+9
-9
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.staffmanage.member.controller.apply;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.BpmProcessConstant;
|
||||
@@ -51,7 +52,7 @@ public class MemberApplyMineController {
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("member.apply.mine")
|
||||
@SaCheckPermission(value = {"member.apply.mine", "h5.member.apply.mine"}, mode = SaMode.OR)
|
||||
public Result pageData(MemberApplyPageForm pageForm) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
@@ -101,12 +102,9 @@ public class MemberApplyMineController {
|
||||
MemberApplyPageForm.buildSearch(cnd, pageForm);
|
||||
cnd.and("nd.nodeCode", "=", 10);
|
||||
cnd.and("define.`code`", "=", BpmProcessConstant.MEMBER_SINGLE_APPLY.name());
|
||||
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
|
||||
if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())) {
|
||||
cnd.andEX("vu.unionId","=", SecurityUtil.getUnionId());
|
||||
} else {
|
||||
cnd.and("vu.id", "=", SecurityUtil.getUserId());
|
||||
}
|
||||
// “我的申请”仅系统管理员可查看全部,其他角色固定按申请记录归属查询。
|
||||
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
|
||||
cnd.and("record.userId", "=", SecurityUtil.getUserId());
|
||||
}
|
||||
cnd.desc("record.applyDateTime");
|
||||
sql.setCondition(cnd);
|
||||
@@ -117,9 +115,10 @@ public class MemberApplyMineController {
|
||||
@At
|
||||
@ApiOperation("删除会员申请记录")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission("member.apply.mine")
|
||||
@SaCheckPermission(value = {"member.apply.mine", "h5.member.apply.mine"}, mode = SaMode.OR)
|
||||
@SLog(tag = "会员管理-入会申请-我的申请记录", msg = "删除申请")
|
||||
public Result delete(@Valid String id) {
|
||||
memberApplyRecordService.checkMineRecordAccess(id);
|
||||
memberApplyRecordService.delete(id);
|
||||
bpmService.deleteInstance(id);
|
||||
return Result.success();
|
||||
@@ -129,9 +128,10 @@ public class MemberApplyMineController {
|
||||
@At
|
||||
@ApiOperation("个人申请撤回")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission("member.apply.mine")
|
||||
@SaCheckPermission(value = {"member.apply.mine", "h5.member.apply.mine"}, mode = SaMode.OR)
|
||||
@SLog(tag = "会员管理-入会申请-个人申请撤回", msg = "个人申请撤回")
|
||||
public Result revokeApply(@Valid String id) {
|
||||
memberApplyRecordService.checkMineRecordAccess(id);
|
||||
bpmService.revokeApply(id);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
+12
-11
@@ -1,7 +1,7 @@
|
||||
package com.budwk.app.zhgh.staffmanage.member.controller.apply;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.BpmProcessConstant;
|
||||
@@ -9,7 +9,6 @@ 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.bpm.enums.BpmProcessTaskStatusEnum;
|
||||
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
|
||||
import com.budwk.app.bpm.param.BpmTaskApprovalParam;
|
||||
import com.budwk.app.bpm.service.BpmService;
|
||||
import com.budwk.app.sys.models.Sys_user_history;
|
||||
@@ -64,7 +63,7 @@ public class MemberApplySchoolUnionAuditController {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("member.apply.schoolUnionAudit")
|
||||
@SaCheckPermission(value = {"member.apply.schoolUnionAudit", "h5.member.apply.school"}, mode = SaMode.OR)
|
||||
public Result pageData(MemberApplyPageForm pageForm) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
@@ -123,17 +122,19 @@ public class MemberApplySchoolUnionAuditController {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校工会审核入会申请,PC、H5 共用同一保存入口。
|
||||
*
|
||||
* @param approvalParam approval JSON 中的实例、申请、任务 ID,审核类型、意见及签名图片 URL
|
||||
* @return Result,code 为 0 表示审核及签名保存成功,msg 为结果提示
|
||||
*/
|
||||
@At
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@ApiOperation("会员入会校工会审核")
|
||||
@SaCheckPermission("member.apply.branchUnionAudit")
|
||||
@SaCheckPermission(value = {"member.apply.schoolUnionAudit", "h5.member.apply.school"}, mode = SaMode.OR)
|
||||
@SLog(tag = "会员管理-会员入会申请-校工会审核", msg = "会员入会审核(校工会)")
|
||||
public Result approval(@Param("approval") @Valid BpmTaskApprovalParam approvalParam) {
|
||||
if (approvalParam.getBpmTaskApprovalTypeEnum().equals(BpmTaskApprovalTypeEnum.PASS)) {
|
||||
MemberApplyRecord record = memberManageService.dao().fetch(MemberApplyRecord.class, Cnd.where("id", "=", approvalParam.getProcessInstanceBusinessId()));
|
||||
memberManageService.compareMemberChangeInfoAndUpdateUser(record);
|
||||
}
|
||||
bpmService.completeTask(approvalParam.getProcessInstanceTaskId(), approvalParam.getBpmTaskApprovalTypeEnum(), null, null);
|
||||
memberApplyRecordService.approveSchoolApply(approvalParam);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ public class MemberApplySchoolUnionAuditController {
|
||||
@At
|
||||
@ApiOperation("校工会审核撤回")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission("member.apply.branchUnionAudit")
|
||||
@SaCheckPermission("member.apply.schoolUnionAudit")
|
||||
@SLog(tag = "会员管理-入会申请-校工会撤回", msg = "校工会入会审核撤回")
|
||||
public Result revoke(@Valid String taskId) {
|
||||
bpmService.revokeTask(taskId);
|
||||
@@ -155,7 +156,7 @@ public class MemberApplySchoolUnionAuditController {
|
||||
* @return
|
||||
*/
|
||||
@At
|
||||
@SaCheckPermission(value = "member.apply.branchUnionAudit")
|
||||
@SaCheckPermission(value = "member.apply.schoolUnionAudit")
|
||||
public Result findAuditChangeInfo(@Valid String recordId){
|
||||
Sys_user_history history = memberApplyRecordService.dao().fetch(Sys_user_history.class, Cnd.where("recordId", "=", recordId).or("id","=",recordId));
|
||||
MemberApplyRecord record = memberApplyRecordService.dao().fetch(MemberApplyRecord.class, recordId);
|
||||
|
||||
+58
@@ -1,13 +1,71 @@
|
||||
package com.budwk.app.zhgh.staffmanage.member.service;
|
||||
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.bpm.param.BpmTaskApprovalParam;
|
||||
import com.budwk.app.zhgh.staffmanage.member.models.MemberApplyRecord;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 会员申请记录
|
||||
*/
|
||||
public interface MemberApplyRecordService extends BaseService<MemberApplyRecord> {
|
||||
|
||||
/**
|
||||
* 判断当前登录人是否可以新建入会申请。
|
||||
*
|
||||
* @return 没有进行中的入会流程时返回 true,否则返回 false
|
||||
*/
|
||||
boolean canStartNewApply();
|
||||
|
||||
/**
|
||||
* 校验当前登录人保存或提交的入会申请,已有进行中申请时仅允许操作该申请本身。
|
||||
*
|
||||
* @param recordId 本次申请记录 ID;新建申请时为空,编辑已有申请时传该记录 ID
|
||||
* @throws com.budwk.app.base.exception.BaseException 记录不属于当前用户或存在另一条进行中申请时抛出
|
||||
*/
|
||||
void checkCanSaveOrSubmit(String recordId);
|
||||
|
||||
/**
|
||||
* 校验“我的申请”记录访问范围,只有系统管理员可操作他人的申请。
|
||||
*
|
||||
* @param recordId member_apply_record 的记录 ID,不能为空
|
||||
* @throws com.budwk.app.base.exception.BaseException 记录不存在或非系统管理员访问他人记录时抛出
|
||||
*/
|
||||
void checkMineRecordAccess(String recordId);
|
||||
|
||||
/**
|
||||
* 查询当前登录人有权查看的申请快照,不使用会员当前资料替代申请内容。
|
||||
*
|
||||
* @param recordId member_apply_record 的申请记录 ID
|
||||
* @return 该次申请保存的 MemberApplyRecord,包含申请人资料及 applyDateTime 申请时间
|
||||
*/
|
||||
MemberApplyRecord findApplyRecordForView(String recordId);
|
||||
|
||||
/**
|
||||
* 查询同一次入会申请的提交、重新提交及审核任务,包含待办和撤回状态。
|
||||
*
|
||||
* @param recordId 申请记录 ID,按申请归属校验访问权限
|
||||
* @return 每项包含节点、办理人、时间、结果、撤回前原结果、意见和签名图片 URL;
|
||||
* 未办理的撤回任务不返回,无流程时返回空列表
|
||||
*/
|
||||
List<NutMap> listApplyApprovalRecords(String recordId);
|
||||
|
||||
/**
|
||||
* 查询有权查看的申请所涉及的资料变更。
|
||||
*
|
||||
* @param recordId 申请记录 ID
|
||||
* @return 变更项列表,每项含字段名、原值和新值;已审核记录优先使用保存的变更历史
|
||||
*/
|
||||
List<NutMap> findApplyChangesForView(String recordId);
|
||||
|
||||
/**
|
||||
* 校工会办理入会申请,同一事务内更新会员资料并保存审核意见、签名和结果。
|
||||
*
|
||||
* @param approvalParam 当前实例、业务和任务标识,审核类型、意见及签名图片 URL
|
||||
*/
|
||||
void approveSchoolApply(BpmTaskApprovalParam approvalParam);
|
||||
|
||||
void startProcess(MemberApplyRecord memberApplyRecord, Long processDefineId);
|
||||
}
|
||||
|
||||
+260
@@ -1,15 +1,44 @@
|
||||
package com.budwk.app.zhgh.staffmanage.member.service.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.budwk.app.base.constant.BpmProcessConstant;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.bpm.enums.BpmProcessInstanceStatusEnum;
|
||||
import com.budwk.app.bpm.enums.BpmProcessNodeTypeEnum;
|
||||
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
||||
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
|
||||
import com.budwk.app.bpm.models.BpmProcessDefine;
|
||||
import com.budwk.app.bpm.models.BpmProcessInstance;
|
||||
import com.budwk.app.bpm.models.BpmProcessNodeDefine;
|
||||
import com.budwk.app.bpm.models.BpmProcessTask;
|
||||
import com.budwk.app.bpm.param.BpmTaskApprovalParam;
|
||||
import com.budwk.app.bpm.service.BpmService;
|
||||
import com.budwk.app.sys.models.Sys_user_history;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.wf2.enums.FlowConst;
|
||||
import com.budwk.app.wf2.service.ProcessInstanceService;
|
||||
import com.budwk.app.zhgh.staffmanage.member.models.MemberApplyRecord;
|
||||
import com.budwk.app.zhgh.staffmanage.member.service.MemberApplyRecordService;
|
||||
import com.budwk.app.zhgh.staffmanage.member.service.MemberManageService;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class MemberApplyRecordServiceImpl extends BaseServiceImpl<MemberApplyRecord> implements MemberApplyRecordService {
|
||||
@@ -20,6 +49,237 @@ public class MemberApplyRecordServiceImpl extends BaseServiceImpl<MemberApplyRec
|
||||
@Inject
|
||||
private ProcessInstanceService processInstanceService;
|
||||
|
||||
@Inject
|
||||
private BpmService bpmService;
|
||||
|
||||
@Inject
|
||||
private MemberManageService memberManageService;
|
||||
|
||||
/**
|
||||
* 入会申请入口仅在本人没有进行中的同类流程时允许新建。
|
||||
*
|
||||
* @return 没有进行中的入会申请时返回 true
|
||||
*/
|
||||
@Override
|
||||
public boolean canStartNewApply() {
|
||||
return !hasRunningApply(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存和提交共用的重复申请校验;编辑原申请时排除该记录,避免阻断重新提交。
|
||||
*
|
||||
* @param recordId 本次记录 ID;新建时为 null
|
||||
*/
|
||||
@Override
|
||||
public void checkCanSaveOrSubmit(String recordId) {
|
||||
if (StrUtil.isNotBlank(recordId)) {
|
||||
MemberApplyRecord record = fetch(recordId);
|
||||
if (record != null && !StrUtil.equals(SecurityUtil.getUserId(), record.getUserId())) {
|
||||
throw new BaseException("不能修改他人的入会申请");
|
||||
}
|
||||
}
|
||||
if (hasRunningApply(recordId)) {
|
||||
throw new BaseException("您有进行中的入会申请,请先处理已有申请");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* “我的申请”操作只允许系统管理员跨用户访问,普通角色以申请记录归属为准。
|
||||
*
|
||||
* @param recordId 申请记录 ID,不能为空
|
||||
*/
|
||||
@Override
|
||||
public void checkMineRecordAccess(String recordId) {
|
||||
if (StrUtil.isBlank(recordId)) {
|
||||
throw new BaseException("申请记录不能为空");
|
||||
}
|
||||
MemberApplyRecord record = fetch(recordId);
|
||||
if (record == null) {
|
||||
throw new BaseException("申请记录不存在");
|
||||
}
|
||||
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())
|
||||
&& !StrUtil.equals(SecurityUtil.getUserId(), record.getUserId())) {
|
||||
throw new BaseException("没有权限操作该申请记录");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅匹配当前登录人的入会流程实例,忽略已结束流程和本次编辑的记录。
|
||||
*
|
||||
* @param excludedRecordId 本次编辑的申请记录 ID,新建时为空
|
||||
* @return 是否存在另一条 RUNNING 状态的入会流程
|
||||
*/
|
||||
private boolean hasRunningApply(String excludedRecordId) {
|
||||
List<String> recordIds = query(Cnd.where("userId", "=", SecurityUtil.getUserId())
|
||||
.and("delFlag", "=", false)).stream()
|
||||
.map(MemberApplyRecord::getId)
|
||||
.filter(id -> !StrUtil.equals(id, excludedRecordId))
|
||||
.toList();
|
||||
if (recordIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
BpmProcessDefine define = dao().fetch(BpmProcessDefine.class,
|
||||
Cnd.where("code", "=", BpmProcessConstant.MEMBER_SINGLE_APPLY.name()));
|
||||
if (define == null) {
|
||||
throw new BaseException("入会申请流程定义不存在");
|
||||
}
|
||||
return dao().count(BpmProcessInstance.class,
|
||||
Cnd.where("processDefineId", "=", define.getId())
|
||||
.and("processInstanceBusinessId", "in", recordIds)
|
||||
.and("delFlag", "=", false)
|
||||
.and("processInstanceStatus", "=", BpmProcessInstanceStatusEnum.RUNNING.name())) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按申请记录归属校验查看范围,保证会员资料后来发生变化时仍展示原申请内容。
|
||||
*
|
||||
* @param recordId 申请记录 ID,不能为空
|
||||
* @return 申请资料及申请时间;记录不存在或无权查看时抛出业务异常
|
||||
*/
|
||||
@Override
|
||||
public MemberApplyRecord findApplyRecordForView(String recordId) {
|
||||
if (StrUtil.isBlank(recordId)) {
|
||||
throw new BaseException("申请记录不能为空");
|
||||
}
|
||||
MemberApplyRecord record = fetch(recordId);
|
||||
if (record == null) {
|
||||
throw new BaseException("申请记录不存在");
|
||||
}
|
||||
|
||||
// 校级管理员可查看全校申请,申请人可查看本人保存的申请。
|
||||
if (AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(),
|
||||
RoleConstant.SCHOOL_UNION_MEMBER_ADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())
|
||||
|| StrUtil.equals(SecurityUtil.getUserId(), record.getUserId())) {
|
||||
return record;
|
||||
}
|
||||
|
||||
// 分工会主席仅能查看申请所属分工会的记录,空工会 ID 不作为授权依据。
|
||||
String unionId = SecurityUtil.getUnionId();
|
||||
if (AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name())
|
||||
&& StrUtil.isNotBlank(unionId) && StrUtil.equals(unionId, record.getUnionId())) {
|
||||
return record;
|
||||
}
|
||||
throw new BaseException("没有权限查看该申请记录");
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> listApplyApprovalRecords(String recordId) {
|
||||
// 先校验申请访问范围,不能仅凭客户端传入的业务 ID 查询他人的审核历史。
|
||||
findApplyRecordForView(recordId);
|
||||
List<BpmProcessInstance> instances = dao().query(BpmProcessInstance.class,
|
||||
Cnd.where("processInstanceBusinessId", "=", recordId).and("delFlag", "=", false));
|
||||
if (instances.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<String> instanceIds = instances.stream().map(BpmProcessInstance::getId).toList();
|
||||
List<BpmProcessTask> tasks = dao().query(BpmProcessTask.class,
|
||||
Cnd.where("processInstanceId", "in", instanceIds).and("delFlag", "=", false)
|
||||
.asc("createdOn").asc("createdAt").asc("id"));
|
||||
if (tasks.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
// START、BACK 节点保留申请及重新提交记录,不能像通用审核查询那样只读取 TASK 节点。
|
||||
List<String> nodeIds = tasks.stream().map(BpmProcessTask::getProcessTaskNodeId).distinct().toList();
|
||||
Set<String> applyNodeIds = dao().query(BpmProcessNodeDefine.class, Cnd.where("id", "in", nodeIds)).stream()
|
||||
.filter(node -> BpmProcessNodeTypeEnum.START.name().equals(node.getNodeType())
|
||||
|| BpmProcessNodeTypeEnum.BACK.name().equals(node.getNodeType()))
|
||||
.map(BpmProcessNodeDefine::getId).collect(Collectors.toSet());
|
||||
List<NutMap> records = new ArrayList<>();
|
||||
for (BpmProcessTask task : tasks) {
|
||||
boolean complete = BpmProcessTaskStatusEnum.COMPLETE.name().equals(task.getTaskStatus())
|
||||
|| BpmProcessTaskStatusEnum.AUTO_COMPLETE.name().equals(task.getTaskStatus())
|
||||
|| BpmProcessTaskStatusEnum.TRANSFER.name().equals(task.getTaskStatus());
|
||||
JSONObject savedVariable = task.getExtVariable() == null ? new JSONObject() : task.getExtVariable();
|
||||
String approvalType = StrUtil.blankToDefault(savedVariable.getStr("bpmTaskApprovalType"), "");
|
||||
// 撤回会把原已办任务恢复为 ACTIVE,但其完成时间和审核变量仍在;这些字段属于原审核记录。
|
||||
boolean withdrawnApproval = !complete && task.getEndOn() != null
|
||||
&& List.of("PASS", "REJECT", "BACK", "BACK_OTHER_NODE").contains(approvalType)
|
||||
&& !applyNodeIds.contains(task.getProcessTaskNodeId());
|
||||
// 后续自动生成的 REVOKE 任务未经审核,不应显示为一条只有“已撤回”的审核记录。
|
||||
if (BpmProcessTaskStatusEnum.REVOKE.name().equals(task.getTaskStatus()) && !withdrawnApproval) {
|
||||
continue;
|
||||
}
|
||||
boolean handled = complete || withdrawnApproval;
|
||||
JSONObject variable = handled ? savedVariable : new JSONObject();
|
||||
String originalResult = switch (approvalType) {
|
||||
case "PASS" -> "同意";
|
||||
case "REJECT" -> "建议撤销";
|
||||
case "BACK", "BACK_OTHER_NODE" -> "退回";
|
||||
default -> null;
|
||||
};
|
||||
String result = switch (StrUtil.blankToDefault(task.getTaskStatus(), "")) {
|
||||
case "ACTIVE" -> withdrawnApproval ? "已撤回" : "待处理";
|
||||
case "REVOKE" -> "已撤回";
|
||||
case "TRANSFER" -> "已转办";
|
||||
case "AUTO_COMPLETE" -> "自动完成";
|
||||
case "COMPLETE" -> switch (approvalType) {
|
||||
case "PASS" -> "同意";
|
||||
case "REJECT" -> "建议撤销";
|
||||
case "BACK", "BACK_OTHER_NODE" -> "退回";
|
||||
case "APPLY" -> "已提交";
|
||||
default -> applyNodeIds.contains(task.getProcessTaskNodeId()) ? "已提交" : "已办理";
|
||||
};
|
||||
default -> "暂无";
|
||||
};
|
||||
records.add(NutMap.NEW()
|
||||
.addv("id", task.getId()).addv("nodeCode", task.getProcessTaskNodeCode())
|
||||
.addv("nodeName", task.getProcessTaskNodeName())
|
||||
.addv("operatorName", handled ? task.getActualOwnerUserName() : null)
|
||||
.addv("operatorLoginName", handled ? task.getActualOwnerLoginName() : null)
|
||||
.addv("handledAt", handled && task.getEndOn() != null ? DateUtil.formatDateTime(task.getEndOn()) : null)
|
||||
.addv("result", result)
|
||||
.addv("originalResult", withdrawnApproval ? originalResult : null)
|
||||
.addv("opinion", variable.getStr("approvalOpinion"))
|
||||
.addv("signature", variable.getStr("approvalSignature")));
|
||||
}
|
||||
return records;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> findApplyChangesForView(String recordId) {
|
||||
MemberApplyRecord record = findApplyRecordForView(recordId);
|
||||
// 审核后会员当前资料已经更新,应优先使用当时保存的变更信息。
|
||||
Sys_user_history history = dao().fetch(Sys_user_history.class,
|
||||
Cnd.where("recordId", "=", recordId).or("id", "=", recordId));
|
||||
return history == null ? memberManageService.compareMemberChangeInfo(record)
|
||||
: memberManageService.compareMemberChangeInfo(history);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void approveSchoolApply(BpmTaskApprovalParam approvalParam) {
|
||||
BpmTaskApprovalTypeEnum approvalType = approvalParam.getBpmTaskApprovalTypeEnum();
|
||||
if (!List.of(BpmTaskApprovalTypeEnum.PASS, BpmTaskApprovalTypeEnum.BACK, BpmTaskApprovalTypeEnum.REJECT).contains(approvalType)) {
|
||||
throw new BaseException("校工会审核类型不正确");
|
||||
}
|
||||
BpmProcessTask task = dao().fetch(BpmProcessTask.class, approvalParam.getProcessInstanceTaskId());
|
||||
if (task == null || Boolean.TRUE.equals(task.getDelFlag())
|
||||
|| !BpmProcessTaskStatusEnum.ACTIVE.name().equals(task.getTaskStatus())) {
|
||||
throw new BaseException("审核任务不存在或已处理,请刷新后重试");
|
||||
}
|
||||
BpmProcessInstance instance = dao().fetch(BpmProcessInstance.class, task.getProcessInstanceId());
|
||||
// 任务、实例和申请必须属于同一次审核,避免用另一条申请的参数更新会员资料。
|
||||
if (instance == null || !StrUtil.equals(instance.getId(), approvalParam.getProcessInstanceId())
|
||||
|| !StrUtil.equals(instance.getProcessInstanceBusinessId(), approvalParam.getProcessInstanceBusinessId())
|
||||
|| !Integer.valueOf(50).equals(task.getProcessTaskNodeCode())) {
|
||||
throw new BaseException("审核任务与申请不匹配");
|
||||
}
|
||||
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())
|
||||
&& (task.getAssignments() == null || !task.getAssignments().contains(SecurityUtil.getUserLoginname()))) {
|
||||
throw new BaseException("当前用户不是该任务的审核人");
|
||||
}
|
||||
MemberApplyRecord record = fetch(approvalParam.getProcessInstanceBusinessId());
|
||||
if (record == null) {
|
||||
throw new BaseException("申请记录不存在");
|
||||
}
|
||||
if (approvalType == BpmTaskApprovalTypeEnum.PASS) {
|
||||
memberManageService.compareMemberChangeInfoAndUpdateUser(record);
|
||||
}
|
||||
// 完成任务时将意见、签名 URL、审核类型一并写入任务扩展变量,供 PC、手机端回显。
|
||||
bpmService.completeTask(task.getId(), approvalType, BeanUtil.beanToMap(approvalParam), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startProcess(MemberApplyRecord record, Long processDefineId) {
|
||||
Dict dict = Dict.create();
|
||||
|
||||
@@ -8,7 +8,9 @@
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<van-popup v-model="showSignaturePanel" :style="{ height: '100vh', width: '100vw' }">
|
||||
<van-popup v-model="showSignaturePanel" get-container="body" :close-on-click-overlay="false"
|
||||
:style="{ height: '100vh', width: '100vw' }">
|
||||
<van-button class="signature-close" size="small" native-type="button" @click="closeSignature">返回</van-button>
|
||||
<signature @save="save"></signature>
|
||||
</van-popup>
|
||||
</div>
|
||||
@@ -42,7 +44,12 @@ module.exports = {
|
||||
},
|
||||
methods: {
|
||||
openSignature() {
|
||||
this.showSignaturePanel = true
|
||||
// 签字弹框独立占一层历史;返回键先关闭签字板,再返回审核详情。
|
||||
h5PopupHistory.open(this._uid)
|
||||
this.$set(this, "showSignaturePanel", true)
|
||||
},
|
||||
closeSignature() {
|
||||
h5PopupHistory.close(this._uid)
|
||||
},
|
||||
|
||||
save(signature) {
|
||||
@@ -61,8 +68,8 @@ module.exports = {
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
alert("保存成功")
|
||||
this.showSignaturePanel = false
|
||||
this.$emit("input", res.data)
|
||||
this.closeSignature()
|
||||
} else {
|
||||
alert("保存失败")
|
||||
}
|
||||
@@ -87,7 +94,14 @@ module.exports = {
|
||||
return new File([blob], filename, { type: contentType })
|
||||
}
|
||||
},
|
||||
created() {}
|
||||
mounted() {
|
||||
h5PopupHistory.register(this._uid, () => {
|
||||
this.$set(this, "showSignaturePanel", false)
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
h5PopupHistory.unregister(this._uid)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -101,4 +115,11 @@ module.exports = {
|
||||
|
||||
.main-panel .open-button {
|
||||
}
|
||||
|
||||
.signature-close {
|
||||
position: fixed;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="signature-wrap">
|
||||
<canvas id="canvas"></canvas>
|
||||
<canvas ref="canvas"></canvas>
|
||||
<div class="action-buttons">
|
||||
<button @click="clear" class="action-button-danger" type="button">清空</button>
|
||||
<button @click="undo" class="action-button-warning" type="button">撤销</button>
|
||||
@@ -30,7 +30,6 @@
|
||||
// window.addEventListener("orientationchange", a)
|
||||
// a()
|
||||
|
||||
let signature = null
|
||||
module.exports = {
|
||||
name: "sysSignature",
|
||||
data() {
|
||||
@@ -40,22 +39,22 @@ module.exports = {
|
||||
},
|
||||
methods: {
|
||||
clear() {
|
||||
signature.clear()
|
||||
this.signature.clear()
|
||||
},
|
||||
undo() {
|
||||
signature.undo()
|
||||
this.signature.undo()
|
||||
},
|
||||
rotate() {
|
||||
signature.getRotateCanvas(90)
|
||||
this.signature.getRotateCanvas(90)
|
||||
},
|
||||
save() {
|
||||
if (signature.isEmpty()) {
|
||||
if (this.signature.isEmpty()) {
|
||||
alert("请签字后再保存")
|
||||
return
|
||||
}
|
||||
// const png = signature.getPNG()
|
||||
// const png = this.signature.getPNG()
|
||||
//旋转一下 横过来
|
||||
const rotateCanvas = signature.getRotateCanvas(-90)
|
||||
const rotateCanvas = this.signature.getRotateCanvas(-90)
|
||||
this.$emit("save", rotateCanvas.toDataURL())
|
||||
}
|
||||
},
|
||||
@@ -63,10 +62,11 @@ module.exports = {
|
||||
const innerWidth = window.innerWidth
|
||||
const innerHeight = window.innerHeight
|
||||
|
||||
const canvas = document.getElementById("canvas")
|
||||
// PJAX 切换后旧弹框可能仍在 body 中,只初始化当前签字组件自己的画布。
|
||||
const canvas = this.$refs.canvas
|
||||
canvas.width = window.innerWidth
|
||||
canvas.height = window.innerHeight
|
||||
signature = new SmoothSignature(canvas, {
|
||||
this.signature = new SmoothSignature(canvas, {
|
||||
width: innerWidth - 30,
|
||||
height: innerHeight - 30,
|
||||
scale: 2,
|
||||
|
||||
@@ -81,6 +81,58 @@
|
||||
callback(true)
|
||||
}
|
||||
|
||||
// 所有 H5 弹框共用一个返回键监听;每打开一层都对应一条浏览器历史记录。
|
||||
const h5PopupHistory = (() => {
|
||||
const stack = []
|
||||
const listeners = {}
|
||||
let nextId = 0
|
||||
let afterClear = null
|
||||
window.addEventListener("popstate", (event) => {
|
||||
const currentId = event.state && event.state.h5PopupId
|
||||
while (stack.length && stack[stack.length - 1].id !== currentId) {
|
||||
const entry = stack.pop()
|
||||
if (listeners[entry.owner]) {
|
||||
listeners[entry.owner]()
|
||||
}
|
||||
}
|
||||
if (!stack.length && afterClear) {
|
||||
const callback = afterClear
|
||||
afterClear = null
|
||||
callback()
|
||||
}
|
||||
})
|
||||
return {
|
||||
register(owner, onClose) {
|
||||
listeners[owner] = onClose
|
||||
},
|
||||
unregister(owner) {
|
||||
delete listeners[owner]
|
||||
},
|
||||
open(owner) {
|
||||
if (!listeners[owner]) {
|
||||
return
|
||||
}
|
||||
const id = ++nextId
|
||||
stack.push({ id, owner })
|
||||
// 保留 pjax 的 state.id,让弹框返回不触发业务页面重载。
|
||||
window.history.pushState(Object.assign({}, window.history.state || {}, { h5PopupId: id }), "", window.location.href)
|
||||
},
|
||||
close(owner) {
|
||||
if (stack.length && stack[stack.length - 1].owner === owner) {
|
||||
window.history.back()
|
||||
}
|
||||
},
|
||||
clear(callback) {
|
||||
if (!stack.length) {
|
||||
callback()
|
||||
return
|
||||
}
|
||||
afterClear = callback
|
||||
window.history.go(-stack.length)
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
//初始化pjax
|
||||
;(function initPjax() {
|
||||
if ($.support.pjax) {
|
||||
@@ -103,15 +155,17 @@
|
||||
})()
|
||||
|
||||
function pjaxReplace(url, data = null) {
|
||||
$.pjax({
|
||||
url: url,
|
||||
container: "#container",
|
||||
maxCacheLength: 0,
|
||||
push: false,
|
||||
replace: true,
|
||||
fragment: "#container",
|
||||
timeout: 8000,
|
||||
data: data
|
||||
h5PopupHistory.clear(() => {
|
||||
$.pjax({
|
||||
url: url,
|
||||
container: "#container",
|
||||
maxCacheLength: 0,
|
||||
push: false,
|
||||
replace: true,
|
||||
fragment: "#container",
|
||||
timeout: 8000,
|
||||
data: data
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+47
-16
@@ -80,33 +80,44 @@ layout("/layouts/platform.html"){
|
||||
</el-card>
|
||||
</template>
|
||||
<template #view>
|
||||
<member-info ref="memberInfoRef"></member-info>
|
||||
<member-apply-audit-info ref="memberApplyAuditInfoRef"></member-apply-audit-info>
|
||||
</template>
|
||||
<template #public>
|
||||
<member-audit-change-info ref="memberAuditChangeInfoRef"></member-audit-change-info>
|
||||
<member-apply-audit-info ref="memberPublicApplyInfoRef"></member-apply-audit-info>
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.processInstanceNodeName}}</div>
|
||||
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="审核人员">
|
||||
<el-input :value="reviewerName" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="审核时间">
|
||||
<el-input :value="reviewTime" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
|
||||
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
|
||||
</el-form-item>
|
||||
<el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:false,message:'必填',trigger:['change','blur']}]">
|
||||
<el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'请签字',trigger:['change','blur']}]">
|
||||
<pc-signature v-model="formData.approvalSignature"></pc-signature>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row type="flex" justify="end">
|
||||
<el-button plain @click="$refs.guava.index()">取消</el-button>
|
||||
<el-button type="danger" @click="doApproval('BACK')">退回重新申请</el-button>
|
||||
<el-button type="danger" @click="doApproval('REJECT')">拒绝申请</el-button>
|
||||
<el-button type="primary" @click="doApproval('PASS')">同意申请</el-button>
|
||||
<el-button type="danger" :loading="formLoading" :disabled="formLoading" @click="doApproval('BACK')">退回重新申请</el-button>
|
||||
<el-button type="danger" :loading="formLoading" :disabled="formLoading" @click="doApproval('REJECT')">拒绝</el-button>
|
||||
<el-button type="primary" :loading="formLoading" :disabled="formLoading" @click="doApproval('PASS')">同意申请</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
<script>
|
||||
<!--#include("../../common/info/memberInfo.js"){}#-->
|
||||
<!--#include("../../common/audit/memberAuditChangeInfo.js"){}#-->
|
||||
<!--#include("../../common/info/memberApplyAuditInfo.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
@@ -128,36 +139,53 @@ layout("/layouts/platform.html"){
|
||||
],
|
||||
unions: [],
|
||||
units: [],
|
||||
showApprovalForm: false
|
||||
showApprovalForm: false,
|
||||
reviewerName: "",
|
||||
reviewTime: ""
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'member-info': MEMBER_INFO,
|
||||
'member-audit-change-info': MEMBER_AUDIT_CHANGE_INFO,
|
||||
'member-apply-audit-info': MEMBER_APPLY_AUDIT_INFO,
|
||||
},
|
||||
methods: {
|
||||
openView(row) {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.memberInfoRef.onOpen(row.userId)
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
openChangeView(row) {
|
||||
this.$refs.guava.public(() => {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.memberAuditChangeInfoRef.onOpen({recordId: row.id, userId: row.userId})
|
||||
this.$refs.memberPublicApplyInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
openApproval(row) {
|
||||
this.$refs.guava.public(() => {
|
||||
this.showApprovalForm = true
|
||||
this.formData = row.approvalParam
|
||||
this.$refs.memberAuditChangeInfoRef.onOpen({recordId: row.id, userId: row.userId})
|
||||
// 审核与查看使用同一份申请快照及历史,当前审核信息只作为表单展示。
|
||||
// 意见和签字预先声明为响应式字段,签字组件异步回填后才能触发表单校验。
|
||||
this.$set(this, "formData", {
|
||||
...row.approvalParam,
|
||||
approvalOpinion: row.approvalParam.approvalOpinion || "",
|
||||
approvalSignature: row.approvalParam.approvalSignature || ""
|
||||
})
|
||||
this.$set(this, "reviewerName", this.$store.state.user.username || "")
|
||||
this.$set(this, "reviewTime", moment().format("YYYY-MM-DD HH:mm:ss"))
|
||||
this.$refs.memberPublicApplyInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* approvalType 传 BACK、REJECT 或 PASS;approval 为包含任务 ID、意见、签字 URL 的 JSON 字符串。
|
||||
* 接口返回 Result,code 为 0 时表示审核成功,msg 为提示信息。
|
||||
*/
|
||||
doApproval(approvalType) {
|
||||
this.formData.bpmTaskApprovalType = approvalType
|
||||
if (this.formLoading) {
|
||||
return
|
||||
}
|
||||
this.$set(this.formData, "bpmTaskApprovalType", approvalType)
|
||||
this.$refs.approvalFormRef.validate((valid) => {
|
||||
if (valid) {
|
||||
this.formLoading = true
|
||||
this.$axios
|
||||
.post(loc() + "/approval", {
|
||||
approval: JSON.stringify(this.formData)
|
||||
@@ -169,6 +197,9 @@ layout("/layouts/platform.html"){
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@ layout("/layouts/platform.html"){
|
||||
<search-item label="姓名/工号">
|
||||
<el-input placeholder="请输入内容" clearable v-model="pageForm.searchKeyword"></el-input>
|
||||
</search-item>
|
||||
<template v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN', 'BRANCH_UNION_CHAIRMAN'])">
|
||||
<template v-if="$auth.hasRole('SYSADMIN')">
|
||||
<search-item label="所属工会">
|
||||
<el-select @change="flushUnits" @clear="flushUnits" clearable filterable
|
||||
placeholder="所属工会" style="width: 100%;" v-model="pageForm.unionId">
|
||||
@@ -42,7 +42,8 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="申请列表">
|
||||
<el-button size="small" type="primary"
|
||||
<el-button size="small" type="primary" :disabled="!canStartNewApply"
|
||||
:title="canStartNewApply ? '' : '已有进行中的入会申请'"
|
||||
@click="$store.dispatch('pjaxRoute', '/platform/member/apply/submit')">申请入会</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id" style="width: 100%">
|
||||
@@ -59,6 +60,10 @@ layout("/layouts/platform.html"){
|
||||
<template scope="{row}" v-if="column.prop=='loginname'">
|
||||
<el-link @click="openView(row)" type="primary">{{row.loginname}}</el-link>
|
||||
</template>
|
||||
<!-- 开始节点仍为申请人待提交阶段,仅调整列表中的显示文案。 -->
|
||||
<template scope="{row}" v-if="column.prop=='processInstanceNodeName'">
|
||||
{{row.processInstanceNodeCode === 10 ? '待提交' : row.processInstanceNodeName}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="220">
|
||||
<template slot-scope="{row}">
|
||||
@@ -90,13 +95,13 @@ layout("/layouts/platform.html"){
|
||||
</template>
|
||||
|
||||
<template #view>
|
||||
<member-info ref="memberInfoRef"></member-info>
|
||||
<member-apply-audit-info ref="memberApplyAuditInfoRef"></member-apply-audit-info>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script type="application/javascript">
|
||||
<!--#include("../../common/info/memberInfo.js"){}#-->
|
||||
<!--#include("../../common/info/memberApplyAuditInfo.js"){}#-->
|
||||
|
||||
new Vue({
|
||||
el: "#app",
|
||||
@@ -115,13 +120,22 @@ layout("/layouts/platform.html"){
|
||||
{ prop: "processInstanceNodeName", label: "当前节点", sortable: true }
|
||||
],
|
||||
unions: [],
|
||||
units: []
|
||||
units: [],
|
||||
canStartNewApply: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"member-info": MEMBER_INFO,
|
||||
"member-apply-audit-info": MEMBER_APPLY_AUDIT_INFO,
|
||||
},
|
||||
methods: {
|
||||
// 入口状态以当前登录人的进行中流程为准,列表筛选条件不影响判断。
|
||||
loadCanStartNewApply() {
|
||||
this.$axios.post("/platform/member/apply/submit/canStartNewApply", {}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.canStartNewApply = res.data === true
|
||||
}
|
||||
})
|
||||
},
|
||||
doDelete(row) {
|
||||
this.$confirm("您确定要删除吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
@@ -131,6 +145,7 @@ layout("/layouts/platform.html"){
|
||||
this.$axios.post(loc() + "/delete", { id: row.id }).then((resp) => {
|
||||
this.$message.success(resp.msg)
|
||||
this.doSearch()
|
||||
this.loadCanStartNewApply()
|
||||
})
|
||||
})
|
||||
},
|
||||
@@ -148,24 +163,19 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
openView(row) {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.memberInfoRef.onOpen(row.userId)
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
initData() {
|
||||
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
|
||||
this.loadCanStartNewApply()
|
||||
// 跨人员筛选仅系统管理员使用,其他角色的列表只查询本人申请。
|
||||
if (this.$auth.hasRole("SYSADMIN")) {
|
||||
this.$businessTool.listUnion(this.pageForm.unionId).then((data) => {
|
||||
this.unions = data
|
||||
})
|
||||
this.$businessTool.listUnit().then((data) => {
|
||||
this.units = data
|
||||
})
|
||||
} else if (this.$auth.hasRole("BRANCH_UNION_CHAIRMAN")){
|
||||
this.$businessTool.listUnion(this.$store.state.user.union.id).then((data) => {
|
||||
this.unions = data
|
||||
})
|
||||
this.$businessTool.listUnit(this.$store.state.user.union.id).then((data) => {
|
||||
this.units = data
|
||||
})
|
||||
}
|
||||
this.doSearch()
|
||||
},
|
||||
|
||||
+47
-16
@@ -80,33 +80,44 @@ layout("/layouts/platform.html"){
|
||||
</el-card>
|
||||
</template>
|
||||
<template #view>
|
||||
<member-info ref="memberInfoRef"></member-info>
|
||||
<member-apply-audit-info ref="memberApplyAuditInfoRef"></member-apply-audit-info>
|
||||
</template>
|
||||
<template #public>
|
||||
<member-audit-change-info ref="memberAuditChangeInfoRef"></member-audit-change-info>
|
||||
<member-apply-audit-info ref="memberPublicApplyInfoRef"></member-apply-audit-info>
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.processInstanceNodeName}}</div>
|
||||
<el-form :model="formData" ref="approvalFormRef" label-position="left" label-width="80px">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="审核人员">
|
||||
<el-input :value="reviewerName" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="审核时间">
|
||||
<el-input :value="reviewTime" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="审核意见" prop="approvalOpinion" :rules="[{required:true,message:'必填',trigger:['change','blur']}]">
|
||||
<user-opinion-textarea v-model="formData.approvalOpinion"></user-opinion-textarea>
|
||||
</el-form-item>
|
||||
<el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:false,message:'必填',trigger:['change','blur']}]">
|
||||
<el-form-item label="电子签名" prop="approvalSignature" :rules="[{required:true,message:'请签字',trigger:['change','blur']}]">
|
||||
<pc-signature v-model="formData.approvalSignature"></pc-signature>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row type="flex" justify="end">
|
||||
<el-button plain @click="$refs.guava.index()">取消</el-button>
|
||||
<el-button type="danger" @click="doApproval('BACK')">退回重新申请</el-button>
|
||||
<el-button type="danger" @click="doApproval('REJECT')">拒绝申请</el-button>
|
||||
<el-button type="primary" @click="doApproval('PASS')">同意申请</el-button>
|
||||
<el-button type="danger" :loading="formLoading" :disabled="formLoading" @click="doApproval('BACK')">退回重新申请</el-button>
|
||||
<el-button type="danger" :loading="formLoading" :disabled="formLoading" @click="doApproval('REJECT')">拒绝</el-button>
|
||||
<el-button type="primary" :loading="formLoading" :disabled="formLoading" @click="doApproval('PASS')">同意申请</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
<script>
|
||||
<!--#include("../../common/info/memberInfo.js"){}#-->
|
||||
<!--#include("../../common/audit/memberAuditChangeInfo.js"){}#-->
|
||||
<!--#include("../../common/info/memberApplyAuditInfo.js"){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
@@ -128,36 +139,53 @@ layout("/layouts/platform.html"){
|
||||
],
|
||||
unions: [],
|
||||
units: [],
|
||||
showApprovalForm: false
|
||||
showApprovalForm: false,
|
||||
reviewerName: "",
|
||||
reviewTime: ""
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'member-info': MEMBER_INFO,
|
||||
'member-audit-change-info': MEMBER_AUDIT_CHANGE_INFO,
|
||||
'member-apply-audit-info': MEMBER_APPLY_AUDIT_INFO,
|
||||
},
|
||||
methods: {
|
||||
openView(row) {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.memberInfoRef.onOpen(row.userId)
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
openChangeView(row) {
|
||||
this.$refs.guava.public(() => {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.memberAuditChangeInfoRef.onOpen({recordId: row.id, userId: row.userId})
|
||||
this.$refs.memberPublicApplyInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
openApproval(row) {
|
||||
this.$refs.guava.public(() => {
|
||||
this.showApprovalForm = true
|
||||
this.formData = row.approvalParam
|
||||
this.$refs.memberAuditChangeInfoRef.onOpen({recordId: row.id, userId: row.userId})
|
||||
// 审核与查看使用同一份申请快照及历史,当前审核信息只作为表单展示。
|
||||
// 意见和签字预先声明为响应式字段,签字组件异步回填后才能触发表单校验。
|
||||
this.$set(this, "formData", {
|
||||
...row.approvalParam,
|
||||
approvalOpinion: row.approvalParam.approvalOpinion || "",
|
||||
approvalSignature: row.approvalParam.approvalSignature || ""
|
||||
})
|
||||
this.$set(this, "reviewerName", this.$store.state.user.username || "")
|
||||
this.$set(this, "reviewTime", moment().format("YYYY-MM-DD HH:mm:ss"))
|
||||
this.$refs.memberPublicApplyInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* approvalType 传 BACK、REJECT 或 PASS;approval 为包含任务 ID、意见、签字 URL 的 JSON 字符串。
|
||||
* 接口返回 Result,code 为 0 时表示审核成功,msg 为提示信息。
|
||||
*/
|
||||
doApproval(approvalType) {
|
||||
this.formData.bpmTaskApprovalType = approvalType
|
||||
if (this.formLoading) {
|
||||
return
|
||||
}
|
||||
this.$set(this.formData, "bpmTaskApprovalType", approvalType)
|
||||
this.$refs.approvalFormRef.validate((valid) => {
|
||||
if (valid) {
|
||||
this.formLoading = true
|
||||
this.$axios
|
||||
.post(loc() + "/approval", {
|
||||
approval: JSON.stringify(this.formData)
|
||||
@@ -169,6 +197,9 @@ layout("/layouts/platform.html"){
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -124,7 +124,7 @@ layout("/layouts/platform.html"){
|
||||
<el-table-column width="100px">
|
||||
<template slot="header" slot-scope="scope">
|
||||
<el-button type="primary" size="mini"
|
||||
@click="formData.families.push({})">添加
|
||||
@click="addFamily">添加
|
||||
</el-button>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
@@ -151,8 +151,8 @@ layout("/layouts/platform.html"){
|
||||
<el-row v-if="!this.$store.state.user.member" justify="end" type="flex" class="mt10">
|
||||
<!-- <el-row justify="end" type="flex" class="mt10">-->
|
||||
<el-button v-if="formData.id" @click="$store.dispatch('pjaxRoute', '/platform/member/apply/mine')">返回</el-button>
|
||||
<el-button @click="doSave" type="primary">保存申请</el-button>
|
||||
<el-button @click="doSubmit" type="primary">提交申请</el-button>
|
||||
<el-button @click="doSave" type="primary" :disabled="formDisabled">保存申请</el-button>
|
||||
<el-button @click="doSubmit" type="primary" :disabled="formDisabled">提交申请</el-button>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
@@ -185,11 +185,41 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 家庭成员可能由用户资料或申请记录以 JSON 字符串返回,表格编辑需要数组。
|
||||
normalizeFamilies(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
if (typeof value === "string" && value) {
|
||||
try {
|
||||
const parsed = JSON.parse(value)
|
||||
return Array.isArray(parsed) ? parsed : []
|
||||
} catch (error) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
return []
|
||||
},
|
||||
// 添加前确保家庭成员字段可编辑,兼容页面回填后的异常数据类型。
|
||||
addFamily() {
|
||||
if (!Array.isArray(this.formData.families)) {
|
||||
this.$set(this.formData, "families", this.normalizeFamilies(this.formData.families))
|
||||
}
|
||||
this.formData.families.push({})
|
||||
},
|
||||
// 表单编码请求需将家庭成员数组作为 JSON 字符串传给后端,保留页面中的数组供继续编辑。
|
||||
buildSubmitPayload() {
|
||||
return {
|
||||
...this.formData,
|
||||
families: JSON.stringify(this.normalizeFamilies(this.formData.families))
|
||||
}
|
||||
},
|
||||
init() {
|
||||
if (this.id) {
|
||||
this.$axios.post(loc() + "/findApplyById", { id: this.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.formData = res.data
|
||||
this.$set(this.formData, "families", this.normalizeFamilies(this.formData.families))
|
||||
}
|
||||
})
|
||||
} else {
|
||||
@@ -202,6 +232,8 @@ layout("/layouts/platform.html"){
|
||||
nation,
|
||||
political,
|
||||
education,
|
||||
userState,
|
||||
preparedBy,
|
||||
governmentPosition,
|
||||
mobile,
|
||||
email,
|
||||
@@ -220,6 +252,9 @@ layout("/layouts/platform.html"){
|
||||
this.$set(this.formData, "nation", nation)
|
||||
this.$set(this.formData, "political", political)
|
||||
this.$set(this.formData, "education", education)
|
||||
// 新建申请时沿用登录用户的人事信息,保证两个字典字段在提交前有对应值。
|
||||
this.$set(this.formData, "userState", userState)
|
||||
this.$set(this.formData, "preparedBy", preparedBy)
|
||||
this.$set(this.formData, "unitName", unit ? unit.name : null)
|
||||
this.$set(this.formData, "unitId", unit ? unit.id : null)
|
||||
this.$set(this.formData, "unionName", union ? union.name : null)
|
||||
@@ -229,7 +264,7 @@ layout("/layouts/platform.html"){
|
||||
this.$set(this.formData, "mobile", mobile)
|
||||
this.$set(this.formData, "email", email)
|
||||
this.$set(this.formData, "wantJoinLoveMutualAidAssociation", wantJoinLoveMutualAidAssociation)
|
||||
this.$set(this.formData, "families", families ? families : [])
|
||||
this.$set(this.formData, "families", this.normalizeFamilies(families))
|
||||
this.$set(this.formData, "personalData", personalData)
|
||||
}
|
||||
},
|
||||
@@ -237,7 +272,7 @@ layout("/layouts/platform.html"){
|
||||
this.$confirm("保存后可在我的申请里面再次编辑,您确定要保存吗?", "提示", { type: "warning" })
|
||||
.then(() => {
|
||||
this.$axios
|
||||
.post(loc() + "/doSave", this.formData)
|
||||
.post(loc() + "/doSave", this.buildSubmitPayload())
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
@@ -250,9 +285,7 @@ layout("/layouts/platform.html"){
|
||||
doSubmit() {
|
||||
this.$confirm("您确定要提交申请吗?", "提示", { type: "warning" })
|
||||
.then(() => {
|
||||
this.$axios.post(loc() + "/doSubmit", {
|
||||
...this.formData,
|
||||
}).then((res) => {
|
||||
this.$axios.post(loc() + "/doSubmit", this.buildSubmitPayload()).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.$store.dispatch("pjaxRoute", "/platform/member/apply/mine")
|
||||
@@ -262,9 +295,25 @@ layout("/layouts/platform.html"){
|
||||
.catch()
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.init()
|
||||
this.units = await this.$businessTool.listUnit()
|
||||
created() {
|
||||
this.$businessTool.listUnit().then((data) => {
|
||||
this.units = data
|
||||
})
|
||||
if (this.id) {
|
||||
this.init()
|
||||
return
|
||||
}
|
||||
// 直接进入新建页面时也检查本人是否已有进行中的入会流程。
|
||||
this.formDisabled = true
|
||||
this.$axios.post(loc() + "/canStartNewApply", {}).then((res) => {
|
||||
if (res.code === 0 && res.data === true) {
|
||||
this.init()
|
||||
this.formDisabled = false
|
||||
} else {
|
||||
this.$message.warning("您有进行中的入会申请,请先处理已有申请")
|
||||
this.$store.dispatch("pjaxRoute", "/platform/member/apply/mine")
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
+1
@@ -56,6 +56,7 @@ const MEMBER_AUDIT_CHANGE_INFO = {
|
||||
</el-table>
|
||||
<el-empty v-else :image-size="50" description="未获取到变更信息"></el-empty>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</el-card>
|
||||
`,
|
||||
props: {
|
||||
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
const MEMBER_APPLY_AUDIT_INFO = {
|
||||
template: /*language=HTML*/ `
|
||||
<div v-loading="viewLoading">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane label="申请信息" name="apply">
|
||||
<el-descriptions :column="3" border class="descriptions-form">
|
||||
<el-descriptions-item label="申请时间" :span="3">{{ viewData.applyDateTime || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="工号">{{ viewData.loginname }}</el-descriptions-item>
|
||||
<el-descriptions-item label="姓名">{{ viewData.username }}</el-descriptions-item>
|
||||
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
|
||||
<el-descriptions-item label="民族">{{ viewData.nation }}</el-descriptions-item>
|
||||
<el-descriptions-item label="在职状态">{{ viewData.userState }}</el-descriptions-item>
|
||||
<el-descriptions-item label="人事编制">{{ viewData.preparedBy }}</el-descriptions-item>
|
||||
<el-descriptions-item label="人员类型">{{ viewData.personType }}</el-descriptions-item>
|
||||
<el-descriptions-item label="学历">{{ viewData.education }}</el-descriptions-item>
|
||||
<el-descriptions-item label="政治面貌">{{ viewData.political }}</el-descriptions-item>
|
||||
<el-descriptions-item label="证件号码">{{ viewData.idCard }}</el-descriptions-item>
|
||||
<el-descriptions-item label="联系电话">{{ viewData.mobile }}</el-descriptions-item>
|
||||
<el-descriptions-item label="电子邮箱">{{ viewData.email }}</el-descriptions-item>
|
||||
<el-descriptions-item label="所属工会">{{ viewData.unionName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="工作单位">{{ viewData.unitName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="岗位职务">{{ viewData.governmentPosition }}</el-descriptions-item>
|
||||
<el-descriptions-item label="是否愿意加入大病互助基金会" :span="3">{{ viewData.wantJoinLoveMutualAidAssociation ? '是' : '否' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="家庭主要成员及其工作单位" :span="3">
|
||||
<el-table v-if="families.length" :data="families" size="mini" border style="width: 100%">
|
||||
<el-table-column prop="relation" label="与本人关系"></el-table-column>
|
||||
<el-table-column prop="name" label="姓名"></el-table-column>
|
||||
<el-table-column prop="unit" label="单位"></el-table-column>
|
||||
<el-table-column prop="remark" label="备注"></el-table-column>
|
||||
</el-table>
|
||||
<span v-else>暂无</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="个人简况" :span="3">
|
||||
<div v-if="viewData.personalData" v-html="viewData.personalData"></div>
|
||||
<span v-else>暂无</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="备注" :span="3">{{ viewData.notes || '暂无' }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="branchRecords.length" label="分工会审核信息" name="branch">
|
||||
<div class="process-title">分工会审核信息</div>
|
||||
<el-descriptions v-for="record in branchRecords" :key="record.id" :column="2" border class="descriptions-form mb15">
|
||||
<el-descriptions-item label="审核人员">{{ record.operatorName || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核时间">{{ record.handledAt || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核结果" :span="2">{{ record.result }}</el-descriptions-item>
|
||||
<el-descriptions-item v-if="record.originalResult" label="原审核结果" :span="2">{{ record.originalResult }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核意见" :span="2">{{ record.opinion || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="签字" :span="2">
|
||||
<el-image v-if="record.signature" :src="record.signature" fit="contain" style="width: 180px; height: 80px"></el-image>
|
||||
<span v-else>暂无</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="schoolRecords.length" label="校工会审核信息" name="school">
|
||||
<div class="process-title">校工会审核信息</div>
|
||||
<el-descriptions v-for="record in schoolRecords" :key="record.id" :column="2" border class="descriptions-form mb15">
|
||||
<el-descriptions-item label="审核人员">{{ record.operatorName || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核时间">{{ record.handledAt || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核结果" :span="2">{{ record.result }}</el-descriptions-item>
|
||||
<el-descriptions-item v-if="record.originalResult" label="原审核结果" :span="2">{{ record.originalResult }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核意见" :span="2">{{ record.opinion || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="签字" :span="2">
|
||||
<el-image v-if="record.signature" :src="record.signature" fit="contain" style="width: 180px; height: 80px"></el-image>
|
||||
<span v-else>暂无</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
activeName: "apply",
|
||||
viewData: {},
|
||||
approvalRecords: [],
|
||||
viewLoading: false,
|
||||
requestId: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
families() {
|
||||
const value = this.viewData.families
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
if (typeof value === "string" && value) {
|
||||
try {
|
||||
const parsed = JSON.parse(value)
|
||||
return Array.isArray(parsed) ? parsed : []
|
||||
} catch (error) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
return []
|
||||
},
|
||||
// 申请人任务不展示;20、50 节点分别为分工会和校工会审核记录。
|
||||
branchRecords() {
|
||||
return this.approvalRecords.filter((record) => Number(record.nodeCode) === 20 && record.handledAt)
|
||||
},
|
||||
schoolRecords() {
|
||||
return this.approvalRecords.filter((record) => Number(record.nodeCode) === 50 && record.handledAt)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* recordId 为 member_apply_record.id。两个接口的 Result.data 分别为当次申请快照和流程记录列表;
|
||||
* 记录包含 nodeCode、办理人、时间、结果、原审核结果、意见与签字 URL;只展示审核节点。
|
||||
*/
|
||||
onOpen(recordId) {
|
||||
this.$set(this, "activeName", "apply")
|
||||
this.$set(this, "viewData", {})
|
||||
this.$set(this, "approvalRecords", [])
|
||||
this.$set(this, "requestId", this.requestId + 1)
|
||||
const requestId = this.requestId
|
||||
this.$set(this, "viewLoading", true)
|
||||
return Promise.all([
|
||||
this.$axios.post("/platform/member/apply/common/findApplyRecord", { recordId }),
|
||||
this.$axios.post("/platform/member/apply/common/approvalRecords", { recordId })
|
||||
])
|
||||
.then(([applyRes, recordsRes]) => {
|
||||
if (requestId === this.requestId && applyRes.code === 0) {
|
||||
this.$set(this, "viewData", applyRes.data || {})
|
||||
this.$set(this, "approvalRecords", recordsRes.code === 0 ? recordsRes.data || [] : [])
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (requestId === this.requestId) {
|
||||
this.$set(this, "viewLoading", false)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
+66
-9
@@ -1,7 +1,9 @@
|
||||
const MEMBER_INFO = {
|
||||
template: `
|
||||
<div>
|
||||
template: /*language=HTML*/ `
|
||||
<div v-loading="viewLoading">
|
||||
<div v-if="applyRecordId" class="process-title">本次申请</div>
|
||||
<el-descriptions :column="3" border class="descriptions-form">
|
||||
<el-descriptions-item v-if="applyRecordId" label="申请时间" :span="3">{{ viewData.applyDateTime || '暂无' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="姓名">{{ viewData.username + '(' + viewData.loginname + ')' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="性别">{{ viewData.sex }}</el-descriptions-item>
|
||||
<el-descriptions-item label="民族">{{ viewData.nation }}</el-descriptions-item>
|
||||
@@ -45,20 +47,75 @@
|
||||
<span v-else>无数据</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div v-if="applyRecordId" class="mt20">
|
||||
<div class="process-title">申请及审核记录</div>
|
||||
<el-table :data="approvalRecords" border size="small" row-key="id" empty-text="暂无申请及审核记录">
|
||||
<el-table-column prop="nodeName" label="节点" min-width="130"></el-table-column>
|
||||
<el-table-column label="办理人" min-width="120">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.operatorName || '暂无' }}
|
||||
<span v-if="scope.row.operatorLoginName">({{ scope.row.operatorLoginName }})</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="处理时间" min-width="160">
|
||||
<template slot-scope="scope">{{ scope.row.handledAt || '暂无' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="result" label="结果" min-width="100"></el-table-column>
|
||||
<el-table-column label="审核意见" min-width="160">
|
||||
<template slot-scope="scope">{{ scope.row.opinion || '暂无' }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签字" min-width="160">
|
||||
<template slot-scope="scope">
|
||||
<el-image v-if="scope.row.signature" :src="scope.row.signature" fit="contain" style="width: 150px; height: 70px"></el-image>
|
||||
<span v-else>暂无</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
viewData: {}
|
||||
viewData: {},
|
||||
approvalRecords: [],
|
||||
applyRecordId: "",
|
||||
viewLoading: false,
|
||||
viewRequestId: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onOpen(id) {
|
||||
this.$axios.post("/platform/member/apply/common/findOne", { id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
}
|
||||
})
|
||||
/**
|
||||
* id 为会员 userId,recordId 可选,传入时查看该次申请快照。
|
||||
* 接口返回 Result,data 为会员资料或申请资料;申请资料含 applyDateTime。
|
||||
*/
|
||||
onOpen(id, recordId = "") {
|
||||
this.$set(this, "applyRecordId", recordId)
|
||||
this.$set(this, "viewData", {})
|
||||
this.$set(this, "approvalRecords", [])
|
||||
this.$set(this, "viewRequestId", this.viewRequestId + 1)
|
||||
const requestId = this.viewRequestId
|
||||
const url = recordId ? "/platform/member/apply/common/findApplyRecord" : "/platform/member/apply/common/findOne"
|
||||
const params = recordId ? { recordId } : { id }
|
||||
this.$set(this, "viewLoading", true)
|
||||
// 入会查看同时读取申请快照和任务历史;普通会员资料查看仍只查询会员信息。
|
||||
const requests = [this.$axios.post(url, params)]
|
||||
if (recordId) {
|
||||
requests.push(this.$axios.post("/platform/member/apply/common/approvalRecords", { recordId }))
|
||||
}
|
||||
return Promise.all(requests)
|
||||
.then(([res, recordsRes]) => {
|
||||
// 快速切换查看对象时,仅接收最后一次请求,避免显示上一条申请。
|
||||
if (res.code === 0 && requestId === this.viewRequestId) {
|
||||
this.$set(this, "viewData", res.data || {})
|
||||
this.$set(this, "approvalRecords", recordsRes && recordsRes.code === 0 ? recordsRes.data || [] : [])
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (requestId === this.viewRequestId) {
|
||||
this.$set(this, "viewLoading", false)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+74
-25
@@ -127,6 +127,10 @@ layout("/layouts/platform_h5.html"){
|
||||
height: calc(100vh - 46px);
|
||||
overflow: auto;
|
||||
}
|
||||
.approval-popup .van-tabs {
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
.van-cell-group__title {
|
||||
padding: 6px 0;
|
||||
}
|
||||
@@ -211,30 +215,32 @@ layout("/layouts/platform_h5.html"){
|
||||
<van-nodata :figure="23" title="暂无数据" v-else></van-nodata>
|
||||
</div>
|
||||
|
||||
<van-popup v-model="infoShow" position="right" :style="{ height: '100%', width: '100%' }" safe-area-inset-bottom>
|
||||
<van-popup v-model="infoShow" :class="{'approval-popup': showApprovalForm}" :close-on-click-overlay="false" position="right" :style="{ height: '100%', width: '100%' }" safe-area-inset-bottom>
|
||||
<van-sticky>
|
||||
<van-nav-bar @click-left="infoShow=false" left-arrow
|
||||
<van-nav-bar @click-left="closeInfo" left-arrow
|
||||
left-text="返回" title="分工会审核"></van-nav-bar>
|
||||
</van-sticky>
|
||||
<member-change-info ref="memberChangeInfoRef"></member-change-info>
|
||||
<member-apply-audit-info ref="memberApplyAuditInfoRef"></member-apply-audit-info>
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.processInstanceNodeName}}</div>
|
||||
<form @submit.prevent="">
|
||||
<van-field label="审核人员" :value="reviewerName" readonly></van-field>
|
||||
<van-field label="审核时间" :value="reviewTime" readonly></van-field>
|
||||
<van-field label="审核意见" name="approvalOpinion" v-model="formData.approvalOpinion" required></van-field>
|
||||
<van-field label="签字" name="signature" v-model="formData.approvalSignature" required class="direction-column-field">
|
||||
<van-field label="签字" name="approvalSignature" v-model="formData.approvalSignature" required class="direction-column-field">
|
||||
<h5-signature v-model="formData.approvalSignature" slot="input"></h5-signature>
|
||||
</van-field>
|
||||
</form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click.submit="doApproval('BACK')">退回</van-button>
|
||||
<van-button type="danger" block @click.submit="doApproval('REJECT')">建议撤销</van-button>
|
||||
<van-button type="primary" block @click.submit="doApproval('PASS')">同意</van-button>
|
||||
<van-button type="danger" block :loading="formLoading" :disabled="formLoading" @click.submit="doApproval('BACK')">退回</van-button>
|
||||
<van-button type="danger" block :loading="formLoading" :disabled="formLoading" @click.submit="doApproval('REJECT')">拒绝</van-button>
|
||||
<van-button type="primary" block :loading="formLoading" :disabled="formLoading" @click.submit="doApproval('PASS')">同意</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
<script>
|
||||
<!--#include("../../common/mobileMemberChangeInfo.js"){}#-->
|
||||
<!--#include("../../common/mobileMemberApplyAuditInfo.js"){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
@@ -256,40 +262,72 @@ layout("/layouts/platform_h5.html"){
|
||||
],
|
||||
tableLoading: false,
|
||||
tableFinished: false,
|
||||
formLoading: false,
|
||||
// 签名组件通过 v-model 回填图片 URL,必须预先声明为响应式表单字段。
|
||||
formData: {
|
||||
approvalOpinion: "",
|
||||
approvalSignature: ""
|
||||
},
|
||||
rules: {
|
||||
approvalOpinion: [{ required: true, message: "请填写审核意见" }],
|
||||
approvalSignature: [{ required: true, message: "请签字" }]
|
||||
},
|
||||
|
||||
userId: "",
|
||||
infoShow: false,
|
||||
showApprovalForm: false
|
||||
showApprovalForm: false,
|
||||
reviewerName: "",
|
||||
reviewTime: ""
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'member-change-info': MOBILE_MEMBER_CHANGE_INFO
|
||||
'member-apply-audit-info': MOBILE_MEMBER_APPLY_AUDIT_INFO
|
||||
},
|
||||
methods: {
|
||||
openApproval(row) {
|
||||
this.infoShow = true
|
||||
// 复制当前任务参数,保留已有意见和签名,避免本次编辑修改列表中的原始数据。
|
||||
this.$set(this, "formData", {
|
||||
...row.approvalParam,
|
||||
approvalOpinion: row.approvalParam.approvalOpinion || "",
|
||||
approvalSignature: row.approvalParam.approvalSignature || ""
|
||||
})
|
||||
// 审核表单只展示当前审核人和时间,提交仍由原任务参数与意见、签字组成。
|
||||
this.$set(this, "reviewerName", this.$store.state.user.username || "")
|
||||
this.$set(this, "reviewTime", moment().format("YYYY-MM-DD HH:mm:ss"))
|
||||
this.$set(this, "showApprovalForm", true)
|
||||
h5PopupHistory.open(this._uid)
|
||||
this.$set(this, "infoShow", true)
|
||||
this.$nextTick(() => {
|
||||
this.showApprovalForm = true
|
||||
this.formData = row.approvalParam
|
||||
this.$refs.memberChangeInfoRef.activeName = "change"
|
||||
this.$refs.memberChangeInfoRef.onOpen({recordId:row.id, userId:row.userId})
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* approvalType 为 BACK(退回)、REJECT(建议撤销)或 PASS(同意)。
|
||||
* approval 参数传入包含任务标识、审核意见及签名图片 URL 的 JSON 字符串;
|
||||
* 接口返回 Result 对象,code 为 0 表示审核成功,msg 为结果提示。
|
||||
*/
|
||||
doApproval(approvalType) {
|
||||
this.formData.bpmTaskApprovalType = approvalType
|
||||
// 请求完成前阻止重复审核,避免同一任务被连续提交。
|
||||
if (this.formLoading) {
|
||||
return
|
||||
}
|
||||
this.$set(this.formData, "bpmTaskApprovalType", approvalType)
|
||||
formRules(this.rules, this.formData, (valid) => {
|
||||
if (valid) {
|
||||
this.$axios
|
||||
.post("/platform/member/apply/branchUnionAudit/approval", {
|
||||
approval: JSON.stringify(this.formData)
|
||||
})
|
||||
this.$set(this, "formLoading", true)
|
||||
this.$axios.post("/platform/member/apply/branchUnionAudit/approval", {
|
||||
approval: JSON.stringify(this.formData)
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.infoShow = false
|
||||
this.closeInfo()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.$set(this, "formLoading", false)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -315,13 +353,16 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
},
|
||||
openView(row) {
|
||||
this.infoShow = true
|
||||
this.$set(this, "showApprovalForm", false)
|
||||
h5PopupHistory.open(this._uid)
|
||||
this.$set(this, "infoShow", true)
|
||||
this.$nextTick(() => {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.memberChangeInfoRef.activeName = "basic"
|
||||
this.$refs.memberChangeInfoRef.onOpen({recordId:row.id, userId:row.userId})
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
closeInfo() {
|
||||
h5PopupHistory.close(this._uid)
|
||||
},
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.tableData = []
|
||||
@@ -379,6 +420,14 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
h5PopupHistory.register(this._uid, () => {
|
||||
this.$set(this, "infoShow", false)
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
h5PopupHistory.unregister(this._uid)
|
||||
},
|
||||
created() {
|
||||
this.initUnion()
|
||||
this.flushUnits()
|
||||
|
||||
@@ -28,6 +28,24 @@ layout("/layouts/platform_h5.html"){
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
.apply-status-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 6px 4px;
|
||||
}
|
||||
|
||||
.apply-status-text {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.apply-action-buttons {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.van-col {
|
||||
line-height: 24px;
|
||||
}
|
||||
@@ -142,7 +160,7 @@ layout("/layouts/platform_h5.html"){
|
||||
input-align="left"
|
||||
@search="doSearch"
|
||||
></van-search>
|
||||
<van-dropdown-menu v-if="$auth.hasRoleOr('SYSADMIN,SCHOOL_UNION_ADMIN,BRANCH_UNION_CHAIRMAN')" :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-menu v-if="$auth.hasRole('SYSADMIN')" :close-on-click-outside="false" :close-on-click-overlay="false">
|
||||
<van-dropdown-item :options="unionList" @change="unionChange" v-model="pageForm.unionId"></van-dropdown-item>
|
||||
<van-dropdown-item :options="unitList" @change="doSearch" v-model="pageForm.unitId"></van-dropdown-item>
|
||||
</van-dropdown-menu>
|
||||
@@ -184,26 +202,26 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
<van-divider></van-divider>
|
||||
|
||||
<div style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>
|
||||
<div class="apply-status-row">
|
||||
<div class="apply-status-text">
|
||||
<span style="color: grey">当前状态:</span>
|
||||
<span>{{item.processInstanceNodeName}}</span>
|
||||
<!-- 开始节点仍是申请人待提交阶段,仅缩短列表中的显示文案。 -->
|
||||
<span>{{item.processInstanceNodeCode === 10 ? '待提交' : item.processInstanceNodeName}}</span>
|
||||
</div>
|
||||
<div>
|
||||
<div class="apply-action-buttons">
|
||||
<van-button size="small" @click="openView(item)"
|
||||
type="info" style="margin-right: 4px">查看
|
||||
type="info">查看
|
||||
</van-button>
|
||||
<van-button size="small" type="primary"
|
||||
v-if="[10,40,70].includes(item.processInstanceNodeCode)"
|
||||
@click="$pjaxReplace('/platform/h5/member/apply/submit?id=' + item.id)"
|
||||
style="margin-right: 4px">编辑
|
||||
@click="$pjaxReplace('/platform/h5/member/apply/submit?id=' + item.id)">编辑
|
||||
</van-button>
|
||||
<van-button size="small" @click="openRevoke(item)"
|
||||
type="danger" style="margin-right: 4px"
|
||||
type="danger"
|
||||
v-if="[20].includes(item.processInstanceNodeCode) && !item.nextTaskIsComplete">撤销
|
||||
</van-button>
|
||||
<van-button size="small" @click="doDelete(item)"
|
||||
type="danger" style="margin-right: 4px"
|
||||
type="danger"
|
||||
v-if="[10].includes(item.processInstanceNodeCode)">删除
|
||||
</van-button>
|
||||
</div>
|
||||
@@ -214,16 +232,16 @@ layout("/layouts/platform_h5.html"){
|
||||
<van-nodata :figure="23" title="暂无数据" v-else></van-nodata>
|
||||
</div>
|
||||
|
||||
<van-popup v-model="infoShow" position="right" :style="{ height: '100%', width: '100%' }" safe-area-inset-bottom>
|
||||
<van-popup v-model="infoShow" :close-on-click-overlay="false" position="right" :style="{ height: '100%', width: '100%' }" safe-area-inset-bottom>
|
||||
<van-sticky>
|
||||
<van-nav-bar @click-left="infoShow=false" left-arrow
|
||||
<van-nav-bar @click-left="closeInfo" left-arrow
|
||||
left-text="返回" title="我的申请信息"></van-nav-bar>
|
||||
</van-sticky>
|
||||
<member-change-info ref="memberChangeInfoRef"></member-change-info>
|
||||
<member-apply-audit-info ref="memberApplyAuditInfoRef"></member-apply-audit-info>
|
||||
</van-popup>
|
||||
</div>
|
||||
<script>
|
||||
<!--#include("../../common/mobileMemberChangeInfo.js"){}#-->
|
||||
<!--#include("../../common/mobileMemberApplyAuditInfo.js"){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
@@ -247,7 +265,7 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'member-change-info': MOBILE_MEMBER_CHANGE_INFO
|
||||
'member-apply-audit-info': MOBILE_MEMBER_APPLY_AUDIT_INFO
|
||||
},
|
||||
methods: {
|
||||
openRevoke(row) {
|
||||
@@ -293,11 +311,15 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
},
|
||||
openView(row) {
|
||||
this.infoShow = true
|
||||
h5PopupHistory.open(this._uid)
|
||||
this.$set(this, "infoShow", true)
|
||||
this.$nextTick(() => {
|
||||
this.$refs.memberChangeInfoRef.onOpen({recordId:row.id, userId:row.userId})
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
closeInfo() {
|
||||
h5PopupHistory.close(this._uid)
|
||||
},
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.tableData = []
|
||||
@@ -328,18 +350,18 @@ layout("/layouts/platform_h5.html"){
|
||||
this.doSearch()
|
||||
},
|
||||
initUnion() {
|
||||
// 普通用户只看自己的申请,无需按当前工会或单位再次过滤。
|
||||
if (!this.$auth.hasRole('SYSADMIN')) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const hasAdmin = this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])
|
||||
const unionId = hasAdmin ? null : this.$store.state.user.union.id
|
||||
this.$businessTool.listUnion(unionId).then((data) => {
|
||||
this.$businessTool.listUnion().then((data) => {
|
||||
this.unionList = data
|
||||
this.unionList.forEach((v) => {
|
||||
v.text = v.name
|
||||
v.value = v.id
|
||||
})
|
||||
if (hasAdmin) {
|
||||
this.unionList.unshift({ text: "全部工会", value: null })
|
||||
}
|
||||
this.unionList.unshift({ text: "全部工会", value: null })
|
||||
if (this.unionList && this.unionList.length > 0) {
|
||||
this.$set(this.pageForm, "unionId", this.unionList[0].value)
|
||||
}
|
||||
@@ -348,16 +370,17 @@ layout("/layouts/platform_h5.html"){
|
||||
|
||||
},
|
||||
flushUnits() {
|
||||
if (!this.$auth.hasRole('SYSADMIN')) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const hasAdmin = this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])
|
||||
const unionId = hasAdmin ? this.pageForm.unionId : this.$store.state.user.union.id
|
||||
this.$businessTool.listUnit(unionId).then((data) => {
|
||||
this.$businessTool.listUnit(this.pageForm.unionId).then((data) => {
|
||||
this.unitList = data
|
||||
this.unitList.forEach((v) => {
|
||||
v.text = v.name
|
||||
v.value = v.id
|
||||
})
|
||||
if (hasAdmin && !this.pageForm.unionId) {
|
||||
if (!this.pageForm.unionId) {
|
||||
this.unitList.unshift({ text: "全部单位", value: null })
|
||||
}
|
||||
if (this.unitList && this.unitList.length > 0) {
|
||||
@@ -367,6 +390,14 @@ layout("/layouts/platform_h5.html"){
|
||||
} catch (e) {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
h5PopupHistory.register(this._uid, () => {
|
||||
this.$set(this, "infoShow", false)
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
h5PopupHistory.unregister(this._uid)
|
||||
},
|
||||
created() {
|
||||
this.initUnion()
|
||||
this.flushUnits()
|
||||
|
||||
+76
-27
@@ -127,13 +127,17 @@ layout("/layouts/platform_h5.html"){
|
||||
height: calc(100vh - 46px);
|
||||
overflow: auto;
|
||||
}
|
||||
.approval-popup .van-tabs {
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
}
|
||||
.van-cell-group__title {
|
||||
padding: 6px 0;
|
||||
}
|
||||
</style>
|
||||
<div id="app" v-cloak>
|
||||
<van-sticky>
|
||||
<van-nav-bar title="会员入会分工会审核" left-text="返回" left-arrow @click-left="$pjaxReplace('/platform/h5/home')"></van-nav-bar>
|
||||
<van-nav-bar title="会员入会校工会审核" left-text="返回" left-arrow @click-left="$pjaxReplace('/platform/h5/home')"></van-nav-bar>
|
||||
<van-search
|
||||
v-model="pageForm.searchKeyword"
|
||||
placeholder="请输入工号或者姓名进行查询"
|
||||
@@ -207,30 +211,32 @@ layout("/layouts/platform_h5.html"){
|
||||
<van-nodata :figure="23" title="暂无数据" v-else></van-nodata>
|
||||
</div>
|
||||
|
||||
<van-popup v-model="infoShow" position="right" :style="{ height: '100%', width: '100%' }" safe-area-inset-bottom>
|
||||
<van-popup v-model="infoShow" :class="{'approval-popup': showApprovalForm}" :close-on-click-overlay="false" position="right" :style="{ height: '100%', width: '100%' }" safe-area-inset-bottom>
|
||||
<van-sticky>
|
||||
<van-nav-bar @click-left="infoShow=false" left-arrow
|
||||
left-text="返回" title="分工会审核"></van-nav-bar>
|
||||
<van-nav-bar @click-left="closeInfo" left-arrow
|
||||
left-text="返回" title="校工会审核"></van-nav-bar>
|
||||
</van-sticky>
|
||||
<member-change-info ref="memberChangeInfoRef"></member-change-info>
|
||||
<member-apply-audit-info ref="memberApplyAuditInfoRef"></member-apply-audit-info>
|
||||
<div v-if="showApprovalForm">
|
||||
<div class="process-title">{{formData.processInstanceNodeName}}</div>
|
||||
<form @submit.prevent="">
|
||||
<van-field label="审核人员" :value="reviewerName" readonly></van-field>
|
||||
<van-field label="审核时间" :value="reviewTime" readonly></van-field>
|
||||
<van-field label="审核意见" name="approvalOpinion" v-model="formData.approvalOpinion" required></van-field>
|
||||
<van-field label="签字" name="signature" v-model="formData.approvalSignature" required class="direction-column-field">
|
||||
<van-field label="签字" name="approvalSignature" v-model="formData.approvalSignature" required class="direction-column-field">
|
||||
<h5-signature v-model="formData.approvalSignature" slot="input"></h5-signature>
|
||||
</van-field>
|
||||
</form>
|
||||
<div style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button type="danger" block @click.submit="doApproval('BACK')">退回重新填写</van-button>
|
||||
<van-button type="danger" block @click.submit="doApproval('REJECT')">建议撤销</van-button>
|
||||
<van-button type="primary" block @click.submit="doApproval('PASS')">同意</van-button>
|
||||
<van-button type="danger" block :loading="formLoading" :disabled="formLoading" @click.submit="doApproval('BACK')">退回</van-button>
|
||||
<van-button type="danger" block :loading="formLoading" :disabled="formLoading" @click.submit="doApproval('REJECT')">拒绝</van-button>
|
||||
<van-button type="primary" block :loading="formLoading" :disabled="formLoading" @click.submit="doApproval('PASS')">同意</van-button>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
<script>
|
||||
<!--#include("../../common/mobileMemberChangeInfo.js"){}#-->
|
||||
<!--#include("../../common/mobileMemberApplyAuditInfo.js"){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
store,
|
||||
@@ -253,40 +259,72 @@ layout("/layouts/platform_h5.html"){
|
||||
],
|
||||
tableLoading: false,
|
||||
tableFinished: false,
|
||||
formLoading: false,
|
||||
// 签名组件通过 v-model 回填图片 URL,必须预先声明为响应式表单字段。
|
||||
formData: {
|
||||
approvalOpinion: "",
|
||||
approvalSignature: ""
|
||||
},
|
||||
rules: {
|
||||
approvalOpinion: [{ required: true, message: "请填写审核意见" }],
|
||||
approvalSignature: [{ required: true, message: "请签字" }]
|
||||
},
|
||||
|
||||
userId: "",
|
||||
infoShow: false,
|
||||
showApprovalForm: false
|
||||
showApprovalForm: false,
|
||||
reviewerName: "",
|
||||
reviewTime: ""
|
||||
}
|
||||
},
|
||||
components: {
|
||||
'member-change-info': MOBILE_MEMBER_CHANGE_INFO
|
||||
'member-apply-audit-info': MOBILE_MEMBER_APPLY_AUDIT_INFO
|
||||
},
|
||||
methods: {
|
||||
openApproval(row) {
|
||||
this.infoShow = true
|
||||
// 复制当前任务参数,保留已有意见和签名,避免本次编辑修改列表中的原始数据。
|
||||
this.$set(this, "formData", {
|
||||
...row.approvalParam,
|
||||
approvalOpinion: row.approvalParam.approvalOpinion || "",
|
||||
approvalSignature: row.approvalParam.approvalSignature || ""
|
||||
})
|
||||
// 审核表单只展示当前审核人和时间,提交仍由原任务参数与意见、签字组成。
|
||||
this.$set(this, "reviewerName", this.$store.state.user.username || "")
|
||||
this.$set(this, "reviewTime", moment().format("YYYY-MM-DD HH:mm:ss"))
|
||||
this.$set(this, "showApprovalForm", true)
|
||||
h5PopupHistory.open(this._uid)
|
||||
this.$set(this, "infoShow", true)
|
||||
this.$nextTick(() => {
|
||||
this.showApprovalForm = true
|
||||
this.formData = row.approvalParam
|
||||
this.$refs.memberChangeInfoRef.activeName = "change"
|
||||
this.$refs.memberChangeInfoRef.onOpen({recordId:row.id, userId:row.userId})
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* approvalType 为 BACK(退回)、REJECT(建议撤销)或 PASS(同意)。
|
||||
* approval 参数传入包含任务标识、审核意见及签名图片 URL 的 JSON 字符串;
|
||||
* 接口返回 Result 对象,code 为 0 表示审核成功,msg 为结果提示。
|
||||
*/
|
||||
doApproval(approvalType) {
|
||||
this.formData.bpmTaskApprovalType = approvalType
|
||||
// 请求完成前阻止重复审核,避免同一任务被连续提交。
|
||||
if (this.formLoading) {
|
||||
return
|
||||
}
|
||||
this.$set(this.formData, "bpmTaskApprovalType", approvalType)
|
||||
formRules(this.rules, this.formData, (valid) => {
|
||||
if (valid) {
|
||||
this.$axios
|
||||
.post("/platform/member/apply/schoolUnionAudit/approval", {
|
||||
approval: JSON.stringify(this.formData)
|
||||
})
|
||||
this.$set(this, "formLoading", true)
|
||||
this.$axios.post("/platform/member/apply/schoolUnionAudit/approval", {
|
||||
approval: JSON.stringify(this.formData)
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.infoShow = false
|
||||
this.closeInfo()
|
||||
this.$toast.success(res.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.$set(this, "formLoading", false)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -312,13 +350,16 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
},
|
||||
openView(row) {
|
||||
this.infoShow = true
|
||||
this.$set(this, "showApprovalForm", false)
|
||||
h5PopupHistory.open(this._uid)
|
||||
this.$set(this, "infoShow", true)
|
||||
this.$nextTick(() => {
|
||||
this.showApprovalForm = false
|
||||
this.$refs.memberChangeInfoRef.activeName = "basic"
|
||||
this.$refs.memberChangeInfoRef.onOpen({recordId:row.id, userId:row.userId})
|
||||
this.$refs.memberApplyAuditInfoRef.onOpen(row.id)
|
||||
})
|
||||
},
|
||||
closeInfo() {
|
||||
h5PopupHistory.close(this._uid)
|
||||
},
|
||||
doSearch() {
|
||||
this.pageForm.pageNumber = 1
|
||||
this.tableData = []
|
||||
@@ -381,6 +422,14 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
h5PopupHistory.register(this._uid, () => {
|
||||
this.$set(this, "infoShow", false)
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
h5PopupHistory.unregister(this._uid)
|
||||
},
|
||||
created() {
|
||||
this.initUnion()
|
||||
this.flushUnits()
|
||||
|
||||
+22
-5
@@ -191,9 +191,9 @@ layout("/layouts/platform_h5.html"){
|
||||
</van-field>
|
||||
</form>
|
||||
<div v-if="!this.$store.state.user.member" style="display: flex; justify-content: space-between; column-gap: 10px; padding: 10px">
|
||||
<van-button block v-if="formData.id" type="primary" @click.submit="$pjaxReplace('/platform/h5/member/apply/mine')">返 回</van-button>
|
||||
<van-button block type="primary" @click.submit="doSave">保存申请</van-button>
|
||||
<van-button block type="primary" @click.submit="doSubmit">提交申请</van-button>
|
||||
<!-- <van-button block v-if="formData.id" type="primary" @click.submit="$pjaxReplace('/platform/h5/member/apply/mine')">返 回</van-button> -->
|
||||
<van-button block type="primary" :disabled="isDisable" @click.submit="doSave">保存申请</van-button>
|
||||
<van-button block type="primary" :disabled="isDisable" @click.submit="doSubmit">提交申请</van-button>
|
||||
</div>
|
||||
</van-cell-group>
|
||||
</div>
|
||||
@@ -318,7 +318,7 @@ layout("/layouts/platform_h5.html"){
|
||||
return { value: item.name, text: item.name }
|
||||
})
|
||||
// 在职状态
|
||||
const userStatusData = await this.$businessTool.getDictOptions('USER_STATUS')
|
||||
const userStatusData = await this.$businessTool.getDictOptions('USER_STATE')
|
||||
this.userStateColumns = userStatusData.map(item => {
|
||||
return { value: item.name, text: item.name }
|
||||
})
|
||||
@@ -342,6 +342,9 @@ layout("/layouts/platform_h5.html"){
|
||||
if (!this.id) {
|
||||
this.formData.id = null
|
||||
this.formData.userId = res.data.id
|
||||
// 新建申请优先读取登录用户的人事信息,登录信息为空时保留接口返回值。
|
||||
this.$set(this.formData, 'userState', this.$store.state.user.userState || res.data.userState)
|
||||
this.$set(this.formData, 'preparedBy', this.$store.state.user.preparedBy || res.data.preparedBy)
|
||||
}
|
||||
if (!this.formData.families) {
|
||||
this.formData.families = []
|
||||
@@ -371,7 +374,21 @@ layout("/layouts/platform_h5.html"){
|
||||
},
|
||||
created() {
|
||||
this.initDictOptions()
|
||||
this.initUserData()
|
||||
if (this.id) {
|
||||
this.initUserData()
|
||||
return
|
||||
}
|
||||
// H5 菜单可以直达新建页面,进入前需检查本人是否已有进行中的申请。
|
||||
this.isDisable = true
|
||||
this.$axios.post('/platform/member/apply/submit/canStartNewApply', {}).then((res) => {
|
||||
if (res.code === 0 && res.data === true) {
|
||||
this.initUserData()
|
||||
this.isDisable = false
|
||||
} else {
|
||||
this.$toast.fail('您有进行中的入会申请,请先处理已有申请')
|
||||
this.$pjaxReplace('/platform/h5/member/apply/mine')
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
const MOBILE_MEMBER_APPLY_AUDIT_INFO = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<van-tabs v-model="activeName" sticky>
|
||||
<van-tab title="申请信息" name="apply">
|
||||
<van-loading v-if="viewLoading" size="24px">正在加载申请信息</van-loading>
|
||||
<van-cell-group v-else-if="viewData.id">
|
||||
<van-cell title="申请时间">{{ viewData.applyDateTime || '暂无' }}</van-cell>
|
||||
<van-cell title="工号">{{ viewData.loginname }}</van-cell>
|
||||
<van-cell title="姓名">{{ viewData.username }}</van-cell>
|
||||
<van-cell title="性别">{{ viewData.sex }}</van-cell>
|
||||
<van-cell title="民族">{{ viewData.nation }}</van-cell>
|
||||
<van-cell title="在职状态">{{ viewData.userState }}</van-cell>
|
||||
<van-cell title="人事编制">{{ viewData.preparedBy }}</van-cell>
|
||||
<van-cell title="人员类型">{{ viewData.personType }}</van-cell>
|
||||
<van-cell title="学历">{{ viewData.education }}</van-cell>
|
||||
<van-cell title="政治面貌">{{ viewData.political }}</van-cell>
|
||||
<van-cell title="证件号码">{{ viewData.idCard }}</van-cell>
|
||||
<van-cell title="联系电话">{{ viewData.mobile }}</van-cell>
|
||||
<van-cell title="电子邮箱">{{ viewData.email }}</van-cell>
|
||||
<van-cell title="所属工会">{{ viewData.unionName }}</van-cell>
|
||||
<van-cell title="工作单位">{{ viewData.unitName }}</van-cell>
|
||||
<van-cell title="岗位职务">{{ viewData.governmentPosition }}</van-cell>
|
||||
<van-cell title="是否愿意加入大病互助基金会">{{ viewData.wantJoinLoveMutualAidAssociation ? '是' : '否' }}</van-cell>
|
||||
<van-cell title="家庭主要成员及其工作单位">
|
||||
<div slot="label" v-if="families.length">
|
||||
<div v-for="(family, index) in families" :key="index">
|
||||
{{ family.relation }} {{ family.name }} {{ family.unit }} {{ family.remark }}
|
||||
</div>
|
||||
</div>
|
||||
<span v-else>暂无</span>
|
||||
</van-cell>
|
||||
<van-cell title="个人简况">
|
||||
<div slot="label" class="van-cell-rich-text" v-html="viewData.personalData"></div>
|
||||
</van-cell>
|
||||
<van-cell title="备注">{{ viewData.notes || '暂无' }}</van-cell>
|
||||
</van-cell-group>
|
||||
<van-nodata v-else :figure="23" title="暂无申请信息"></van-nodata>
|
||||
</van-tab>
|
||||
<van-tab v-if="branchRecords.length" title="分工会审核信息" name="branch">
|
||||
<van-cell-group v-for="record in branchRecords" :key="record.id" class="mb15">
|
||||
<van-cell title="审核结果">{{ record.result }}</van-cell>
|
||||
<van-cell v-if="record.originalResult" title="原审核结果">{{ record.originalResult }}</van-cell>
|
||||
<van-cell title="审核人员">{{ record.operatorName || '暂无' }}</van-cell>
|
||||
<van-cell title="审核时间">{{ record.handledAt || '暂无' }}</van-cell>
|
||||
<van-cell title="审核意见">{{ record.opinion || '暂无' }}</van-cell>
|
||||
<van-cell title="签字">
|
||||
<van-image v-if="record.signature" :src="record.signature" fit="contain" width="180" height="80"></van-image>
|
||||
<span v-else>暂无</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-tab>
|
||||
<van-tab v-if="schoolRecords.length" title="校工会审核信息" name="school">
|
||||
<van-cell-group v-for="record in schoolRecords" :key="record.id" class="mb15">
|
||||
<van-cell title="审核结果">{{ record.result }}</van-cell>
|
||||
<van-cell v-if="record.originalResult" title="原审核结果">{{ record.originalResult }}</van-cell>
|
||||
<van-cell title="审核人员">{{ record.operatorName || '暂无' }}</van-cell>
|
||||
<van-cell title="审核时间">{{ record.handledAt || '暂无' }}</van-cell>
|
||||
<van-cell title="审核意见">{{ record.opinion || '暂无' }}</van-cell>
|
||||
<van-cell title="签字">
|
||||
<van-image v-if="record.signature" :src="record.signature" fit="contain" width="180" height="80"></van-image>
|
||||
<span v-else>暂无</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</van-tab>
|
||||
</van-tabs>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
activeName: "apply",
|
||||
viewData: {},
|
||||
approvalRecords: [],
|
||||
viewLoading: false,
|
||||
requestId: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
families() {
|
||||
const value = this.viewData.families
|
||||
if (Array.isArray(value)) {
|
||||
return value
|
||||
}
|
||||
if (typeof value === "string" && value) {
|
||||
try {
|
||||
const parsed = JSON.parse(value)
|
||||
return Array.isArray(parsed) ? parsed : []
|
||||
} catch (error) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
return []
|
||||
},
|
||||
// 申请人任务不展示;20、50 节点分别为分工会和校工会审核记录。
|
||||
branchRecords() {
|
||||
return this.approvalRecords.filter((record) => Number(record.nodeCode) === 20 && record.handledAt)
|
||||
},
|
||||
schoolRecords() {
|
||||
return this.approvalRecords.filter((record) => Number(record.nodeCode) === 50 && record.handledAt)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* recordId 为申请记录 ID。接口返回 Result;data 分别为申请快照和流程记录列表,
|
||||
* 按 nodeCode 将审核结果、意见与签字 URL 分到分工会和校工会页签。
|
||||
*/
|
||||
onOpen(recordId) {
|
||||
this.$set(this, "activeName", "apply")
|
||||
this.$set(this, "viewData", {})
|
||||
this.$set(this, "approvalRecords", [])
|
||||
this.$set(this, "requestId", this.requestId + 1)
|
||||
const requestId = this.requestId
|
||||
this.$set(this, "viewLoading", true)
|
||||
return Promise.all([
|
||||
this.$axios.post("/platform/member/apply/common/findApplyRecord", { recordId }),
|
||||
this.$axios.post("/platform/member/apply/common/approvalRecords", { recordId })
|
||||
])
|
||||
.then(([applyRes, recordsRes]) => {
|
||||
if (requestId === this.requestId && applyRes.code === 0) {
|
||||
this.$set(this, "viewData", applyRes.data || {})
|
||||
this.$set(this, "approvalRecords", recordsRes.code === 0 ? recordsRes.data || [] : [])
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (requestId === this.requestId) {
|
||||
this.$set(this, "viewLoading", false)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
-5
@@ -1,7 +1,61 @@
|
||||
const MOBILE_MEMBER_CHANGE_INFO = {
|
||||
template: `
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<van-collapse v-model="activeName" accordion>
|
||||
<van-collapse-item title="本次申请" name="apply">
|
||||
<van-loading v-if="applyLoading" size="24px">正在加载申请记录</van-loading>
|
||||
<van-cell-group v-else-if="applyData.id">
|
||||
<van-cell title="申请时间">{{ applyData.applyDateTime || '暂无' }}</van-cell>
|
||||
<van-cell title="姓名">{{ applyData.username }}</van-cell>
|
||||
<van-cell title="工号">{{ applyData.loginname }}</van-cell>
|
||||
<van-cell title="所属工会">{{ applyData.unionName }}</van-cell>
|
||||
<van-cell title="工作单位">{{ applyData.unitName }}</van-cell>
|
||||
<van-cell title="岗位职务">{{ applyData.governmentPosition }}</van-cell>
|
||||
<van-cell title="性别">{{ applyData.sex }}</van-cell>
|
||||
<van-cell title="民族">{{ applyData.nation }}</van-cell>
|
||||
<van-cell title="证件号码">{{ applyData.idCard }}</van-cell>
|
||||
<van-cell title="联系电话">{{ applyData.mobile }}</van-cell>
|
||||
<van-cell title="电子邮箱">{{ applyData.email }}</van-cell>
|
||||
<van-cell title="在职状态">{{ applyData.userState }}</van-cell>
|
||||
<van-cell title="人事编制">{{ applyData.preparedBy }}</van-cell>
|
||||
<van-cell title="人员类型">{{ applyData.personType }}</van-cell>
|
||||
<van-cell title="学历">{{ applyData.education }}</van-cell>
|
||||
<van-cell title="政治面貌">{{ applyData.political }}</van-cell>
|
||||
<van-cell title="是否愿意加入大病互助基金会">{{ applyData.wantJoinLoveMutualAidAssociation ? '是' : '否' }}</van-cell>
|
||||
<van-cell title="家庭主要成员及其工作单位">
|
||||
<div slot="label" v-if="applyData.families && applyData.families.length">
|
||||
<div v-for="(family, index) in applyData.families" :key="index">
|
||||
{{ family.relation }} {{ family.name }} {{ family.unit }} {{ family.remark }}
|
||||
</div>
|
||||
</div>
|
||||
<span v-else>暂无</span>
|
||||
</van-cell>
|
||||
<van-cell title="个人简况">
|
||||
<div slot="label" class="van-cell-rich-text" v-html="applyData.personalData"></div>
|
||||
</van-cell>
|
||||
<van-cell title="备注">{{ applyData.notes || '暂无' }}</van-cell>
|
||||
</van-cell-group>
|
||||
<van-nodata :figure="23" title="暂无申请记录" v-else></van-nodata>
|
||||
</van-collapse-item>
|
||||
<van-collapse-item title="申请及审核记录" name="approval">
|
||||
<van-loading v-if="applyLoading" size="24px">正在加载审核记录</van-loading>
|
||||
<template v-else-if="approvalRecords.length">
|
||||
<van-cell-group v-for="record in approvalRecords" :key="record.id" class="mb15">
|
||||
<van-cell :title="record.nodeName" :value="record.result"></van-cell>
|
||||
<van-cell title="办理人">
|
||||
{{ record.operatorName || '暂无' }}
|
||||
<span v-if="record.operatorLoginName">({{ record.operatorLoginName }})</span>
|
||||
</van-cell>
|
||||
<van-cell title="处理时间">{{ record.handledAt || '暂无' }}</van-cell>
|
||||
<van-cell title="审核意见">{{ record.opinion || '暂无' }}</van-cell>
|
||||
<van-cell title="签字">
|
||||
<van-image v-if="record.signature" :src="record.signature" fit="contain" width="150" height="70"></van-image>
|
||||
<span v-else>暂无</span>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
</template>
|
||||
<van-nodata :figure="23" title="暂无申请及审核记录" v-else></van-nodata>
|
||||
</van-collapse-item>
|
||||
<van-collapse-item name="basic">
|
||||
<template #title>
|
||||
<span style="color: #409eff">会员基础信息</span>
|
||||
@@ -50,24 +104,64 @@ const MOBILE_MEMBER_CHANGE_INFO = {
|
||||
</table>
|
||||
</van-collapse-item>
|
||||
</van-collapse>
|
||||
<slot></slot>
|
||||
</div>
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
changeList: [],
|
||||
viewData: {},
|
||||
applyData: {},
|
||||
approvalRecords: [],
|
||||
applyLoading: false,
|
||||
applyRequestId: 0,
|
||||
activeName: "basic"
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
removeHTMLTag,
|
||||
findAuditChangeInfo(recordId) {
|
||||
/**
|
||||
* recordId 为当前申请记录 ID;两个接口的 Result.data 分别返回申请资料和任务历史列表。
|
||||
* 历史项包含节点、办理人、处理时间、结果、意见及签名图片 URL。
|
||||
* 申请快照单独展示,避免审核后更新的会员资料覆盖原申请内容。
|
||||
*/
|
||||
findApplyRecord(recordId) {
|
||||
this.$set(this, "applyData", {})
|
||||
this.$set(this, "approvalRecords", [])
|
||||
this.$set(this, "applyRequestId", this.applyRequestId + 1)
|
||||
const requestId = this.applyRequestId
|
||||
this.$set(this, "applyLoading", false)
|
||||
if (!recordId) {
|
||||
return
|
||||
}
|
||||
this.$axios.post("/platform/member/apply/branchUnionAudit/findAuditChangeInfo", { recordId: recordId }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.changeList = res.data
|
||||
this.$set(this, "applyLoading", true)
|
||||
return Promise.all([
|
||||
this.$axios.post("/platform/member/apply/common/findApplyRecord", { recordId }),
|
||||
this.$axios.post("/platform/member/apply/common/approvalRecords", { recordId })
|
||||
])
|
||||
.then(([res, recordsRes]) => {
|
||||
// 弹框切换到另一条申请后,忽略先前尚未完成的查询响应。
|
||||
if (res.code === 0 && requestId === this.applyRequestId) {
|
||||
this.$set(this, "applyData", res.data || {})
|
||||
this.$set(this, "approvalRecords", recordsRes.code === 0 ? recordsRes.data || [] : [])
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
if (requestId === this.applyRequestId) {
|
||||
this.$set(this, "applyLoading", false)
|
||||
}
|
||||
})
|
||||
},
|
||||
findAuditChangeInfo(recordId) {
|
||||
this.$set(this, "changeList", [])
|
||||
if (!recordId) {
|
||||
return
|
||||
}
|
||||
// 公共接口同时识别 PC、H5 权限,校工会和本人查看无需借用分工会审核权限。
|
||||
const requestId = this.applyRequestId
|
||||
return this.$axios.post("/platform/member/apply/common/findApplyChanges", { recordId }).then((res) => {
|
||||
if (res.code === 0 && requestId === this.applyRequestId) {
|
||||
this.$set(this, "changeList", res.data || [])
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -82,6 +176,11 @@ const MOBILE_MEMBER_CHANGE_INFO = {
|
||||
})
|
||||
},
|
||||
onOpen(data) {
|
||||
this.findApplyRecord(data.recordId)
|
||||
// 查看默认展开本次申请;审核入口指定的“变更信息”仍按原设置展开。
|
||||
if (this.activeName !== "change") {
|
||||
this.$set(this, "activeName", "apply")
|
||||
}
|
||||
this.findAuditChangeInfo(data.recordId)
|
||||
this.$nextTick(() => {
|
||||
this.findUserInfo(data.userId)
|
||||
|
||||
Reference in New Issue
Block a user