Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3db3de39c5 | ||
|
|
9bb29a57de | ||
|
|
49407374b0 | ||
|
|
f83513d8f1 |
@@ -49,7 +49,9 @@ public class MemberAgendaController {
|
||||
final String title = "【会员系统】";
|
||||
|
||||
List<NutMap> list = new ArrayList<>();
|
||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06,gh01,H03")) {
|
||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06,gh01,H03")
|
||||
&& !org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.union")
|
||||
&& !org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.school")) {
|
||||
return list;
|
||||
}
|
||||
boolean anyRoles = ShiroUtil.hasAnyRoles("sysadmin,A06,H03");
|
||||
@@ -67,20 +69,26 @@ public class MemberAgendaController {
|
||||
|
||||
int marUnionNum = 0;
|
||||
Cnd marUnionCnd = Cnd.where("mar.stateId", "=", MemberApplyState.UNION);
|
||||
if (!anyRoles) {
|
||||
marUnionCnd.and("u.unionid", "=", Vi.getUnionId());
|
||||
// 入会审核范围与 PC 部门审核列表一致,校级角色不能自动越过部门权限。
|
||||
if (!ShiroUtil.hasAnyRoles("sysadmin")) {
|
||||
marUnionCnd.and("mar.unionId", "=", Vi.getUnionId());
|
||||
}
|
||||
marSql.setCondition(marUnionCnd);
|
||||
marUnionNum = memberService.count(marSql);
|
||||
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/union")).addv("label", "待部门工会入会审核").addv("number", marUnionNum).addv("url", "/platform/member/apply/audit/union"));
|
||||
if (org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.union"))
|
||||
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/union")).addv("label", "待部门工会入会审核").addv("number", marUnionNum).addv("url", "/platform/member/apply/audit/union"));
|
||||
|
||||
int marSchoolNum = 0;
|
||||
Cnd marSchoolCnd = Cnd.where("mar.stateId", "=", MemberApplyState.SCHOOL_UNION);
|
||||
marSql.setCondition(marSchoolCnd);
|
||||
marSchoolNum = memberService.count(marSql);
|
||||
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/school")).addv("label", "待校工会入会审核").addv("number", marSchoolNum).addv("url", "/platform/member/apply/audit/school"));
|
||||
if (org.apache.shiro.SecurityUtils.getSubject().isPermitted("member.apply.audit.school"))
|
||||
list.add(new NutMap().addv("title", title).addv("iconClass", vi.getIconByPath("/platform/member/apply/audit/school")).addv("label", "待校工会入会审核").addv("number", marSchoolNum).addv("url", "/platform/member/apply/audit/school"));
|
||||
|
||||
|
||||
// 非原会员变更管理角色仅返回按权限计算的入会待办。
|
||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06,gh01,H03")) return list;
|
||||
|
||||
// 会员变更
|
||||
Sql mcrSql = Sqls.create("""
|
||||
SELECT
|
||||
@@ -111,4 +119,24 @@ public class MemberAgendaController {
|
||||
List<Sys_menu> menus = Optional.ofNullable(user).orElse(new Sys_user()).getMenus();
|
||||
return list.stream().filter(v -> Strings.isNotBlank(v.getString("url")) && menus.stream().anyMatch(x -> Strings.isNotBlank(x.getHref()) && v.getString("url").contains(x.getHref()))).distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 无需参数,返回当前登录人今年可办理的入会审核节点。
|
||||
* 每项 title/name/count/mobileHref 分别表示业务标题、节点名称、待办数量和手机入口。
|
||||
*/
|
||||
@At
|
||||
@ViReturn
|
||||
public Object getMobileAgenda() {
|
||||
return memberService.getCurrentYearApplyAgenda();
|
||||
}
|
||||
|
||||
/**
|
||||
* 无需传入办理人,身份从登录会话获取;返回本人今年实际办理的会员入会记录。
|
||||
* 每项 moduleName/auditState/auditTime/mobileUrl 为业务名称、办理节点、办理时间和只读详情地址。
|
||||
*/
|
||||
@At
|
||||
@ViReturn
|
||||
public Object getCompletes() {
|
||||
return memberService.getCurrentYearApplyCompletes();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@ import io.v.nutz.util.ShiroUtil;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
@@ -130,6 +132,7 @@ public class MemberApplyAuditController {
|
||||
|
||||
@At
|
||||
@ViReturn
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Object doAudit(@ViRequired String recordId, Audit audit) {
|
||||
MemberApplyRecord record = memberApplyRecordViService.fetch(recordId);
|
||||
MemberApplyAuditHandle applyHandle = Enum.instance(MemberApplyAuditHandle.class, record.getStateId());
|
||||
|
||||
@@ -7,6 +7,7 @@ import io.v.nutz.diseaseaid.constant.AidFundMemberAuditState;
|
||||
import io.v.nutz.diseaseaid.mode.AidFundMemberMode;
|
||||
import io.v.nutz.diseaseaid.model.AidFundMemberAuditRecord;
|
||||
import io.v.nutz.member.UserMode;
|
||||
import io.v.nutz.member.service.MemberService;
|
||||
import io.v.nutz.member.constant.MemberApplyState;
|
||||
import io.v.nutz.member.constant.MemberOrigin;
|
||||
import io.v.nutz.member.model.MemberApplyRecord;
|
||||
@@ -25,6 +26,8 @@ import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.util.ViResource;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import lombok.Getter;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
@@ -55,6 +58,7 @@ public enum MemberApplyAuditHandle {
|
||||
*/
|
||||
CREATE(null) {
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
||||
record.setUserId(ShiroUtil.getPrincipalProperty("id").toString());
|
||||
record.setStateId(MemberApplyState.UNION);
|
||||
@@ -64,22 +68,8 @@ public enum MemberApplyAuditHandle {
|
||||
Sys_user user = sysUserService.fetch(record.getUserId());
|
||||
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
su.loginname,
|
||||
su.username
|
||||
FROM
|
||||
sys_user_role sur
|
||||
LEFT JOIN sys_user su ON su.id = sur.userId
|
||||
WHERE
|
||||
sur.roleId = @roleId
|
||||
AND sur.unionid = @unionId
|
||||
""")
|
||||
// .setParam("roleId", Roles.UNION_MANGER)
|
||||
.setParam("roleId", Roles.GH01)
|
||||
.setParam("unionId", record.getUnionId());
|
||||
|
||||
List<NutMap> mapList = sysUserService.listMap(sql);
|
||||
// 接收人由 PC 部门审核权限关联的角色确定,并限定申请所属工会。
|
||||
List<NutMap> mapList = memberService.applyAuditRecipients(false, record.getUnionId());
|
||||
|
||||
if (Lang.isNotEmpty(mapList)) {
|
||||
List<TodoTask.Processor> processors = new ArrayList<>();
|
||||
@@ -102,6 +92,8 @@ public enum MemberApplyAuditHandle {
|
||||
todoTask.setInitiatorId(user.getLoginname());
|
||||
todoTask.setPcViewUrl(Globals.AppDomain + "/platform/member/apply/audit/union");
|
||||
todoTask.setH5ViewUrl(Globals.AppDomain + "/mobile/member/audit");
|
||||
todoTask.setDoneH5Url(Globals.AppDomain + "/mobile/member/audit?isAudit=true");
|
||||
todoTask.setDonePcUrl(todoTask.getPcViewUrl() + "?audit=1");
|
||||
todoTask.setBizId(insert.getId());
|
||||
todoTask.setBizType("申请入会部门工会审核");
|
||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.ACTIVE.name());
|
||||
@@ -121,6 +113,7 @@ public enum MemberApplyAuditHandle {
|
||||
*/
|
||||
AUDIT_UNION(MemberApplyState.UNION) {
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
||||
|
||||
record.setStateId(audit.getAuditPass() ? MemberApplyState.SCHOOL_UNION : MemberApplyState.UNION_FAIL);
|
||||
@@ -130,18 +123,8 @@ public enum MemberApplyAuditHandle {
|
||||
|
||||
if (audit.getAuditPass()) {
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
su.loginname,
|
||||
su.username
|
||||
FROM
|
||||
sys_user_role sur
|
||||
LEFT JOIN sys_user su ON su.id = sur.userId
|
||||
WHERE
|
||||
sur.roleId = @roleId
|
||||
""").setParam("roleId", Roles.H03);
|
||||
|
||||
List<NutMap> mapList = sysUserService.listMap(sql);
|
||||
// 部门通过后仅向具有 PC 校工会审核权限的角色成员派发下一阶段待办。
|
||||
List<NutMap> mapList = memberService.applyAuditRecipients(true, record.getUnionId());
|
||||
|
||||
if (Lang.isNotEmpty(mapList)) {
|
||||
List<TodoTask.Processor> processors = new ArrayList<>();
|
||||
@@ -163,6 +146,8 @@ public enum MemberApplyAuditHandle {
|
||||
todoTask.setInitiatorId(user.getLoginname());
|
||||
todoTask.setPcViewUrl(Globals.AppDomain + "/platform/member/apply/audit/school");
|
||||
todoTask.setH5ViewUrl(Globals.AppDomain + "/mobile/member/audit");
|
||||
todoTask.setDoneH5Url(Globals.AppDomain + "/mobile/member/audit?isAudit=true");
|
||||
todoTask.setDonePcUrl(todoTask.getPcViewUrl() + "?audit=1");
|
||||
todoTask.setBizId(record.getId());
|
||||
todoTask.setBizType("申请入会校工会审核");
|
||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.ACTIVE.name());
|
||||
@@ -178,14 +163,7 @@ public enum MemberApplyAuditHandle {
|
||||
List.of(Map.of("tool", MsgApi.sendTool.wechat_enterprise.name())));
|
||||
}
|
||||
|
||||
//部门工会的待办设置为完成
|
||||
TodoTask todoTask = dao.fetch(TodoTask.class, Cnd.where("bizId", "=", record.getId())
|
||||
.and("bizType", "=", "申请入会部门工会审核"));
|
||||
if (todoTask != null) {
|
||||
todoTask.setProcessorId(ShiroUtil.getPrincipalProperty("loginname").toString());
|
||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.COMPLETE.name());
|
||||
todoTaskInterface.updateTask(todoTask);
|
||||
}
|
||||
memberService.completeApplyAuditTasks(record.getId(), false);
|
||||
return record;
|
||||
}
|
||||
},
|
||||
@@ -194,6 +172,7 @@ public enum MemberApplyAuditHandle {
|
||||
*/
|
||||
AUDIT_SCHOOL(MemberApplyState.SCHOOL_UNION) {
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public MemberApplyRecord next(MemberApplyRecord record, Audit audit) {
|
||||
|
||||
memberApplyRecordViService.transactional(() -> {
|
||||
@@ -242,14 +221,7 @@ public enum MemberApplyAuditHandle {
|
||||
List.of(Map.of("tool", MsgApi.sendTool.wechat_enterprise.name())));
|
||||
}
|
||||
|
||||
//校工会的待办设置为完成
|
||||
TodoTask todoTask = dao.fetch(TodoTask.class, Cnd.where("bizId", "=", record.getId())
|
||||
.and("bizType", "=", "申请入会校工会审核"));
|
||||
if (todoTask != null) {
|
||||
todoTask.setProcessorId(ShiroUtil.getPrincipalProperty("loginname").toString());
|
||||
todoTask.setStatus(TodoTaskEnum.TaskStatus.COMPLETE.name());
|
||||
todoTaskInterface.updateTask(todoTask);
|
||||
}
|
||||
memberService.completeApplyAuditTasks(record.getId(), true);
|
||||
});
|
||||
|
||||
sysUserService.deleteCache(record.getUserId());
|
||||
@@ -270,6 +242,7 @@ public enum MemberApplyAuditHandle {
|
||||
public TodoTaskInterface todoTaskInterface = ViResource.ioc.getByType(TodoTaskInterface.class);
|
||||
public MsgApi msgApi = ViResource.ioc.getByType(MsgApi.class);
|
||||
public Dao dao = ViResource.dao;
|
||||
public MemberService memberService = ViResource.ioc.getByType(MemberService.class);
|
||||
|
||||
public abstract MemberApplyRecord next(MemberApplyRecord record, Audit audit);
|
||||
|
||||
|
||||
@@ -34,4 +34,21 @@ public interface MemberService extends ViService<Sys_user> {
|
||||
* @return
|
||||
*/
|
||||
Pagination memberChangeRecords(PageForm pageForm, CndPlus cnd);
|
||||
/** 按当前用户 PC 审核权限查询手机列表;isAudit 为已审标记,year 可空,返回 list/totalCount 分页数据。 */
|
||||
Object mobileApplyAuditPage(int pageNumber, int pageSize, boolean isAudit, Integer year);
|
||||
|
||||
/** 按申请记录校验访问范围并返回审核/只读视图,userId 必须属于该记录,done 强制只读。 */
|
||||
String mobileApplyAuditView(String recordId, String userId, boolean done);
|
||||
|
||||
/** 查询拥有指定阶段审核权限的启用角色成员;部门阶段限定 unionId,返回 loginname/username。 */
|
||||
List<NutMap> applyAuditRecipients(boolean school, String unionId);
|
||||
|
||||
/** 关闭指定申请当前阶段的全部有效待办,保留接收人并记录实际办理人和已办地址。 */
|
||||
void completeApplyAuditTasks(String recordId, boolean school);
|
||||
|
||||
/** 返回当前年份入会待办卡片;身份取当前会话,部门限定本工会,超管可查看两级范围。 */
|
||||
List<NutMap> getCurrentYearApplyAgenda();
|
||||
|
||||
/** 返回当前登录人本年度实际审核的入会记录及只读详情地址,不把角色范围内的已审视作本人已办。 */
|
||||
List<NutMap> getCurrentYearApplyCompletes();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,21 @@ import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.plugins.wkcache.annotation.CacheDefaults;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import io.v.nutz.base.utils.Vi;
|
||||
import io.v.nutz.member.constant.MemberApplyState;
|
||||
import io.v.nutz.member.model.MemberApplyRecord;
|
||||
import io.v.nutz.todoTask.TodoTask;
|
||||
import io.v.nutz.todoTask.TodoTaskInterface;
|
||||
import io.v.nutz.web.commons.base.Globals;
|
||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||
import org.apache.shiro.authz.UnauthorizedException;
|
||||
import org.apache.shiro.authz.permission.WildcardPermission;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.lang.Strings;
|
||||
|
||||
|
||||
/**
|
||||
@@ -70,4 +85,151 @@ public class MemberServiceImpl extends ViServiceImpl<Sys_user> implements Member
|
||||
Sql sql = Sqls.create(MEMBER_CHANGE_RECORDS).setCondition(cnd);
|
||||
return list(pageForm, sql);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private TodoTaskInterface todoTaskInterface;
|
||||
|
||||
/** 与 PC 页面的权限注解一致,不能用待办角色名称替代审核权限。 */
|
||||
private boolean canApplyAudit(boolean school) {
|
||||
return ShiroUtil.hasPermission("member.apply.audit." + (school ? "school" : "union"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object mobileApplyAuditPage(int pageNumber, int pageSize, boolean isAudit, Integer year) {
|
||||
boolean union = canApplyAudit(false);
|
||||
boolean school = canApplyAudit(true);
|
||||
if (!union && !school) throw new UnauthorizedException("无会员审核权限");
|
||||
Sql sql = Sqls.create("SELECT mar.*, st.stateName, st.stateColor, u.unionname, u.username, "
|
||||
+ "u.loginname, u.personType FROM member_apply_record mar "
|
||||
+ "LEFT JOIN audit_state st ON st.stateId=mar.stateId LEFT JOIN `user` u ON u.id=mar.userId $condition");
|
||||
SqlExpressionGroup scope = new SqlExpressionGroup();
|
||||
// 已审沿用 PC 各阶段 stateId > 当前阶段的口径;双权限取并集,避免重复记录。
|
||||
if (union && (ShiroUtil.hasRole("sysadmin") || Strings.isNotBlank(Vi.getUnionId()))) {
|
||||
Cnd department = Cnd.where("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION);
|
||||
if (!ShiroUtil.hasRole("sysadmin")) department.and("mar.unionId", "=", Vi.getUnionId());
|
||||
scope.or(department.where());
|
||||
} else if (!school) {
|
||||
return listPageMap(Math.max(1, pageNumber), Math.max(1, pageSize), sql.setCondition(Cnd.where("1", "=", 0)));
|
||||
}
|
||||
if (school) scope.or("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
||||
CndPlus cnd = CndPlus.create();
|
||||
cnd.and(scope);
|
||||
cnd.andExcludeEmpty("YEAR(mar.applyTime)", "=", year);
|
||||
cnd.asc("mar.stateId").desc("mar.applyTime");
|
||||
return listPageMap(Math.max(1, pageNumber), Math.max(1, Math.min(pageSize, 100)), sql.setCondition(cnd));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String mobileApplyAuditView(String recordId, String userId, boolean done) {
|
||||
MemberApplyRecord record = Strings.isBlank(recordId) ? null : dao().fetch(MemberApplyRecord.class, recordId);
|
||||
if (record == null || !Objects.equals(record.getUserId(), userId)) {
|
||||
throw new IllegalArgumentException("申请记录不存在或申请人不匹配");
|
||||
}
|
||||
boolean union = canApplyAudit(false) && (ShiroUtil.hasRole("sysadmin")
|
||||
|| Strings.isNotBlank(Vi.getUnionId()) && Objects.equals(Vi.getUnionId(), record.getUnionId()));
|
||||
boolean school = canApplyAudit(true) && record.getStateId() != null
|
||||
&& record.getStateId() >= MemberApplyState.SCHOOL_UNION;
|
||||
if (!union && !school) throw new UnauthorizedException("无权查看该申请");
|
||||
if (!done && union && Objects.equals(record.getStateId(), MemberApplyState.UNION)) {
|
||||
return "beetl:/mobile/member/union_Audit.html";
|
||||
}
|
||||
if (!done && school && Objects.equals(record.getStateId(), MemberApplyState.SCHOOL_UNION)) {
|
||||
return "beetl:/mobile/member/school_Audit.html";
|
||||
}
|
||||
return "beetl:/mobile/member/detail.html";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> applyAuditRecipients(boolean school, String unionId) {
|
||||
// 从 PC 权限对应的角色成员取接收人,兼容 Shiro 通配权限并排除禁用角色、菜单和账号。
|
||||
Sql sql = Sqls.create("SELECT DISTINCT su.loginname, su.username, sm.permission FROM sys_user_role sur "
|
||||
+ "JOIN sys_user su ON su.id=sur.userId JOIN sys_role sr ON sr.id=sur.roleId "
|
||||
+ "JOIN sys_role_menu srm ON srm.roleId=sr.id JOIN sys_menu sm ON sm.id=srm.menuId "
|
||||
+ "WHERE sr.disabled=false AND sm.disabled=false AND su.disabled=false "
|
||||
+ (school ? "" : "AND sur.unionid=@unionId AND su.unionid=@unionId "));
|
||||
sql.setParam("unionId", unionId);
|
||||
WildcardPermission required = new WildcardPermission("member.apply.audit." + (school ? "school" : "union"));
|
||||
java.util.Map<String, NutMap> recipients = new java.util.LinkedHashMap<>();
|
||||
for (NutMap row : listMap(sql)) {
|
||||
String permission = row.getString("permission");
|
||||
if (Strings.isNotBlank(permission) && Strings.isNotBlank(row.getString("loginname"))
|
||||
&& new WildcardPermission(permission).implies(required)) {
|
||||
recipients.putIfAbsent(row.getString("loginname"), row);
|
||||
}
|
||||
}
|
||||
return new java.util.ArrayList<>(recipients.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void completeApplyAuditTasks(String recordId, boolean school) {
|
||||
// 同阶段可能存在历史重复待办,只关闭 ACTIVE 项,保留接收角色成员列表用于已办归属。
|
||||
List<TodoTask> tasks = dao().query(TodoTask.class, Cnd.where("bizId", "=", recordId)
|
||||
.and("bizType", "=", school ? "申请入会校工会审核" : "申请入会部门工会审核")
|
||||
.and("status", "=", "ACTIVE").and(Cnd.exps("delFlag", "=", false).or("delFlag", "is", null)));
|
||||
for (TodoTask task : tasks) {
|
||||
task.setProcessorId(ShiroUtil.getPrincipalProperty("loginname").toString());
|
||||
task.setStatus("COMPLETE");
|
||||
task.setDonePcUrl(Globals.AppDomain + "/platform/member/apply/audit/" + (school ? "school" : "union") + "?audit=1");
|
||||
task.setDoneH5Url(Globals.AppDomain + "/mobile/member/audit?isAudit=true");
|
||||
todoTaskInterface.updateTask(task);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> getCurrentYearApplyAgenda() {
|
||||
int year = java.time.LocalDate.now().getYear();
|
||||
boolean admin = ShiroUtil.hasRole("sysadmin");
|
||||
List<NutMap> items = new java.util.ArrayList<>();
|
||||
for (boolean school : new boolean[]{false, true}) {
|
||||
if (!admin && !canApplyAudit(school)) continue;
|
||||
// 没有工会归属的部门审核人不能因空条件而获得全校范围。
|
||||
if (!school && !admin && Strings.isBlank(Vi.getUnionId())) continue;
|
||||
Cnd cnd = Cnd.where("stateId", "=", school ? MemberApplyState.SCHOOL_UNION : MemberApplyState.UNION)
|
||||
.and("applyTime", ">=", year + "-01-01")
|
||||
.and("applyTime", "<", (year + 1) + "-01-01");
|
||||
if (!school && !admin) cnd.and("unionId", "=", Vi.getUnionId());
|
||||
int count = dao().count(MemberApplyRecord.class, cnd);
|
||||
items.add(new NutMap().setv("title", "【会员入会】")
|
||||
.setv("name", school ? "待校工会入会审核" : "待部门工会入会审核")
|
||||
.setv("count", count).setv("mobileHref", "/mobile/member/audit"));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> getCurrentYearApplyCompletes() {
|
||||
Object principalLoginname = ShiroUtil.getPrincipalProperty("loginname");
|
||||
String loginname = principalLoginname == null ? "" : principalLoginname.toString();
|
||||
boolean admin = ShiroUtil.hasRole("sysadmin");
|
||||
boolean union = admin || canApplyAudit(false);
|
||||
boolean school = admin || canApplyAudit(true);
|
||||
if (Strings.isBlank(loginname) || !union && !school) return java.util.Collections.emptyList();
|
||||
int year = java.time.LocalDate.now().getYear();
|
||||
// 只读取当前申请实际关联的审核记录,按办理工号和办理年份筛选;同人办理两级保留两个节点。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT mar.id, a.id auditId, nodes.nodeId,
|
||||
CONCAT('【会员入会】', COALESCE(u.username, '')) moduleName,
|
||||
nodes.nodeName auditState, a.auditTime,
|
||||
CONCAT('/mobile/member/audit/findOne?record_id=', mar.id,
|
||||
'&user_id=', mar.userId, '&done=true') mobileUrl
|
||||
FROM member_apply_record mar
|
||||
LEFT JOIN `user` u ON u.id=mar.userId
|
||||
JOIN (SELECT 1 nodeId, '部门工会审核' nodeName
|
||||
UNION ALL SELECT 2, '校工会审核') nodes ON 1=1
|
||||
JOIN audit a ON a.id=CASE nodes.nodeId WHEN 1 THEN mar.unionAuditId ELSE mar.schoolAuditId END
|
||||
WHERE a.loginname=@loginname AND a.auditTime>=@startTime AND a.auditTime<@endTime
|
||||
AND ((nodes.nodeId=1 AND @unionAllowed=1 AND (@admin=1 OR mar.unionId=@unionId))
|
||||
OR (nodes.nodeId=2 AND @schoolAllowed=1))
|
||||
ORDER BY a.auditTime DESC, mar.id, nodes.nodeId
|
||||
""");
|
||||
sql.setParam("loginname", loginname);
|
||||
sql.setParam("startTime", year + "-01-01");
|
||||
sql.setParam("endTime", (year + 1) + "-01-01");
|
||||
sql.setParam("unionAllowed", union ? 1 : 0);
|
||||
sql.setParam("schoolAllowed", school ? 1 : 0);
|
||||
sql.setParam("admin", admin ? 1 : 0);
|
||||
sql.setParam("unionId", Strings.sNull(Vi.getUnionId()));
|
||||
return listMap(sql);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,112 +1,47 @@
|
||||
package io.v.nutz.mobile.member;
|
||||
|
||||
import cn.wizzer.framework.base.service.BaseService;
|
||||
import io.v.nutz.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.Vi;
|
||||
import io.v.nutz.dao.CndPlus;
|
||||
import io.v.nutz.member.constant.MemberApplyState;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import io.v.nutz.member.service.MemberService;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.apache.shiro.authz.annotation.Logical;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
/**
|
||||
* @author zhf
|
||||
* @date 2021/9/26 9:24
|
||||
* @description
|
||||
*/
|
||||
/** 手机端会员审核统一入口,与 PC 端共享两级审核权限。 */
|
||||
@IocBean
|
||||
@At("/mobile/member/audit")
|
||||
@Ok("json:full")
|
||||
@RequiresAuthentication
|
||||
@RequiresPermissions(value = {"member.apply.audit.union", "member.apply.audit.school"}, logical = Logical.OR)
|
||||
public class MemberAuditUnionController {
|
||||
@Inject
|
||||
private MemberService memberService;
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/mobile/member/audit_list.html")
|
||||
public void indext() {
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
|
||||
|
||||
/**
|
||||
* pageNumber/pageSize 为页码和每页条数,isAudit 区分已审/待审,year 为申请年份(可空)。
|
||||
* 返回分页对象,list 为申请记录,totalCount 为符合当前审核权限的数据总数。
|
||||
*/
|
||||
@At
|
||||
@ViReturn
|
||||
public Object pageData(int pageNumber, int pageSize, boolean isAudit, Integer year) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
mar.*,
|
||||
st.stateName,
|
||||
st.stateColor,
|
||||
u.unionname,
|
||||
u.username,
|
||||
u.loginname,
|
||||
u.personType
|
||||
FROM
|
||||
`member_apply_record` mar
|
||||
LEFT JOIN audit_state st ON st.stateId = mar.stateId
|
||||
LEFT JOIN `user` u ON u.id = mar.userId
|
||||
$condition
|
||||
""");
|
||||
|
||||
CndPlus cnd = CndPlus.create();
|
||||
cnd.and("mar.memberStates", "=", 1);
|
||||
|
||||
if (ShiroUtil.hasAnyRoles("sysadmin")) {
|
||||
cnd.and("mar.stateId", "in", isAudit ? Lang.array(MemberApplyState.UNION_FAIL, MemberApplyState.SCHOOL_UNION_FAIL, MemberApplyState.NORMAL_MEMBER) : Lang.array(MemberApplyState.UNION, MemberApplyState.SCHOOL_UNION));
|
||||
} else {
|
||||
if (ShiroUtil.hasAnyRoles("A06,wyh02") && ShiroUtil.hasAnyRoles("H04")) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.or("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
||||
seg.or(CndPlus.exps("mar.unionId", "=", Vi.getUnionId()).and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION));
|
||||
cnd.and(seg);
|
||||
} else if (ShiroUtil.hasAnyRoles("A06,wyh02")) {
|
||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
||||
} else if (ShiroUtil.hasAnyRoles("H04")) {
|
||||
cnd.and("mar.unionId", "=", Vi.getUnionId());
|
||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION);
|
||||
}
|
||||
|
||||
|
||||
/*if (ShiroUtil.hasAnyRoles("A06,wyh02")) {
|
||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
||||
} else if (ShiroUtil.hasAnyRoles("H04")) {
|
||||
cnd.and("mar.unionId", "=", Vi.getUnionId());
|
||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.UNION);
|
||||
}*/
|
||||
}
|
||||
|
||||
/* if (!ShiroUtil.hasAnyRoles("sysadmin")) {
|
||||
if (ShiroUtil.hasAnyRoles("A06,wyh02")) {
|
||||
cnd.and("mar.stateId", isAudit ? ">" : "=", MemberApplyState.SCHOOL_UNION);
|
||||
}
|
||||
}*/
|
||||
|
||||
cnd.andExcludeEmpty("YEAR(mar.applyTime)", "=", year);
|
||||
|
||||
cnd.asc("mar.stateId");
|
||||
cnd.desc("mar.applyTime");
|
||||
sql.setCondition(cnd);
|
||||
return baseService.listPageMap(pageNumber, pageSize, sql);
|
||||
return memberService.mobileApplyAuditPage(pageNumber, pageSize, isAudit, year);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* record_id 为申请记录 ID,user_id 为申请人 ID,done 表示从已办入口只读查看。
|
||||
* 返回 Beetl 页面视图;实际审核阶段和访问范围均由数据库记录决定。
|
||||
*/
|
||||
@At("/findOne")
|
||||
@Ok("re")
|
||||
public String findOne(Integer stateId) {
|
||||
if (stateId == MemberApplyState.UNION && ShiroUtil.hasAnyRoles("H04,A06,sysadmin")) {
|
||||
return "beetl:/mobile/member/union_Audit.html";
|
||||
} else if (stateId == MemberApplyState.SCHOOL_UNION && ShiroUtil.hasAnyRoles("A06,sysadmin")) {
|
||||
return "beetl:/mobile/member/school_Audit.html";
|
||||
} /*else if (stateId == MemberApplyState.NORMAL_MEMBER || stateId == MemberApplyState.UNION_FAIL || stateId == MemberApplyState.SCHOOL_UNION_FAIL) {
|
||||
return "beetl:/mobile/member/detail.html";
|
||||
}*/
|
||||
return "beetl:/mobile/member/detail.html";
|
||||
public String findOne(String record_id, String user_id, boolean done) {
|
||||
return memberService.mobileApplyAuditView(record_id, user_id, done);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -121,11 +121,12 @@ public class MemberMobileController {
|
||||
@ViReturn
|
||||
@RequiresRoles(value = {"H04", "A06"}, logical = Logical.OR)
|
||||
public Object viewInfo(String id) {
|
||||
// 用户表仅存储出生日期,按当前日期计算周岁,空出生日期返回空年龄。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
u.username,
|
||||
u.sex,
|
||||
u.age,
|
||||
TIMESTAMPDIFF(YEAR, NULLIF(u.birthday, ''), CURDATE()) AS age,
|
||||
u.nation,
|
||||
u.education,
|
||||
u.political,
|
||||
|
||||
@@ -12,13 +12,11 @@ import io.v.nutz.sys.models.Sys_menu;
|
||||
import io.v.nutz.sys.models.Sys_user;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.zgfw.service.CondolenceService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
@@ -53,71 +51,24 @@ public class CondolenceAgentController {
|
||||
|
||||
List<NutMap> result = new ArrayList<>();
|
||||
|
||||
result.add(new NutMap().setv("title", title).setv("url", UCR).setv("iconClass", vi.getIconByPath(UCR)).setv("label", "待部门工会审核").setv("number", getUcrCount()));
|
||||
result.add(new NutMap().setv("title", title).setv("url", FR).setv("iconClass", vi.getIconByPath(FR)).setv("label", "待二级党组织审核").setv("number", getFrCount()));
|
||||
result.add(new NutMap().setv("title", title).setv("url", VCR).setv("iconClass", vi.getIconByPath(VCR)).setv("label", "待校工会审核").setv("number", getVcrCount()));
|
||||
result.add(new NutMap().setv("title", title).setv("url", ECR).setv("iconClass", vi.getIconByPath(ECR)).setv("label", "待工会常务副主席审核").setv("number", getEcrCount()));
|
||||
result.add(new NutMap().setv("title", title).setv("url", UCR).setv("iconClass", vi.getIconByPath(UCR)).setv("label", "待部门工会审核").setv("number", condolenceService.countCurrentYearAgenda(2000)));
|
||||
result.add(new NutMap().setv("title", title).setv("url", FR).setv("iconClass", vi.getIconByPath(FR)).setv("label", "待二级党组织审核").setv("number", condolenceService.countCurrentYearAgenda(2012)));
|
||||
result.add(new NutMap().setv("title", title).setv("url", VCR).setv("iconClass", vi.getIconByPath(VCR)).setv("label", "待校工会审核").setv("number", condolenceService.countCurrentYearAgenda(2020)));
|
||||
result.add(new NutMap().setv("title", title).setv("url", ECR).setv("iconClass", vi.getIconByPath(ECR)).setv("label", "待工会常务副主席审核").setv("number", condolenceService.countCurrentYearAgenda(2050)));
|
||||
Sys_user user = (Sys_user) ShiroUtil.getPrincipal();
|
||||
List<Sys_menu> menus = Optional.ofNullable(user).orElse(new Sys_user()).getMenus();
|
||||
return result.stream().filter(v -> Strings.isNotBlank(v.getString("url")) && menus.stream().anyMatch(x -> Strings.isNotBlank(x.getHref()) && v.getString("url").equals(x.getHref()))).distinct().collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 待工会主席审核
|
||||
*
|
||||
* @return
|
||||
* 无需传参,身份取自登录会话,返回今年本人办理的慰问记录列表。
|
||||
* 每项包含 moduleName(业务名称)、auditState(办理节点)、auditTime(审核日期)、mobileUrl(详情链接)。
|
||||
*/
|
||||
private Integer getUcrCount() {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT COUNT(1) FROM condolence con LEFT JOIN `user` us ON con.be_user=us.id $condition
|
||||
""");
|
||||
cnd.and("con.state_id", "=", 2000);
|
||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
||||
cnd.and("us.unionid", "=", vi.getUnionId());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return condolenceService.count(sql);
|
||||
@At
|
||||
@ViReturn
|
||||
@RequiresAuthentication
|
||||
public Object getCompletes() {
|
||||
return condolenceService.getCurrentYearCompletes();
|
||||
}
|
||||
|
||||
/**
|
||||
* 待工会会计审核
|
||||
* 暂时没用
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Integer getFrCount() {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT COUNT(1) FROM condolence con LEFT JOIN `user` us ON con.be_user=us.id $condition
|
||||
""");
|
||||
cnd.and("con.state_id", "=", 2012);
|
||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
||||
cnd.and("us.unionid", "=", vi.getUnionId());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return condolenceService.count(sql);
|
||||
}
|
||||
|
||||
/**
|
||||
* 待校工会主席审核
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Integer getVcrCount() {
|
||||
return condolenceService.count(Cnd.where("state_id", "=", 2020));
|
||||
}
|
||||
|
||||
/**
|
||||
* 待工会常务副主席审核
|
||||
* 暂时没用
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private Integer getEcrCount() {
|
||||
return condolenceService.count(Cnd.where("state_id", "=", 2050));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.v.nutz.service.ViService;
|
||||
import io.v.nutz.zgfw.model.condolence.Condolence;
|
||||
import org.nutz.dao.entity.Record;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
@@ -19,6 +20,20 @@ public interface CondolenceService extends ViService<Condolence> {
|
||||
*/
|
||||
NutMap findOne(String id);
|
||||
|
||||
/**
|
||||
* 无参数;按当前会话工号及本自然年审核日期查询本人慰问已办。
|
||||
* @return 列表项包含 id、reviewId、moduleName、auditState、auditTime、mobileUrl;按审核日期倒序
|
||||
*/
|
||||
List<NutMap> getCurrentYearCompletes();
|
||||
|
||||
/**
|
||||
* 统计当前登录用户可见范围内、申请时间属于当前自然年的慰问待办数量。
|
||||
*
|
||||
* @param stateId 审核状态:2000 部门工会、2012 二级党组织、2020 校工会、2050 历史常务副主席待办
|
||||
* @return 待办数量(Integer);不支持的状态返回 0,权限菜单过滤仍由待办接口保留
|
||||
*/
|
||||
Integer countCurrentYearAgenda(int stateId);
|
||||
|
||||
/**
|
||||
* 判断被慰问人在当前自然年是否已有住院慰问申请。
|
||||
*
|
||||
|
||||
@@ -3,6 +3,8 @@ package io.v.nutz.zgfw.service.impl;
|
||||
|
||||
import cn.wizzer.framework.base.service.BaseService;
|
||||
import io.v.nutz.base.utils.DateUtil;
|
||||
import io.v.nutz.base.utils.Vi;
|
||||
import io.v.nutz.util.ShiroUtil;
|
||||
import io.v.nutz.modules.services.ReviewService;
|
||||
import io.v.nutz.service.impl.ViServiceImpl;
|
||||
import io.v.nutz.zgfw.model.condolence.Condolence;
|
||||
@@ -19,6 +21,8 @@ import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* @author 1V
|
||||
@@ -37,6 +41,78 @@ public class CondolenceServiceImpl extends ViServiceImpl<Condolence> implements
|
||||
this.condolenceDao = dao;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按审核状态统计本自然年申请,保留原待办对部门工会、二级党组织节点的工会范围限制。
|
||||
*
|
||||
* @param stateId 2000、2012、2020 或 2050;其他值不属于本接口的待办节点
|
||||
* @return 当前节点的待办条数,不包含往年或下一年度申请
|
||||
*/
|
||||
/**
|
||||
* 按审核记录的办理人工号及办理年份筛选,不将申请当前状态误作个人审核结果。
|
||||
* @return 本人今年的已办列表;未获得登录工号时返回空列表,禁止扩大到全员记录
|
||||
*/
|
||||
@Override
|
||||
public List<NutMap> getCurrentYearCompletes() {
|
||||
Object principalLoginname = ShiroUtil.getPrincipalProperty("loginname");
|
||||
String loginname = principalLoginname == null ? "" : principalLoginname.toString();
|
||||
if (Strings.isBlank(loginname)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
int year = DateUtil.getYear();
|
||||
// 只读取申请当前关联的审核记录;再次审核覆盖的旧关联无法在此恢复。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT con.id, r.id reviewId,
|
||||
CONCAT('【职工慰问】', COALESCE(con.be_user_username, '')) moduleName,
|
||||
nodes.nodeName auditState, r.time auditTime,
|
||||
CONCAT('/mobile/condolence/apply/info?id=', con.id) mobileUrl
|
||||
FROM condolence con
|
||||
JOIN (
|
||||
SELECT 1 nodeId, '部门工会审核' nodeName
|
||||
UNION ALL SELECT 2, '二级党组织审核'
|
||||
UNION ALL SELECT 3, '校工会审核'
|
||||
UNION ALL SELECT 4, '工会常务副主席审核'
|
||||
) nodes ON 1=1
|
||||
JOIN review r ON r.id = CASE nodes.nodeId
|
||||
WHEN 1 THEN con.union_chairman_review
|
||||
WHEN 2 THEN con.finance_review
|
||||
WHEN 3 THEN con.vice_chairman_review
|
||||
WHEN 4 THEN con.executive_chairman_review END
|
||||
WHERE r.loginname = @loginname AND r.time >= @startTime AND r.time < @endTime
|
||||
ORDER BY r.time DESC, con.id, nodes.nodeId
|
||||
""");
|
||||
sql.setParam("loginname", loginname);
|
||||
sql.setParam("startTime", year + "-01-01");
|
||||
sql.setParam("endTime", (year + 1) + "-01-01");
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer countCurrentYearAgenda(int stateId) {
|
||||
if (stateId != 2000 && stateId != 2012 && stateId != 2020 && stateId != 2050) {
|
||||
return 0;
|
||||
}
|
||||
// 年份只读取一次;左闭右开范围包含年初当天及年末全部时间,跨年后自动切换。
|
||||
int year = DateUtil.getYear();
|
||||
if (stateId == 2000 || stateId == 2012) {
|
||||
Cnd cnd = Cnd.where("con.state_id", "=", stateId)
|
||||
.and("con.apply_time", ">=", year + "-01-01")
|
||||
.and("con.apply_time", "<", (year + 1) + "-01-01");
|
||||
// 沿用原待办的角色判断:系统管理员和校工会管理员不限制所属工会。
|
||||
if (!ShiroUtil.hasAnyRoles("sysadmin,A06")) {
|
||||
cnd.and("us.unionid", "=", Vi.getUnionId());
|
||||
}
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT COUNT(1) FROM condolence con LEFT JOIN `user` us ON con.be_user=us.id $condition
|
||||
""");
|
||||
sql.setCondition(cnd);
|
||||
return count(sql);
|
||||
}
|
||||
// 校级节点保留原有全校统计范围,仅追加申请年份条件。
|
||||
return count(Cnd.where("state_id", "=", stateId)
|
||||
.and("apply_time", ">=", year + "-01-01")
|
||||
.and("apply_time", "<", (year + 1) + "-01-01"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHospitalCondolenceInCurrentYear(Condolence application) {
|
||||
CondolenceType type = condolenceDao.fetch(CondolenceType.class, application.getType());
|
||||
@@ -110,6 +186,14 @@ public class CondolenceServiceImpl extends ViServiceImpl<Condolence> implements
|
||||
if (Strings.isNotBlank(record.getString("union_chairman_review"))) {
|
||||
record.put("ucr", reviewService.fetch(record.getString("union_chairman_review")));
|
||||
}
|
||||
// 二级党组织审核沿用 finance_review 字段,详情以 fr 返回审核人、时间、意见和签字。
|
||||
if (Strings.isNotBlank(record.getString("finance_review"))) {
|
||||
record.put("fr", reviewService.fetch(record.getString("finance_review")));
|
||||
}
|
||||
// 历史常务副主席审核记录仅用于展示,不改变当前审批流转。
|
||||
if (Strings.isNotBlank(record.getString("executive_chairman_review"))) {
|
||||
record.put("ecr", reviewService.fetch(record.getString("executive_chairman_review")));
|
||||
}
|
||||
//校工会
|
||||
if (Strings.isNotBlank(record.getString("vice_chairman_review"))) {
|
||||
record.put("vcr", reviewService.fetch(record.getString("vice_chairman_review")));
|
||||
|
||||
@@ -235,6 +235,36 @@
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane v-if="hasPane(6)&&viewData.ecr" label="工会常务副主席审核信息" name="6">
|
||||
<el-form label-width="130px" label-suffix=":" style="padding: 20px 0">
|
||||
|
||||
<vi-title title="审核信息"></vi-title>
|
||||
|
||||
<el-row gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="审核人员">
|
||||
{{ viewData.ecr.username }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="审核时间">
|
||||
{{ viewData.ecr.time }}
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="审核意见">
|
||||
<div class="textarea-div">{{ viewData.ecr.opinion ? viewData.ecr.opinion : '暂无' }}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="签  字">
|
||||
<el-image v-if="viewData.ecr.sign"
|
||||
style="width: 300px; height: 100px"
|
||||
:src="viewData.ecr.sign"
|
||||
fit="contain"></el-image>
|
||||
<span v-else>暂无</span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane v-if="handle" :label="label" name="999">
|
||||
<slot name="handle"></slot>
|
||||
</el-tab-pane>
|
||||
@@ -257,7 +287,7 @@ module.exports = {
|
||||
},
|
||||
panes: {
|
||||
type: Array,
|
||||
default: []
|
||||
default: () => []
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
@@ -278,27 +308,32 @@ module.exports = {
|
||||
watch: {},
|
||||
methods: {
|
||||
hasPane(name) {
|
||||
if (!this.handle) {
|
||||
// 未指定页签范围时展示所有已有审核记录;显式传入范围时保持原有限制。
|
||||
if (!this.handle || this.panes.length === 0) {
|
||||
return true
|
||||
}
|
||||
return this.panes.includes(name)
|
||||
},
|
||||
async getInfo(id) {
|
||||
this.loading = true
|
||||
const {data, code, msg} = await $.get("/platform/fw/condolence/findOne", {id})
|
||||
this.loading = false
|
||||
if (data) {
|
||||
this.activeName = this.handle ? "999" : "1"
|
||||
condolence.toFormData(data)
|
||||
this.viewData = data
|
||||
|
||||
} else {
|
||||
this.viewData = {}
|
||||
this.$message({
|
||||
message: "获取信息失败",
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
/**
|
||||
* id 为慰问申请 ID;接口 data 为申请详情,ucr/fr/vcr/ecr 为各节点审核记录对象。
|
||||
* 无记录时对应页签隐藏;请求结束后统一解除加载状态。
|
||||
*/
|
||||
getInfo(id) {
|
||||
this.$set(this, 'loading', true)
|
||||
this.$set(this, 'viewData', {})
|
||||
return $.post('/platform/fw/condolence/findOne', {id})
|
||||
.then((res) => {
|
||||
if (res.code === 0 && res.data) {
|
||||
condolence.toFormData(res.data)
|
||||
this.$set(this, 'activeName', this.handle ? '999' : '1')
|
||||
this.$set(this, 'viewData', res.data)
|
||||
} else {
|
||||
this.$message.error('获取信息失败')
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
this.$set(this, 'loading', false)
|
||||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
@@ -223,9 +223,12 @@ layout("/mobile/platform.html"){
|
||||
roles: [],
|
||||
active: 1,
|
||||
needCount: 0,
|
||||
needRequestId: 0,
|
||||
needItems: [],
|
||||
activeName: '0',
|
||||
completedItems: [],
|
||||
completedLoading: false,
|
||||
completedRequestId: 0,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -244,7 +247,8 @@ layout("/mobile/platform.html"){
|
||||
location.href = o.mobileHref
|
||||
},
|
||||
toHref(o) {
|
||||
location.href = o.mobileUrl + '?audit=1';
|
||||
// 详情链接已携带申请 ID,保留查询参数。
|
||||
location.href = o.mobileUrl;
|
||||
},
|
||||
/**
|
||||
* 入学登记待办
|
||||
@@ -256,20 +260,111 @@ layout("/mobile/platform.html"){
|
||||
this.needItems = this.needItems.concat(data.filter(v => v.number > 0))
|
||||
}
|
||||
},*/
|
||||
async getNeedItems() {
|
||||
const {data, code} = await $.get('/platform/needItems/getNeedItems')
|
||||
if (code === 0) {
|
||||
const obj = data.filter(v => {
|
||||
return v.mobileHref != null && v.count > 0
|
||||
/**
|
||||
* requestId 为本轮刷新序号,忽略旧请求,避免返回页面或切换页签时覆盖新数据。
|
||||
* 通用接口 data 为待办数组,使用 count 和 mobileHref;完成后继续加载慰问待办。
|
||||
*/
|
||||
getNeedItems(requestId) {
|
||||
return $.post('/platform/needItems/getNeedItems')
|
||||
.then((res) => {
|
||||
if (requestId === this.needRequestId && res.code === 0) {
|
||||
this.$set(this, 'needItems', (res.data || []).filter(v => v.mobileHref && v.count > 0
|
||||
&& v.mobileHref.split('?')[0] !== '/mobile/member/audit'
|
||||
&& !['/platform/member/apply/audit/union', '/platform/member/apply/audit/school'].includes((v.href || '').split('?')[0])))
|
||||
}
|
||||
})
|
||||
.always(() => {
|
||||
if (requestId === this.needRequestId) {
|
||||
this.getCondolenceAgenda(requestId)
|
||||
}
|
||||
})
|
||||
this.needItems = obj
|
||||
}
|
||||
},
|
||||
async getCompletes() {
|
||||
const {data, code} = await $.get('/platform/sys/completed/getCompletes')
|
||||
if (code === 0) {
|
||||
this.completedItems = data;
|
||||
}
|
||||
/**
|
||||
* 复用 PC 慰问待办的菜单权限和统计口径,将 label/number 转为手机模板的 name/count。
|
||||
* 仅映射手机端已有审核页面的三个节点,历史常务副主席节点不提供手机办理入口。
|
||||
*/
|
||||
getCondolenceAgenda(requestId) {
|
||||
const auditUrls = [
|
||||
'/platform/fw/condolence/ucr/union',
|
||||
'/platform/fw/condolence/fr',
|
||||
'/platform/fw/condolence/vcr/school'
|
||||
]
|
||||
return $.post('/platform/condolence/agent/getAgenda')
|
||||
.then((res) => {
|
||||
if (requestId !== this.needRequestId || res.code !== 0) {
|
||||
return
|
||||
}
|
||||
const items = (res.data || []).filter(v => auditUrls.includes(v.url) && v.number > 0)
|
||||
.map(v => ({
|
||||
title: v.title,
|
||||
name: v.label,
|
||||
count: v.number,
|
||||
mobileHref: '/mobile/condolence/audit'
|
||||
}))
|
||||
this.$set(this, 'needItems', this.needItems.concat(items))
|
||||
})
|
||||
.always(() => {
|
||||
if (requestId === this.needRequestId) {
|
||||
this.getMemberApplyAgenda(requestId)
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 无需业务参数;后端按会话权限返回今年会员入会节点,字段与首页待办卡片一致。
|
||||
* 专用数据替代通用配置中的同业务卡片,避免双计数;失败不影响已加载的慰问待办。
|
||||
*/
|
||||
getMemberApplyAgenda(requestId) {
|
||||
return $.post('/platform/member/agenda/getMobileAgenda')
|
||||
.then((res) => {
|
||||
if (requestId !== this.needRequestId) return
|
||||
if (res.code === 0) {
|
||||
const items = (res.data || []).filter(v => v.count > 0 && v.mobileHref)
|
||||
this.$set(this, 'needItems', this.needItems.concat(items))
|
||||
} else {
|
||||
vant.Toast.fail('会员入会待办加载失败,请重试')
|
||||
}
|
||||
}, () => {
|
||||
if (requestId === this.needRequestId) vant.Toast.fail('会员入会待办加载失败,请重试')
|
||||
})
|
||||
.always(() => {
|
||||
if (requestId === this.needRequestId) this.$set(this, 'needCount', this.needItems.length)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 两个接口均无需传办理人,按当前会话返回本人今年已办。
|
||||
* 各业务独立合并;全部请求结束后关闭 loading,旧刷新结果不得覆盖当前列表。
|
||||
*/
|
||||
getCompletes() {
|
||||
const requestId = this.completedRequestId + 1
|
||||
this.$set(this, 'completedRequestId', requestId)
|
||||
this.$set(this, 'completedItems', [])
|
||||
this.$set(this, 'completedLoading', true)
|
||||
const sources = [
|
||||
{url: '/platform/condolence/agent/getCompletes', label: '慰问'},
|
||||
{url: '/platform/member/agenda/getCompletes', label: '会员入会'}
|
||||
]
|
||||
let remaining = sources.length
|
||||
const requests = sources.map(source => $.post(source.url)
|
||||
.then((res) => {
|
||||
if (requestId !== this.completedRequestId) return
|
||||
if (res.code === 0) {
|
||||
const items = this.completedItems.concat(res.data || [])
|
||||
// 现有日期字段统一交给 moment 解析,兼容日期字符串和时间戳。
|
||||
items.sort((a, b) => (moment(b.auditTime).valueOf() || 0) - (moment(a.auditTime).valueOf() || 0))
|
||||
this.$set(this, 'completedItems', items)
|
||||
} else {
|
||||
vant.Toast.fail(source.label + '已办加载失败,请重试')
|
||||
}
|
||||
}, () => {
|
||||
if (requestId === this.completedRequestId) vant.Toast.fail(source.label + '已办加载失败,请重试')
|
||||
})
|
||||
.always(() => {
|
||||
remaining--
|
||||
if (requestId === this.completedRequestId && remaining === 0) {
|
||||
this.$set(this, 'completedLoading', false)
|
||||
}
|
||||
}))
|
||||
return $.when.apply($, requests)
|
||||
},
|
||||
/**
|
||||
* 会员个人核对待办
|
||||
@@ -291,12 +386,13 @@ layout("/mobile/platform.html"){
|
||||
this.needItems = this.needItems.concat(data.filter(v => v.count > 0))
|
||||
}
|
||||
},
|
||||
async initData() {
|
||||
await this.getNeedItems();
|
||||
// await this.getMemberCheckSelfAgenda()
|
||||
// await this.getWelfareCheckSelfAgenda()
|
||||
// await this.getCompletes();
|
||||
this.needCount = this.needItems.length
|
||||
initData() {
|
||||
this.getCompletes()
|
||||
// 每轮重新合并通用、慰问和会员入会待办,防止重复追加;刷新序号隔离尚未完成的旧请求。
|
||||
this.$set(this, 'needRequestId', this.needRequestId + 1)
|
||||
this.$set(this, 'needItems', [])
|
||||
this.$set(this, 'needCount', 0)
|
||||
return this.getNeedItems(this.needRequestId)
|
||||
},
|
||||
async setNeedItems() {
|
||||
const {data, code} = await $.get('/platform/needItems/getNeedItems')
|
||||
|
||||
@@ -59,9 +59,10 @@ layout("/mobile/platform.html"){
|
||||
{text: '已审核', value: true},
|
||||
],
|
||||
handle: true,
|
||||
queryVersion: 0,
|
||||
pageForm: {
|
||||
year: new Date().getFullYear(),
|
||||
isAudit: false,
|
||||
year: GetQueryString("isAudit") === "true" ? null : new Date().getFullYear(),
|
||||
isAudit: GetQueryString("isAudit") === "true",
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -70,6 +71,7 @@ layout("/mobile/platform.html"){
|
||||
},
|
||||
methods: {
|
||||
yearChange() {
|
||||
this.queryVersion++
|
||||
this.pageForm.pageNumber = 1
|
||||
this.tableData = []
|
||||
this.finished = false
|
||||
@@ -77,40 +79,32 @@ layout("/mobile/platform.html"){
|
||||
},
|
||||
onLoad() {
|
||||
this.loading = true
|
||||
$.post(loc() + '/pageData', this.pageForm).then(res => {
|
||||
// 捕获本次筛选条件,筛选切换后忽略旧请求,避免串页。
|
||||
const requestKey = this.queryVersion || 0
|
||||
$.post('/mobile/member/audit/pageData', Object.assign({}, this.pageForm)).then(res => {
|
||||
if (requestKey !== (this.queryVersion || 0)) return
|
||||
if (res.code === 0) {
|
||||
this.tableData = this.tableData.concat(res.data.list)
|
||||
if (this.tableData.length === res.data.totalCount) {
|
||||
this.finished = true
|
||||
} else {
|
||||
this.pageForm.pageNumber++
|
||||
}
|
||||
this.finished = this.tableData.length >= res.data.totalCount || res.data.list.length === 0
|
||||
if (!this.finished) this.pageForm.pageNumber++
|
||||
} else {
|
||||
this.finished = true
|
||||
this.$toast.fail(res.msg || '加载失败')
|
||||
}
|
||||
this.loading = false
|
||||
}).fail(() => {
|
||||
if (requestKey !== (this.queryVersion || 0)) return
|
||||
this.finished = true
|
||||
this.$toast.fail('加载失败,请重新筛选后重试')
|
||||
}).always(() => {
|
||||
if (requestKey === (this.queryVersion || 0)) this.loading = false
|
||||
})
|
||||
},
|
||||
/* pageData() {
|
||||
this.mLoading = true
|
||||
setTimeout(async () => {
|
||||
$.get(loc() + '/pageData', this.pageForm, (res) => {
|
||||
|
||||
if (res.code === 0) {
|
||||
this.tableData = this.tableData.concat(res.data.list)
|
||||
if (this.tableData.length === res.data.totalCount) {
|
||||
this.finished = true
|
||||
} else {
|
||||
this.pageForm.pageNumber++
|
||||
}
|
||||
}
|
||||
})
|
||||
this.mLoading = false
|
||||
}, 600)
|
||||
},*/
|
||||
openView(o) {
|
||||
window.location.href = '/mobile/member/audit/findOne?stateId=' + o.stateId + '&record_id=' + o.id + '&user_id=' + o.userId
|
||||
window.location.href = '/mobile/member/audit/findOne?stateId=' + o.stateId + '&record_id=' + o.id + '&user_id=' + o.userId + '&done=' + this.pageForm.isAudit
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
created() {
|
||||
this.yearList = [{text: '全部年份', value: null}]
|
||||
let nowYear = new Date().getFullYear()
|
||||
for (let i = nowYear; i >= nowYear - 9; i--) {
|
||||
this.yearList.push({text: i, value: i})
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
<!--#
|
||||
layout("/mobile/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.member-query-header {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.member-query-list {
|
||||
padding: 10px 0 20px;
|
||||
}
|
||||
|
||||
.member-query-count {
|
||||
padding: 0 16px 10px;
|
||||
color: #969799;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.member-query-detail {
|
||||
height: 85%;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.member-query-detail .van-cell__value,
|
||||
.member-query-list .van-cell__value {
|
||||
overflow-wrap: anywhere;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.member-query-loading {
|
||||
padding: 40px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<div class="member-query-header">
|
||||
<van-nav-bar title="会员查询" left-arrow placeholder fixed
|
||||
@click-left="location.replace('/mobile/index')"></van-nav-bar>
|
||||
|
||||
<form action="/mobile/member/query" @submit.prevent="doSearch">
|
||||
<van-search v-model="keyword" placeholder="请输入姓名或工号" label="会员" show-action
|
||||
@search="doSearch" @clear="doSearch">
|
||||
<template #action>
|
||||
<van-button type="primary" size="small" native-type="button" @click="doSearch">搜索</van-button>
|
||||
</template>
|
||||
</van-search>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="member-query-list">
|
||||
<div v-if="tableData.length" class="member-query-count">共 {{pageForm.totalCount}} 位会员</div>
|
||||
<van-list v-model="loading" :finished="finished" :error.sync="loadError"
|
||||
error-text="加载失败,点击重试" :finished-text="tableData.length ? '没有更多了' : ''"
|
||||
:immediate-check="false" @load="onLoad">
|
||||
<div v-for="o in tableData" :key="o.id" class="list-card">
|
||||
<van-cell-group inset>
|
||||
<van-cell :border="false" title="姓 名">{{o.username || '—'}}</van-cell>
|
||||
<van-cell :border="false" title="工 号">{{o.loginname || '—'}}</van-cell>
|
||||
<van-cell :border="false" title="所在工会">{{o.unionname || '—'}}</van-cell>
|
||||
<van-cell :border="false" title="所在单位">{{o.unitname || '—'}}</van-cell>
|
||||
<van-cell :border="false" title="人员类型">{{o.personType || '—'}}</van-cell>
|
||||
</van-cell-group>
|
||||
<van-cell title="查看会员详情" is-link clickable @click="openView(o)"></van-cell>
|
||||
</div>
|
||||
</van-list>
|
||||
<van-empty v-if="!loading && !loadError && finished && tableData.length === 0"
|
||||
image="/none.svg" description="暂无符合条件的会员"></van-empty>
|
||||
</div>
|
||||
|
||||
<van-popup v-model="showDetail" position="bottom" round class="member-query-detail">
|
||||
<van-nav-bar title="会员详情" left-arrow @click-left="showDetail = false"></van-nav-bar>
|
||||
<div v-if="detailLoading" class="member-query-loading">
|
||||
<van-loading size="24px" vertical>加载中...</van-loading>
|
||||
</div>
|
||||
<van-empty v-else-if="detailError" description="详情加载失败">
|
||||
<van-button type="primary" size="small" @click="openView(selectedMember)">重试</van-button>
|
||||
</van-empty>
|
||||
<van-cell-group v-else-if="memberInfo">
|
||||
<van-cell title="姓名" :value="memberInfo.username || '—'"></van-cell>
|
||||
<van-cell title="性别" :value="memberInfo.sex || '—'"></van-cell>
|
||||
<van-cell title="年龄" :value="memberInfo.age == null ? '—' : memberInfo.age"></van-cell>
|
||||
<van-cell title="民族" :value="memberInfo.nation || '—'"></van-cell>
|
||||
<van-cell title="学历" :value="memberInfo.education || '—'"></van-cell>
|
||||
<van-cell title="政治面貌" :value="memberInfo.political || '—'"></van-cell>
|
||||
<van-cell title="职称" :value="memberInfo.jobTitle || '—'"></van-cell>
|
||||
<van-cell title="职务" :value="memberInfo.position || '—'"></van-cell>
|
||||
<van-cell title="所在单位" :value="memberInfo.unitname || '—'"></van-cell>
|
||||
<van-cell title="个人简历" :value="memberInfo.vita || '—'"></van-cell>
|
||||
</van-cell-group>
|
||||
<van-empty v-else description="暂无会员详情"></van-empty>
|
||||
</van-popup>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 复用移动端会员接口,在查询页内查看详情,保持与查询入口一致的角色权限。
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [mobileMixins],
|
||||
data() {
|
||||
return {
|
||||
keyword: '',
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: ''
|
||||
},
|
||||
loadError: false,
|
||||
requestId: 0,
|
||||
pending: false,
|
||||
showDetail: false,
|
||||
detailLoading: false,
|
||||
detailError: false,
|
||||
detailRequestId: 0,
|
||||
selectedMember: null,
|
||||
memberInfo: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
// 新搜索使上一轮分页请求失效,避免较慢的旧响应混入新结果。
|
||||
this.requestId++
|
||||
this.pending = false
|
||||
this.pageForm.pageNumber = 1
|
||||
this.pageForm.totalCount = 0
|
||||
this.pageForm.searchKeyword = this.keyword.trim()
|
||||
this.tableData = []
|
||||
this.finished = false
|
||||
this.loadError = false
|
||||
this.onLoad()
|
||||
},
|
||||
async onLoad() {
|
||||
if (this.pending || this.finished) return
|
||||
const requestId = this.requestId
|
||||
this.pending = true
|
||||
this.loading = true
|
||||
this.loadError = false
|
||||
try {
|
||||
const res = await $.post('/mobile/member/getMemberData', Object.assign({}, this.pageForm))
|
||||
if (requestId !== this.requestId) return
|
||||
if (res.code !== 0 || !res.data || !Array.isArray(res.data.list)) {
|
||||
throw new Error('会员查询失败')
|
||||
}
|
||||
this.tableData = this.tableData.concat(res.data.list)
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
this.finished = res.data.list.length === 0 || this.tableData.length >= res.data.totalCount
|
||||
if (!this.finished) this.pageForm.pageNumber++
|
||||
} catch (e) {
|
||||
if (requestId === this.requestId) this.loadError = true
|
||||
} finally {
|
||||
if (requestId === this.requestId) {
|
||||
this.pending = false
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
},
|
||||
async openView(member) {
|
||||
if (!member || !member.id) {
|
||||
this.$toast.fail('缺少会员信息')
|
||||
return
|
||||
}
|
||||
const requestId = ++this.detailRequestId
|
||||
this.selectedMember = member
|
||||
this.memberInfo = null
|
||||
this.showDetail = true
|
||||
this.detailLoading = true
|
||||
this.detailError = false
|
||||
try {
|
||||
const res = await $.get('/mobile/member/viewInfo', {id: member.id})
|
||||
if (requestId !== this.detailRequestId) return
|
||||
if (res.code !== 0) throw new Error('会员详情加载失败')
|
||||
this.memberInfo = res.data
|
||||
} catch (e) {
|
||||
if (requestId === this.detailRequestId) this.detailError = true
|
||||
} finally {
|
||||
if (requestId === this.detailRequestId) this.detailLoading = false
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -26,7 +26,6 @@ layout("/mobile/platform.html"){
|
||||
<van-field v-model="formData.auditTime" label="审核时间" readonly></van-field>
|
||||
|
||||
<van-field
|
||||
required
|
||||
v-model="formData.auditOpinion"
|
||||
rows="1"
|
||||
autosize
|
||||
@@ -46,12 +45,12 @@ layout("/mobile/platform.html"){
|
||||
|
||||
<van-row gutter="20" style="margin-top: 30px;padding: 0 25px">
|
||||
<van-col span="12">
|
||||
<van-button :color="themeColor" plain block @click="doAudit(false)">拒 绝
|
||||
<van-button :color="themeColor" plain block :loading="formLoading" :disabled="formLoading" @click="doAudit(false)">拒 绝
|
||||
</van-button>
|
||||
</van-col>
|
||||
|
||||
<van-col span="12">
|
||||
<van-button :color="themeColor" block @click="doAudit(true)">通 过
|
||||
<van-button :color="themeColor" block :loading="formLoading" :disabled="formLoading" @click="doAudit(true)">通 过
|
||||
</van-button>
|
||||
</van-col>
|
||||
</van-row>
|
||||
@@ -72,6 +71,7 @@ layout("/mobile/platform.html"){
|
||||
data() {
|
||||
return {
|
||||
handle: true,
|
||||
formLoading: false,
|
||||
id: "",
|
||||
formData: {},
|
||||
}
|
||||
@@ -81,25 +81,27 @@ layout("/mobile/platform.html"){
|
||||
'mobile-sign': httpVueLoader('/components/sign/mobileSign.vue'),
|
||||
},
|
||||
methods: {
|
||||
async doAudit(pass) {
|
||||
if (!this.formData.auditOpinion) {
|
||||
this.$toast.fail('请填写审核意见');
|
||||
return
|
||||
}
|
||||
this.formData.auditPass = pass
|
||||
const resp = await $.post("/platform/member/apply/audit/doAudit", this.formData)
|
||||
requestLaterFun(resp, (data) => {
|
||||
this.$toast.success('审核成功');
|
||||
setTimeout(() => {
|
||||
location.href = '/mobile/member/audit'
|
||||
}, 1000)
|
||||
}, () => {
|
||||
this.$toast.fail('审核失败');
|
||||
}, () => {
|
||||
doAudit(pass) {
|
||||
if (this.formLoading) return
|
||||
// 与 PC 共用审核参数;提交前读取手写签名,避免仅提交历史签名。
|
||||
this.$refs.signature.submitSign()
|
||||
this.$set(this.formData, 'auditPass', pass)
|
||||
this.formLoading = true
|
||||
$.post('/platform/member/apply/audit/doAudit', this.formData).then(resp => {
|
||||
requestLaterFun(resp, () => {
|
||||
this.$toast.success('审核成功')
|
||||
location.replace('/mobile/member/audit')
|
||||
}, () => {
|
||||
this.$toast.fail('审核失败')
|
||||
}, () => {})
|
||||
}).fail(() => {
|
||||
this.$toast.fail('审核失败,请稍后重试')
|
||||
}).always(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
created() {
|
||||
const record_id = GetQueryString("record_id")
|
||||
const user_id = GetQueryString("user_id")
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -26,7 +26,7 @@ layout("/mobile/platform.html"){
|
||||
|
||||
<van-field v-model="formData.auditTime" label="审核时间" readonly></van-field>
|
||||
|
||||
<van-field required
|
||||
<van-field
|
||||
v-model="formData.auditOpinion"
|
||||
rows="1"
|
||||
autosize
|
||||
@@ -45,12 +45,12 @@ layout("/mobile/platform.html"){
|
||||
|
||||
<van-row gutter="20" style="margin-top: 30px;padding: 0 25px">
|
||||
<van-col span="12">
|
||||
<van-button :color="themeColor" plain block @click="doAudit(false)">拒 绝
|
||||
<van-button :color="themeColor" plain block :loading="formLoading" :disabled="formLoading" @click="doAudit(false)">拒 绝
|
||||
</van-button>
|
||||
</van-col>
|
||||
|
||||
<van-col span="12">
|
||||
<van-button :color="themeColor" block @click="doAudit(true)">通 过
|
||||
<van-button :color="themeColor" block :loading="formLoading" :disabled="formLoading" @click="doAudit(true)">通 过
|
||||
</van-button>
|
||||
</van-col>
|
||||
</van-row>
|
||||
@@ -70,6 +70,7 @@ layout("/mobile/platform.html"){
|
||||
data() {
|
||||
return {
|
||||
handle: true,
|
||||
formLoading: false,
|
||||
id: "",
|
||||
formData: {},
|
||||
}
|
||||
@@ -80,25 +81,27 @@ layout("/mobile/platform.html"){
|
||||
},
|
||||
methods: {
|
||||
|
||||
async doAudit(pass) {
|
||||
if (!this.formData.auditOpinion) {
|
||||
this.$toast.fail('请填写审核意见');
|
||||
return
|
||||
}
|
||||
this.formData.auditPass = pass
|
||||
const resp = await $.post("/platform/member/apply/audit/doAudit", this.formData)
|
||||
requestLaterFun(resp, (data) => {
|
||||
this.$toast.success('审核成功');
|
||||
setTimeout(() => {
|
||||
location.href = '/mobile/member/audit'
|
||||
}, 1000)
|
||||
}, () => {
|
||||
this.$toast.fail('审核失败');
|
||||
}, () => {
|
||||
doAudit(pass) {
|
||||
if (this.formLoading) return
|
||||
// 与 PC 共用审核参数;提交前读取手写签名,避免仅提交历史签名。
|
||||
this.$refs.signature.submitSign()
|
||||
this.$set(this.formData, 'auditPass', pass)
|
||||
this.formLoading = true
|
||||
$.post('/platform/member/apply/audit/doAudit', this.formData).then(resp => {
|
||||
requestLaterFun(resp, () => {
|
||||
this.$toast.success('审核成功')
|
||||
location.replace('/mobile/member/audit')
|
||||
}, () => {
|
||||
this.$toast.fail('审核失败')
|
||||
}, () => {})
|
||||
}).fail(() => {
|
||||
this.$toast.fail('审核失败,请稍后重试')
|
||||
}).always(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
created() {
|
||||
const record_id = GetQueryString("record_id")
|
||||
const user_id = GetQueryString("user_id")
|
||||
setTimeout(() => {
|
||||
|
||||
@@ -288,7 +288,8 @@
|
||||
pageForm: {
|
||||
source: source,
|
||||
searchName: "u.username",
|
||||
audit: 2
|
||||
// 已办入口默认显示本阶段已审核记录。
|
||||
audit: new URLSearchParams(window.location.search).get("audit") === "1" ? 1 : 2
|
||||
},
|
||||
unions: [],
|
||||
tableColumns: [
|
||||
|
||||
Reference in New Issue
Block a user