commit
This commit is contained in:
@@ -41,15 +41,11 @@ import javax.servlet.http.HttpServletResponse;
|
|||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.spec.InvalidKeySpecException;
|
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
|
||||||
import java.util.Base64;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
|
||||||
@IocBean
|
@IocBean
|
||||||
@@ -58,6 +54,11 @@ import java.util.UUID;
|
|||||||
@Api(tags = "登录")
|
@Api(tags = "登录")
|
||||||
public class SysLoginController {
|
public class SysLoginController {
|
||||||
private static final Log log = Logs.get();
|
private static final Log log = Logs.get();
|
||||||
|
private static final LoginRsaKeyRing LOGIN_RSA_KEY_RING = new LoginRsaKeyRing();
|
||||||
|
/**
|
||||||
|
* TODO: 临时屏蔽 localhost 平台登录验证码,恢复时改为 false。
|
||||||
|
*/
|
||||||
|
private static final boolean DISABLE_LOGIN_CAPTCHA = true;
|
||||||
@Inject
|
@Inject
|
||||||
private SysUserService sysUserService;
|
private SysUserService sysUserService;
|
||||||
@Inject
|
@Inject
|
||||||
@@ -123,14 +124,20 @@ public class SysLoginController {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 验证码校验
|
// 验证码校验
|
||||||
try {
|
if (!isLoginCaptchaDisabled(req)) {
|
||||||
validateService.checkCode(captchaKey, captchaCode);
|
try {
|
||||||
} catch (BaseException e) {
|
validateService.checkCode(captchaKey, captchaCode);
|
||||||
return Result.error(e.getMessage());
|
} catch (BaseException e) {
|
||||||
|
return Result.error(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解密密码
|
// 解密密码
|
||||||
String decryptPwd = validateService.decryptPwd(keyId, password);
|
LoginRsaKey rsaKey = LOGIN_RSA_KEY_RING.getPrivateKey(keyId);
|
||||||
|
if (rsaKey == null) {
|
||||||
|
throw new BaseException("Login key expired, please refresh the login page");
|
||||||
|
}
|
||||||
|
String decryptPwd = RsaUtils.decrypt(password, rsaKey.privateKey);
|
||||||
if (decryptPwd == null) {
|
if (decryptPwd == null) {
|
||||||
throw new BaseException("用户登录失败");
|
throw new BaseException("用户登录失败");
|
||||||
}
|
}
|
||||||
@@ -153,6 +160,17 @@ public class SysLoginController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isLoginCaptchaDisabled(HttpServletRequest req) {
|
||||||
|
if (!DISABLE_LOGIN_CAPTCHA || req == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String serverName = req.getServerName();
|
||||||
|
return "localhost".equalsIgnoreCase(serverName)
|
||||||
|
|| "127.0.0.1".equals(serverName)
|
||||||
|
|| "0:0:0:0:0:0:0:1".equals(serverName)
|
||||||
|
|| "::1".equals(serverName);
|
||||||
|
}
|
||||||
|
|
||||||
@At(value = "/platform/sso/login", top = true)
|
@At(value = "/platform/sso/login", top = true)
|
||||||
@Ok("re")
|
@Ok("re")
|
||||||
@ApiOperation("用户cas登录统一入口")
|
@ApiOperation("用户cas登录统一入口")
|
||||||
@@ -267,25 +285,89 @@ public class SysLoginController {
|
|||||||
@ApiOperation("获取公钥")
|
@ApiOperation("获取公钥")
|
||||||
public Object publicKey() {
|
public Object publicKey() {
|
||||||
try {
|
try {
|
||||||
// 生成密钥对
|
LoginRsaKey rsaKey = LOGIN_RSA_KEY_RING.currentKey();
|
||||||
KeyPair keyPair = RsaUtils.generateKeyPair();
|
|
||||||
String publicKeyStr = RsaUtils.getPublicKeyBase64(keyPair.getPublic());
|
|
||||||
String privateKeyStr = RsaUtils.getPrivateKeyBase64(keyPair.getPrivate());
|
|
||||||
|
|
||||||
// 生成 UUID 作为 keyId
|
|
||||||
String keyId = UUID.randomUUID().toString().replace("-", "");
|
|
||||||
|
|
||||||
// 私钥存入 Redis,5 分钟过期,也防止恶意刷密钥
|
|
||||||
redisService.setex(RedisConstant.RSA_KEY_PREFIX + keyId, 5 * 60, privateKeyStr);
|
|
||||||
|
|
||||||
// 返回给前端
|
|
||||||
return Result.success(Map.of(
|
return Result.success(Map.of(
|
||||||
"publicKey", publicKeyStr,
|
"publicKey", rsaKey.publicKey,
|
||||||
"keyId", keyId
|
"keyId", rsaKey.keyId,
|
||||||
|
"expireAt", rsaKey.encryptExpireAt
|
||||||
));
|
));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("生成 RSA 密钥失败", e);
|
log.error("生成 RSA 密钥失败", e);
|
||||||
return Result.error("系统异常");
|
return Result.error("系统异常");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class LoginRsaKeyRing {
|
||||||
|
private static final long ACTIVE_MILLIS = 30 * 60 * 1000L;
|
||||||
|
private static final long DECRYPT_GRACE_MILLIS = 10 * 60 * 1000L;
|
||||||
|
private final ConcurrentHashMap<String, LoginRsaKey> keys = new ConcurrentHashMap<>();
|
||||||
|
private volatile LoginRsaKey current;
|
||||||
|
|
||||||
|
LoginRsaKey currentKey() throws Exception {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
LoginRsaKey key = current;
|
||||||
|
if (key != null && now < key.encryptExpireAt) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
synchronized (this) {
|
||||||
|
key = current;
|
||||||
|
now = System.currentTimeMillis();
|
||||||
|
if (key == null || now >= key.encryptExpireAt) {
|
||||||
|
key = generateKey(now);
|
||||||
|
current = key;
|
||||||
|
keys.put(key.keyId, key);
|
||||||
|
cleanup(now);
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LoginRsaKey getPrivateKey(String keyId) {
|
||||||
|
if (StrUtil.isBlank(keyId)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
LoginRsaKey key = keys.get(keyId);
|
||||||
|
if (key == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (now >= key.decryptExpireAt) {
|
||||||
|
keys.remove(keyId);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
private LoginRsaKey generateKey(long now) throws Exception {
|
||||||
|
KeyPair keyPair = RsaUtils.generateKeyPair();
|
||||||
|
String keyId = UUID.randomUUID().toString().replace("-", "");
|
||||||
|
return new LoginRsaKey(
|
||||||
|
keyId,
|
||||||
|
RsaUtils.getPublicKeyBase64(keyPair.getPublic()),
|
||||||
|
keyPair.getPrivate(),
|
||||||
|
now + ACTIVE_MILLIS,
|
||||||
|
now + ACTIVE_MILLIS + DECRYPT_GRACE_MILLIS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanup(long now) {
|
||||||
|
keys.entrySet().removeIf(entry -> now >= entry.getValue().decryptExpireAt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class LoginRsaKey {
|
||||||
|
private final String keyId;
|
||||||
|
private final String publicKey;
|
||||||
|
private final PrivateKey privateKey;
|
||||||
|
private final long encryptExpireAt;
|
||||||
|
private final long decryptExpireAt;
|
||||||
|
|
||||||
|
private LoginRsaKey(String keyId, String publicKey, PrivateKey privateKey, long encryptExpireAt, long decryptExpireAt) {
|
||||||
|
this.keyId = keyId;
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this.privateKey = privateKey;
|
||||||
|
this.encryptExpireAt = encryptExpireAt;
|
||||||
|
this.decryptExpireAt = decryptExpireAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -64,7 +64,7 @@ public class ActivityCultureServiceImpl extends BaseServiceImpl<ActivityTissue>
|
|||||||
SELECT
|
SELECT
|
||||||
gh.id,
|
gh.id,
|
||||||
gh.name unionname,
|
gh.name unionname,
|
||||||
( SELECT count( 1 ) FROM `user` WHERE id IN ( $scopeUserSql ) AND unionId = gh.id ) as teacherCount
|
( SELECT count( 1 ) FROM `vw_user` WHERE id IN ( $scopeUserSql ) AND unionId = gh.id ) as teacherCount
|
||||||
|
|
||||||
FROM
|
FROM
|
||||||
sys_union gh
|
sys_union gh
|
||||||
|
|||||||
+12
@@ -3,6 +3,7 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact;
|
|||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
@@ -21,7 +22,9 @@ import org.nutz.ioc.loader.annotation.Inject;
|
|||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -116,6 +119,15 @@ public class ProposalCaseCheckController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.caseCheck")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("caseCheck", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("proposal.caseCheck")
|
@SaCheckPermission("proposal.caseCheck")
|
||||||
@ApiOperation("查询当前提案承办单位")
|
@ApiOperation("查询当前提案承办单位")
|
||||||
|
|||||||
+11
@@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
|||||||
import cn.hutool.core.lang.Dict;
|
import cn.hutool.core.lang.Dict;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||||
@@ -28,6 +29,7 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@IocBean
|
@IocBean
|
||||||
@@ -114,6 +116,15 @@ public class ProposalCommitteeFilingController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.committeeFiling")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("committeeFiling", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("proposal.committeeFiling")
|
@SaCheckPermission("proposal.committeeFiling")
|
||||||
@ApiOperation("并案审核")
|
@ApiOperation("并案审核")
|
||||||
|
|||||||
+11
@@ -6,6 +6,7 @@ import cn.hutool.core.lang.Dict;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.flow.entity.ProcessInstance;
|
import com.budwk.app.flow.entity.ProcessInstance;
|
||||||
@@ -36,6 +37,7 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@IocBean
|
@IocBean
|
||||||
@@ -127,6 +129,15 @@ public class ProposalCommitteeFilingUnitController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.committeeFilingUnit")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("committeeFilingUnit", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("proposal.committeeFilingUnit")
|
@SaCheckPermission("proposal.committeeFilingUnit")
|
||||||
@ApiOperation("执行任务")
|
@ApiOperation("执行任务")
|
||||||
|
|||||||
+11
@@ -4,6 +4,7 @@ import cn.dev33.satoken.annotation.SaCheckPermission;
|
|||||||
import com.budwk.app.base.annotation.SLog;
|
import com.budwk.app.base.annotation.SLog;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
import com.budwk.app.bpm.enums.BpmProcessTaskStatusEnum;
|
||||||
@@ -32,6 +33,7 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -127,4 +129,13 @@ public class ProposalDelegationController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.delegation")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("delegation", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -5,6 +5,7 @@ import cn.hutool.json.JSONObject;
|
|||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.flow.entity.ProcessTask;
|
import com.budwk.app.flow.entity.ProcessTask;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
@@ -26,6 +27,7 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@IocBean
|
@IocBean
|
||||||
@@ -116,6 +118,15 @@ public class ProposalFeedbackEvaluationController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.feedbackEvaluation")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("feedbackEvaluation", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("proposal.feedbackEvaluation")
|
@SaCheckPermission("proposal.feedbackEvaluation")
|
||||||
@ApiOperation("获取立案信息")
|
@ApiOperation("获取立案信息")
|
||||||
|
|||||||
+12
@@ -3,6 +3,7 @@ package com.budwk.app.zhgh.democratic.proposal.controller.transact;
|
|||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
@@ -20,7 +21,9 @@ import org.nutz.ioc.loader.annotation.Inject;
|
|||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -113,4 +116,13 @@ public class ProposalPreAuditController {
|
|||||||
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql);
|
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(),pageForm.getPageSize(), sql);
|
||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.preAudit")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("preAudit", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -7,6 +7,7 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.base.vo.LabelValueVO;
|
import com.budwk.app.base.vo.LabelValueVO;
|
||||||
import com.budwk.app.flow.constant.FlowConst;
|
import com.budwk.app.flow.constant.FlowConst;
|
||||||
@@ -38,6 +39,7 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -144,6 +146,15 @@ public class ProposalSchoolLeaderApprovalController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.schoolLeaderApproval")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("schoolLeaderApproval", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("proposal.schoolLeaderApproval")
|
@SaCheckPermission("proposal.schoolLeaderApproval")
|
||||||
@ApiOperation("获取主办单位")
|
@ApiOperation("获取主办单位")
|
||||||
|
|||||||
+11
@@ -5,6 +5,7 @@ import cn.hutool.core.lang.Dict;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.page.Pagination;
|
import com.budwk.app.base.page.Pagination;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.result.Result;
|
import com.budwk.app.base.result.Result;
|
||||||
import com.budwk.app.flow.entity.ProcessTask;
|
import com.budwk.app.flow.entity.ProcessTask;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
@@ -37,6 +38,7 @@ import org.nutz.mvc.annotation.Ok;
|
|||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.constraints.NotBlank;
|
import javax.validation.constraints.NotBlank;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -170,6 +172,15 @@ public class ProposalUnderTakeReplyController {
|
|||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@SaCheckPermission("proposal.unitReply")
|
||||||
|
@ApiOperation("导出列表")
|
||||||
|
public void exportList(@Valid @Param("pageForm") ProposalSearchParam pageForm, boolean approval,
|
||||||
|
@Param("tableColumns") ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
proposalCommonService.exportWorkflowList("unitReply", pageForm, approval, tableColumns, response);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 承办单位答复节点撤回需要基于整组当前节点判断。
|
* 承办单位答复节点撤回需要基于整组当前节点判断。
|
||||||
* 只有“当前流程正在办理的节点”和“这条列表记录所属节点”完全一致时,才允许撤回;
|
* 只有“当前流程正在办理的节点”和“这条列表记录所属节点”完全一致时,才允许撤回;
|
||||||
|
|||||||
+14
@@ -2,8 +2,10 @@ package com.budwk.app.zhgh.democratic.proposal.service.common;
|
|||||||
|
|
||||||
import com.budwk.app.base.service.BaseService;
|
import com.budwk.app.base.service.BaseService;
|
||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
|
import com.budwk.app.zhgh.democratic.proposal.models.ProposalInfo;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
|
import com.budwk.app.zhgh.democratic.proposal.models.ProposalUndertake;
|
||||||
|
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
@@ -137,6 +139,18 @@ public interface ProposalCommonService extends BaseService<ProposalInfo> {
|
|||||||
*/
|
*/
|
||||||
void exportYearReport(String sessionId, HttpServletResponse response);
|
void exportYearReport(String sessionId, HttpServletResponse response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按办理页面当前筛选条件和可见列导出提案列表。
|
||||||
|
*
|
||||||
|
* @param pageCode 页面代码,用于固定查询范围、数据权限和排序白名单
|
||||||
|
* @param pageForm 页面筛选条件
|
||||||
|
* @param approval 审核状态筛选条件
|
||||||
|
* @param tableColumns 当前页面可见列
|
||||||
|
* @param response HTTP 响应
|
||||||
|
*/
|
||||||
|
void exportWorkflowList(String pageCode, ProposalSearchParam pageForm, boolean approval,
|
||||||
|
ExportTableColumns[] tableColumns, HttpServletResponse response);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 合并提案
|
* 合并提案
|
||||||
|
|||||||
+290
-5
@@ -7,8 +7,13 @@ import cn.hutool.core.util.NumberUtil;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.json.JSONObject;
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.exception.BaseException;
|
import com.budwk.app.base.exception.BaseException;
|
||||||
|
import com.budwk.app.base.param.ExportTableColumns;
|
||||||
import com.budwk.app.base.param.PageForm;
|
import com.budwk.app.base.param.PageForm;
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||||
@@ -19,6 +24,7 @@ import com.budwk.app.flow.engine.FlowEngine;
|
|||||||
import com.budwk.app.flow.engine.util.FlowUtil;
|
import com.budwk.app.flow.engine.util.FlowUtil;
|
||||||
import com.budwk.app.flow.entity.ProcessInstance;
|
import com.budwk.app.flow.entity.ProcessInstance;
|
||||||
import com.budwk.app.flow.entity.ProcessTask;
|
import com.budwk.app.flow.entity.ProcessTask;
|
||||||
|
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||||
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
|
||||||
import com.budwk.app.flow.vo.ProcessTaskVO;
|
import com.budwk.app.flow.vo.ProcessTaskVO;
|
||||||
import com.budwk.app.sys.models.Sys_dict;
|
import com.budwk.app.sys.models.Sys_dict;
|
||||||
@@ -28,11 +34,13 @@ import com.budwk.app.sys.models.Sys_user_role;
|
|||||||
import com.budwk.app.sys.services.SysDictService;
|
import com.budwk.app.sys.services.SysDictService;
|
||||||
import com.budwk.app.sys.services.SysRoleService;
|
import com.budwk.app.sys.services.SysRoleService;
|
||||||
import com.budwk.app.sys.services.SysUserService;
|
import com.budwk.app.sys.services.SysUserService;
|
||||||
|
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||||
import com.budwk.app.web.commons.base.Globals;
|
import com.budwk.app.web.commons.base.Globals;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.constants.ProposalState;
|
import com.budwk.app.zhgh.democratic.proposal.constants.ProposalState;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.models.*;
|
import com.budwk.app.zhgh.democratic.proposal.models.*;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
|
import com.budwk.app.zhgh.democratic.proposal.param.ProposalQueryComprehensiveParam;
|
||||||
|
import com.budwk.app.zhgh.democratic.proposal.param.ProposalSearchParam;
|
||||||
import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService;
|
import com.budwk.app.zhgh.democratic.proposal.service.ProposalWriteService;
|
||||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
|
import com.budwk.app.zhgh.democratic.teachercongress.delegate.models.Teacher_congress_delegate;
|
||||||
import com.budwk.app.zhgh.democratic.teachercongress.delegate.service.TeacherCongressDelegateService;
|
import com.budwk.app.zhgh.democratic.teachercongress.delegate.service.TeacherCongressDelegateService;
|
||||||
@@ -55,6 +63,7 @@ import org.nutz.json.Json;
|
|||||||
import org.nutz.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
@@ -73,6 +82,9 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
|||||||
/** PC端提案列表页面的排序字段白名单,页面代码由对应Controller固定传入。 */
|
/** PC端提案列表页面的排序字段白名单,页面代码由对应Controller固定传入。 */
|
||||||
private static final Map<String, Map<String, String>> PROPOSAL_LIST_ORDER_COLUMNS = createProposalListOrderColumns();
|
private static final Map<String, Map<String, String>> PROPOSAL_LIST_ORDER_COLUMNS = createProposalListOrderColumns();
|
||||||
|
|
||||||
|
/** 办理页面允许导出的列表字段,避免请求参数携带非页面字段。 */
|
||||||
|
private static final Map<String, Set<String>> WORKFLOW_EXPORT_COLUMNS = createWorkflowExportColumns();
|
||||||
|
|
||||||
//找出富文本里面上传的图片
|
//找出富文本里面上传的图片
|
||||||
static String IMG_SRC_REGEX = "<img\\s+[^>]*src\\s*=\\s*([\"'])(/platform/sys/file/download\\?id=.*?)\\1[^>]*>";
|
static String IMG_SRC_REGEX = "<img\\s+[^>]*src\\s*=\\s*([\"'])(/platform/sys/file/download\\?id=.*?)\\1[^>]*>";
|
||||||
|
|
||||||
@@ -204,6 +216,219 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
|||||||
return Collections.unmodifiableMap(columns);
|
return Collections.unmodifiableMap(columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按办理页面当前筛选条件和可见列导出列表,查询范围与页面分页列表保持一致。
|
||||||
|
*
|
||||||
|
* @param pageCode 页面代码
|
||||||
|
* @param pageForm 页面筛选条件
|
||||||
|
* @param approval 审核状态
|
||||||
|
* @param tableColumns 页面可见列
|
||||||
|
* @param response HTTP 响应
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void exportWorkflowList(String pageCode, ProposalSearchParam pageForm, boolean approval,
|
||||||
|
ExportTableColumns[] tableColumns, HttpServletResponse response) {
|
||||||
|
List<ExportTableColumns> exportColumns = getWorkflowExportColumns(pageCode, tableColumns);
|
||||||
|
if (exportColumns.isEmpty()) {
|
||||||
|
throw Lang.makeThrow("请选择至少一个列表字段后再导出");
|
||||||
|
}
|
||||||
|
|
||||||
|
Sql sql = buildWorkflowExportSql(pageCode, pageForm, approval);
|
||||||
|
List<NutMap> rows = listMap(sql);
|
||||||
|
convertWorkflowExportValues(rows, pageCode);
|
||||||
|
|
||||||
|
List<ExcelExportEntity> excelColumns = new ArrayList<>();
|
||||||
|
for (ExportTableColumns column : exportColumns) {
|
||||||
|
excelColumns.add(new ExcelExportEntity(column.getLabel(), column.getProp(), 20));
|
||||||
|
}
|
||||||
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
exportParams.setTitle("提案列表");
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelColumns, rows);
|
||||||
|
CommonDownloadUtil.download("提案列表.xlsx", workbook, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据页面代码构造导出查询,保证数据权限、筛选条件及排序规则与列表页一致。 */
|
||||||
|
private Sql buildWorkflowExportSql(String pageCode, ProposalSearchParam pageForm, boolean approval) {
|
||||||
|
boolean isUnitReply = "unitReply".equals(pageCode);
|
||||||
|
boolean isSchoolLeaderApproval = "schoolLeaderApproval".equals(pageCode);
|
||||||
|
boolean requiresUnionFilter = Set.of("preAudit", "committeeFiling", "committeeFilingUnit",
|
||||||
|
"schoolLeaderApproval", "caseCheck").contains(pageCode);
|
||||||
|
String taskName = getWorkflowTaskName(pageCode);
|
||||||
|
|
||||||
|
String schoolLeaderColumns = isSchoolLeaderApproval ? """
|
||||||
|
GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 1 THEN pru.unitName END) AS masterUnitName,
|
||||||
|
GROUP_CONCAT(DISTINCT CASE WHEN pru.isMaster = 0 THEN pru.unitName END) AS slaveUnitNames,
|
||||||
|
""" : "";
|
||||||
|
String auditUserColumn = (isSchoolLeaderApproval || isUnitReply)
|
||||||
|
? "GROUP_CONCAT(DISTINCT ta.actorName, '(', ta.actorAccount, ')') AS auditUser,"
|
||||||
|
: "";
|
||||||
|
String unitReplyColumns = isUnitReply ? """
|
||||||
|
COALESCE(NULLIF(t.variable->>'$.underTakeName', ''), replyUnit.unitName) AS underTakeName,
|
||||||
|
CASE
|
||||||
|
WHEN JSON_EXTRACT(t.variable, '$.underTakeIsMaster') IS NOT NULL
|
||||||
|
THEN IF(JSON_EXTRACT(t.variable, '$.underTakeIsMaster') = true, 1, 0)
|
||||||
|
ELSE IFNULL(replyUnit.isMaster, 0)
|
||||||
|
END AS underTakeIsMaster,
|
||||||
|
""" : "";
|
||||||
|
String unionJoin = requiresUnionFilter ? "LEFT JOIN vw_user vu ON vu.id = info.createUserId" : "";
|
||||||
|
String schoolLeaderJoin = isSchoolLeaderApproval ? "LEFT JOIN proposal_reply_unit pru ON pru.proposalId = info.id" : "";
|
||||||
|
String unitReplyJoin = isUnitReply
|
||||||
|
? "LEFT JOIN proposal_reply_unit replyUnit ON replyUnit.proposalId = info.id AND replyUnit.unitId = ta.actorUnitId\n LEFT JOIN sys_user transferUser ON transferUser.id = t.variable->>'$.tf_transferUserId'"
|
||||||
|
: "";
|
||||||
|
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
info.*,
|
||||||
|
type.name AS typeName,
|
||||||
|
IF(mer.proposalId IS NOT NULL, 1, 0) AS merge,
|
||||||
|
tcs.fullName AS sessionName,
|
||||||
|
tcd.`name` AS delegationName,
|
||||||
|
ins.state AS instanceState,
|
||||||
|
t.finishTime,
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
IFNULL(GROUP_CONCAT(DISTINCT nt.displayName), '结束') AS curTaskName
|
||||||
|
FROM wf_process_task t
|
||||||
|
LEFT JOIN wf_process_instance ins ON ins.id = t.processInstanceId
|
||||||
|
LEFT JOIN wf_process_task_actor ta ON ta.processTaskId = t.id
|
||||||
|
LEFT JOIN wf_process_task nt ON nt.processInstanceId = ins.id AND nt.taskState = 10
|
||||||
|
LEFT JOIN proposal_info info ON info.id = ins.businessNo
|
||||||
|
LEFT JOIN proposal_type type ON type.id = info.typeId
|
||||||
|
LEFT JOIN proposal_merge mer ON mer.proposalId = info.id
|
||||||
|
LEFT JOIN teacher_congress_session tcs ON tcs.id = info.sessionId
|
||||||
|
LEFT JOIN teacher_congress_delegation tcd ON tcd.id = info.delegationId
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
%s
|
||||||
|
$condition
|
||||||
|
""".formatted(schoolLeaderColumns, auditUserColumn, unitReplyColumns, unionJoin, schoolLeaderJoin, unitReplyJoin));
|
||||||
|
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
if (isUnitReply) {
|
||||||
|
cnd.and("t.taskName", "in", List.of("unit_reply", "two_unit_reply", "opinion_unit_reply"));
|
||||||
|
if (!"superadmin".equals(SecurityUtil.getUserLoginname())) {
|
||||||
|
cnd.and("ta.actorId", "=", SecurityUtil.getUserId());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cnd.and("t.taskName", "=", taskName);
|
||||||
|
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
|
||||||
|
cnd.and("ta.actorId", "in", List.of(SecurityUtil.getUserId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (approval) {
|
||||||
|
cnd.and("t.taskState", "in", isUnitReply
|
||||||
|
? List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.TRANSFER.getCode())
|
||||||
|
: List.of(ProcessTaskStateEnum.FINISHED.getCode(), ProcessTaskStateEnum.INTERRUPT.getCode()));
|
||||||
|
} else {
|
||||||
|
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
|
||||||
|
}
|
||||||
|
if (requiresUnionFilter) {
|
||||||
|
cnd.andEX("vu.unionId", "=", pageForm.getUnionId());
|
||||||
|
}
|
||||||
|
ProposalSearchParam.buildSearch(cnd, pageForm);
|
||||||
|
cnd.groupBy("t.id");
|
||||||
|
if (!applySafeProposalListOrder(cnd, pageForm, pageCode)) {
|
||||||
|
cnd.desc("t.createdAt");
|
||||||
|
}
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取页面对应的流程任务编码,页面代码不匹配时拒绝导出。 */
|
||||||
|
private String getWorkflowTaskName(String pageCode) {
|
||||||
|
Map<String, String> taskNames = Map.of(
|
||||||
|
"delegation", "delegation",
|
||||||
|
"preAudit", "preAudit",
|
||||||
|
"committeeFiling", "committee",
|
||||||
|
"committeeFilingUnit", "committeeFilingUnit",
|
||||||
|
"schoolLeaderApproval", "schoolLeader",
|
||||||
|
"feedbackEvaluation", "feedback",
|
||||||
|
"caseCheck", "caseCheck"
|
||||||
|
);
|
||||||
|
String taskName = taskNames.get(pageCode);
|
||||||
|
if (StrUtil.isBlank(taskName) && !"unitReply".equals(pageCode)) {
|
||||||
|
throw Lang.makeThrow("不支持的提案列表导出页面");
|
||||||
|
}
|
||||||
|
return taskName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 将字典、枚举及组合字段转换为与列表页面相同的显示文本。 */
|
||||||
|
private void convertWorkflowExportValues(List<NutMap> rows, String pageCode) {
|
||||||
|
Map<String, String> caseFilingResultMap = sysDictService.getSubListByCode("PROPOSAL_CASE_FILING_RESULT")
|
||||||
|
.stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName));
|
||||||
|
Map<Integer, String> processStateMap = Arrays.stream(ProcessInstanceStateEnum.values())
|
||||||
|
.collect(Collectors.toMap(ProcessInstanceStateEnum::getCode, ProcessInstanceStateEnum::getMessage));
|
||||||
|
for (NutMap row : rows) {
|
||||||
|
if ("schoolLeaderApproval".equals(pageCode)) {
|
||||||
|
row.put("undertakeUnits", formatUndertakeUnits(row));
|
||||||
|
}
|
||||||
|
// 所有含“是否并案”列的办理页面统一导出“是/否”,避免未并案记录出现空白。
|
||||||
|
row.put("merge", row.getInt("merge") == 1 ? "是" : "否");
|
||||||
|
if ("unitReply".equals(pageCode)) {
|
||||||
|
row.put("underTakeIsMaster", row.getInt("underTakeIsMaster") == 1 ? "主办" : "协办");
|
||||||
|
}
|
||||||
|
row.put("caseFilingResult", caseFilingResultMap.getOrDefault(row.getString("caseFilingResult"), row.getString("caseFilingResult")));
|
||||||
|
Integer instanceState = row.getInt("instanceState");
|
||||||
|
row.put("instanceState", processStateMap.getOrDefault(instanceState, row.getString("instanceState")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 校领导审批页按页面展示规则拼接承办单位。 */
|
||||||
|
private String formatUndertakeUnits(NutMap row) {
|
||||||
|
String masterUnitNames = StrUtil.nullToEmpty(row.getString("masterUnitName"));
|
||||||
|
String slaveUnitNames = StrUtil.nullToEmpty(row.getString("slaveUnitNames"));
|
||||||
|
if ("SUGGESTION".equals(row.getString("caseFilingResult"))) {
|
||||||
|
return StrUtil.isNotBlank(masterUnitNames) ? masterUnitNames : slaveUnitNames;
|
||||||
|
}
|
||||||
|
if ("CONFIRM_FILING".equals(row.getString("caseFilingResult"))) {
|
||||||
|
List<String> unitNames = new ArrayList<>();
|
||||||
|
if (StrUtil.isNotBlank(masterUnitNames)) {
|
||||||
|
unitNames.add("主办:" + masterUnitNames);
|
||||||
|
}
|
||||||
|
if (StrUtil.isNotBlank(slaveUnitNames)) {
|
||||||
|
unitNames.add("协办:" + slaveUnitNames);
|
||||||
|
}
|
||||||
|
return StrUtil.join(";", unitNames);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 根据页面列定义过滤导出字段,确保导出范围只包含列表可展示字段。 */
|
||||||
|
private List<ExportTableColumns> getWorkflowExportColumns(String pageCode, ExportTableColumns[] tableColumns) {
|
||||||
|
Set<String> allowedColumns = WORKFLOW_EXPORT_COLUMNS.get(pageCode);
|
||||||
|
if (allowedColumns == null || tableColumns == null) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
return Arrays.stream(tableColumns)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(column -> StrUtil.isNotBlank(column.getLabel()) && allowedColumns.contains(column.getProp()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化各办理页面可导出的列表字段白名单。 */
|
||||||
|
private static Map<String, Set<String>> createWorkflowExportColumns() {
|
||||||
|
Set<String> commonColumns = Set.of("code", "caseFilingCode", "name", "createUserName", "typeName",
|
||||||
|
"sessionName", "delegationName", "curTaskName", "instanceState");
|
||||||
|
Map<String, Set<String>> columns = new HashMap<>();
|
||||||
|
columns.put("delegation", commonColumns);
|
||||||
|
columns.put("preAudit", commonColumns);
|
||||||
|
columns.put("caseCheck", Set.of("code", "caseFilingCode", "name", "createUserName", "typeName",
|
||||||
|
"sessionName", "delegationName", "curTaskName", "instanceState", "finishTime"));
|
||||||
|
columns.put("committeeFiling", Set.of("code", "caseFilingCode", "name", "typeName", "sessionName",
|
||||||
|
"caseFilingResult", "delegationName", "curTaskName", "instanceState"));
|
||||||
|
columns.put("committeeFilingUnit", Set.of("code", "caseFilingCode", "name", "typeName", "sessionName",
|
||||||
|
"caseFilingResult", "delegationName", "curTaskName", "instanceState"));
|
||||||
|
columns.put("schoolLeaderApproval", Set.of("code", "caseFilingCode", "name", "typeName", "undertakeUnits",
|
||||||
|
"merge", "curTaskName", "auditUser", "instanceState"));
|
||||||
|
columns.put("unitReply", Set.of("code", "caseFilingCode", "name", "typeName", "caseFilingResult",
|
||||||
|
"merge", "underTakeName", "underTakeIsMaster", "curTaskName", "auditUser", "instanceState"));
|
||||||
|
columns.put("feedbackEvaluation", Set.of("code", "caseFilingCode", "name", "typeName", "merge",
|
||||||
|
"curTaskName", "instanceState"));
|
||||||
|
return Collections.unmodifiableMap(columns);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 按白名单字段对统计结果执行后端排序,数字按数值比较,文本按中文区域规则比较。
|
* 按白名单字段对统计结果执行后端排序,数字按数值比较,文本按中文区域规则比较。
|
||||||
*
|
*
|
||||||
@@ -407,8 +632,11 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 按任务节点分组
|
// 按任务节点分组
|
||||||
Map<String, List<ProcessTaskVO>> taskGroups = doneTaskVos.stream().collect(Collectors.groupingBy(ProcessTaskVO::getDisplayName));
|
Map<String, List<ProcessTaskVO>> taskGroups = doneTaskVos.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.groupingBy(ProcessTaskVO::getDisplayName));
|
||||||
docData.putAll(taskGroups);
|
docData.putAll(taskGroups);
|
||||||
|
putProposalExportTaskAliases(id, taskGroups, docData);
|
||||||
|
|
||||||
// 提案附议
|
// 提案附议
|
||||||
List<NutMap> secondInfos = new ArrayList<>();
|
List<NutMap> secondInfos = new ArrayList<>();
|
||||||
@@ -479,22 +707,79 @@ public class ProposalCommonServiceImpl extends BaseServiceImpl<ProposalInfo> imp
|
|||||||
Configure config = Configure.builder()
|
Configure config = Configure.builder()
|
||||||
.bind("secondedList", policy)
|
.bind("secondedList", policy)
|
||||||
.bind("seconders", policy)
|
.bind("seconders", policy)
|
||||||
|
.bind("提案附议", policy)
|
||||||
|
.bind("提案委委员审议", policy)
|
||||||
.bind("brief", htmlRenderPolicy)
|
.bind("brief", htmlRenderPolicy)
|
||||||
.bind("measures", htmlRenderPolicy)
|
.bind("measures", htmlRenderPolicy)
|
||||||
.bind("taskFormData.tf_opinion", htmlRenderPolicy)
|
.bind("taskFormData.tf_opinion", htmlRenderPolicy)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
Map<String, Object> renderDocCellDataMap = MapUtil.of("proposal", docCellDataMap);
|
// 数据库模板使用平铺占位符(例如 {{code}}、{{sessionName}}),不能将基础字段嵌套到 proposal 节点。
|
||||||
renderDocCellDataMap.put("secondedList", secondInfos);
|
// 流程节点分组已写入 docData,附议人与代表团审核列表也必须写入同一上下文,才能被模板的循环标签识别。
|
||||||
renderDocCellDataMap.put("delegationAuditList", delegationAuditList);
|
docData.put("secondedList", secondInfos);
|
||||||
|
docData.put("delegationAuditList", delegationAuditList);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("proposal"), config).render(renderDocCellDataMap).writeAndClose(byteArrayOutputStream);
|
XWPFTemplate.compile(sysOfficeTemplateUtil.getTemplate("proposal"), config).render(docData).writeAndClose(byteArrayOutputStream);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
log.error("提案导出失败{},提案id:{}", e.getMessage(), id);
|
log.error("提案导出失败{},提案id:{}", e.getMessage(), id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将现行工作流节点映射到历史提案表模板使用的区块名称,并按主协办单位拆分办理答复。
|
||||||
|
* 模板仍使用旧节点名称时,避免已完成的意见和答复因键名不一致而无法渲染。
|
||||||
|
*
|
||||||
|
* @param proposalId 提案ID,用于查询主办单位
|
||||||
|
* @param taskGroups 已完成任务按显示名称分组后的数据
|
||||||
|
* @param docData Word 模板的平铺渲染数据
|
||||||
|
*/
|
||||||
|
private void putProposalExportTaskAliases(String proposalId, Map<String, List<ProcessTaskVO>> taskGroups,
|
||||||
|
NutMap docData) {
|
||||||
|
putTaskAlias(docData, "提案委主任审核", taskGroups.get("校工会预审核"));
|
||||||
|
putTaskAlias(docData, "提案委主任意见", taskGroups.get("提案委员会立案"));
|
||||||
|
putTaskAlias(docData, "提案委委员审议", taskGroups.get("委员会确认承办单位"));
|
||||||
|
|
||||||
|
List<ProcessTaskVO> replyTasks = taskGroups.get("承办单位答复");
|
||||||
|
if (Lang.isEmpty(replyTasks)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Sql masterUnitSql = Sqls.create("SELECT unitName FROM proposal_reply_unit WHERE proposalId = @proposalId AND isMaster = 1")
|
||||||
|
.setParam("proposalId", proposalId);
|
||||||
|
List<NutMap> masterUnitRows = listMap(masterUnitSql);
|
||||||
|
Set<String> masterUnitNames = masterUnitRows.stream()
|
||||||
|
.map(row -> row.getString("unitName"))
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
List<ProcessTaskVO> masterReplyTasks = new ArrayList<>();
|
||||||
|
List<ProcessTaskVO> slaveReplyTasks = new ArrayList<>();
|
||||||
|
for (ProcessTaskVO replyTask : replyTasks) {
|
||||||
|
Dict taskFormData = replyTask.getTaskFormData();
|
||||||
|
String unitName = taskFormData == null ? null : taskFormData.getStr("unitName");
|
||||||
|
if (masterUnitNames.contains(unitName)) {
|
||||||
|
masterReplyTasks.add(replyTask);
|
||||||
|
} else {
|
||||||
|
slaveReplyTasks.add(replyTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
putTaskAlias(docData, "主办单位答复", masterReplyTasks);
|
||||||
|
putTaskAlias(docData, "协办单位答复", slaveReplyTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仅在存在已完成任务时写入模板区块,空任务不触发 Word 条件标签。
|
||||||
|
*
|
||||||
|
* @param docData Word 模板的平铺渲染数据
|
||||||
|
* @param templateKey Word 模板中的条件或循环标签名称
|
||||||
|
* @param tasks 对应的已完成流程任务
|
||||||
|
*/
|
||||||
|
private void putTaskAlias(NutMap docData, String templateKey, List<ProcessTaskVO> tasks) {
|
||||||
|
if (Lang.isNotEmpty(tasks)) {
|
||||||
|
docData.put(templateKey, tasks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exportProposalFeedBackAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream) {
|
public void exportProposalFeedBackAsDocx(String id, ByteArrayOutputStream byteArrayOutputStream) {
|
||||||
if (id == null || id.isEmpty()) {
|
if (id == null || id.isEmpty()) {
|
||||||
|
|||||||
+14
-64
@@ -25,7 +25,6 @@ import org.nutz.dao.util.cri.SqlExpressionGroup;
|
|||||||
import org.nutz.ioc.aop.Aop;
|
import org.nutz.ioc.aop.Aop;
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.lang.Strings;
|
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
@@ -69,32 +68,25 @@ public class TeacherCongressInstitutionController {
|
|||||||
Teacher_congress_institution rootInstitution = new Teacher_congress_institution();
|
Teacher_congress_institution rootInstitution = new Teacher_congress_institution();
|
||||||
rootInstitution.setId("0");
|
rootInstitution.setId("0");
|
||||||
rootInstitution.setParentId("");
|
rootInstitution.setParentId("");
|
||||||
rootInstitution.setName("两代会组织机构");
|
rootInstitution.setName("教代会机构");
|
||||||
rootInstitution.setLocation(0);
|
rootInstitution.setLocation(0);
|
||||||
institutionList.add(rootInstitution);
|
institutionList.add(rootInstitution);
|
||||||
|
|
||||||
List<TreeNode<String>> treeNodes = institutionList.stream().map(institution -> {
|
List<TreeNode<String>> treeNodes = institutionList.stream().map(institution -> new TreeNode<>(institution.getId(), institution.getParentId(), institution.getName(), institution.getLocation())).toList();
|
||||||
TreeNode<String> treeNode = new TreeNode<>(institution.getId(), institution.getParentId(), institution.getName(), institution.getLocation());
|
|
||||||
treeNode.setExtra(Map.of("code", Strings.sNull(institution.getCode())));
|
|
||||||
return treeNode;
|
|
||||||
}).toList();
|
|
||||||
List<Tree<String>> treeList = TreeUtil.build(treeNodes, "");
|
List<Tree<String>> treeList = TreeUtil.build(treeNodes, "");
|
||||||
return Result.success(treeList);
|
return Result.success(treeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取新增机构表单使用的固定机构字典树。
|
* 表单中的树结构
|
||||||
*
|
*
|
||||||
* @param sessionId 当前教代会届次ID,用于保持接口参数与机构管理页面上下文一致
|
* @param sessionId
|
||||||
* @return Result,data.treeList 为级联组件树结构,data.treeFlat 为名称和代码回填使用的扁平字典列表
|
* @return
|
||||||
*/
|
*/
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("tc.institution")
|
@SaCheckPermission("tc.institution")
|
||||||
public Result formTree(@Valid String sessionId) {
|
public Result formTree(@Valid String sessionId) {
|
||||||
Sys_dict institutionFixedDict = sysDictService.fetch(Cnd.where(Sys_dict::getCode, "=", "TEACHER_CONGRESS_INSTITUTION_FIXED"));
|
Sys_dict institutionFixedDict = sysDictService.fetch(Cnd.where(Sys_dict::getCode, "=", "TEACHER_CONGRESS_INSTITUTION_FIXED"));
|
||||||
if (ObjectUtil.isEmpty(institutionFixedDict)) {
|
|
||||||
return Result.error("未配置双代会固定机构字典");
|
|
||||||
}
|
|
||||||
List<Sys_dict> children = sysDictService.query(Cnd.where(Sys_dict::getPath, "like", institutionFixedDict.getPath() + "%"));
|
List<Sys_dict> children = sysDictService.query(Cnd.where(Sys_dict::getPath, "like", institutionFixedDict.getPath() + "%"));
|
||||||
List<TreeNode<String>> treeNodes = children.stream().map(sysDict -> {
|
List<TreeNode<String>> treeNodes = children.stream().map(sysDict -> {
|
||||||
TreeNode<String> treeNode = new TreeNode<>(sysDict.getId(), sysDict.getParentId(), sysDict.getName(), sysDict.getLocation());
|
TreeNode<String> treeNode = new TreeNode<>(sysDict.getId(), sysDict.getParentId(), sysDict.getName(), sysDict.getLocation());
|
||||||
@@ -105,16 +97,6 @@ public class TeacherCongressInstitutionController {
|
|||||||
return Result.success(Map.of("treeFlat", children, "treeList", treeList));
|
return Result.success(Map.of("treeFlat", children, "treeList", treeList));
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
|
||||||
@SaCheckPermission("tc.institution")
|
|
||||||
public Result specialCommitteeRoleOptions() {
|
|
||||||
Sys_dict parent = sysDictService.fetch(Cnd.where(Sys_dict::getCode, "=", "SPECIAL_COMMITTEE_ROLES"));
|
|
||||||
if (ObjectUtil.isEmpty(parent)) {
|
|
||||||
return Result.success(List.of());
|
|
||||||
}
|
|
||||||
List<Sys_dict> children = sysDictService.query(Cnd.where(Sys_dict::getPath, "like", parent.getPath() + "%").and(Sys_dict::getId, "!=", parent.getId()).asc(Sys_dict::getLocation));
|
|
||||||
return Result.success(children);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 机构分页查询
|
* 机构分页查询
|
||||||
@@ -131,30 +113,24 @@ public class TeacherCongressInstitutionController {
|
|||||||
cnd.and("parentId", "=", parentId);
|
cnd.and("parentId", "=", parentId);
|
||||||
cnd.and("sessionId", "=", sessionId);
|
cnd.and("sessionId", "=", sessionId);
|
||||||
cnd.asc("location");
|
cnd.asc("location");
|
||||||
cnd.asc("code");
|
|
||||||
Pagination pagination = baseService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), "teacher_congress_institution", cnd);
|
Pagination pagination = baseService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), "teacher_congress_institution", cnd);
|
||||||
return Result.success(pagination);
|
return Result.success(pagination);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加当前届次的机构。
|
* 添加机构
|
||||||
*
|
*
|
||||||
* @param institution 机构数据,包含 sessionId、name、code、parentId、location 和 introduce;parentId 可能是固定字典ID
|
* @param institution
|
||||||
* @return Result,机构重复或父级不存在时返回错误,否则返回成功
|
* @return
|
||||||
*/
|
*/
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("tc.institution")
|
@SaCheckPermission("tc.institution")
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
|
||||||
public Result insert(Teacher_congress_institution institution) {
|
public Result insert(Teacher_congress_institution institution) {
|
||||||
if (dao.count(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getCode, "=", institution.getCode()).and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId())) > 0) {
|
if (dao.count(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getCode, "=", institution.getCode()).and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId())) > 0) {
|
||||||
return Result.error("机构已存在");
|
return Result.error("机构已存在");
|
||||||
}
|
}
|
||||||
if (StrUtil.isNotBlank(institution.getParentId()) && !institution.getParentId().equals("0") && dao.count(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getId, "=", institution.getParentId()).and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId())) == 0) {
|
if (StrUtil.isNotBlank(institution.getParentId()) && !institution.getParentId().equals("0")) {
|
||||||
// 级联框提交的是固定字典父级ID,需要按机构代码匹配当前届次的实际父机构。
|
|
||||||
Sys_dict sysDict = sysDictService.fetch(Cnd.where(Sys_dict::getId, "=", institution.getParentId()));
|
Sys_dict sysDict = sysDictService.fetch(Cnd.where(Sys_dict::getId, "=", institution.getParentId()));
|
||||||
if (ObjectUtil.isEmpty(sysDict)) {
|
|
||||||
return Result.error("父级机构不存在");
|
|
||||||
}
|
|
||||||
Teacher_congress_institution parentInstitution = dao.fetch(Teacher_congress_institution.class,
|
Teacher_congress_institution parentInstitution = dao.fetch(Teacher_congress_institution.class,
|
||||||
Cnd.where(Teacher_congress_institution::getCode, "=", sysDict.getCode())
|
Cnd.where(Teacher_congress_institution::getCode, "=", sysDict.getCode())
|
||||||
.and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId())
|
.and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId())
|
||||||
@@ -170,40 +146,15 @@ public class TeacherCongressInstitutionController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新机构名称、描述和排序。
|
* 删除机构
|
||||||
*
|
*
|
||||||
* @param institution 机构数据,id 标识待更新机构,name、introduce、location 为可更新内容
|
* @param id
|
||||||
* @return Result,机构不存在时返回错误,否则返回成功
|
* @return
|
||||||
*/
|
*/
|
||||||
@At
|
|
||||||
@SaCheckPermission("tc.institution")
|
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
|
||||||
public Result update(Teacher_congress_institution institution) {
|
|
||||||
Teacher_congress_institution dbInstitution = dao.fetch(Teacher_congress_institution.class, institution.getId());
|
|
||||||
if (ObjectUtil.isEmpty(dbInstitution)) {
|
|
||||||
return Result.error("机构不存在");
|
|
||||||
}
|
|
||||||
dbInstitution.setName(institution.getName());
|
|
||||||
dbInstitution.setIntroduce(institution.getIntroduce());
|
|
||||||
dbInstitution.setLocation(institution.getLocation());
|
|
||||||
dao.update(dbInstitution);
|
|
||||||
return Result.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("tc.institution")
|
@SaCheckPermission("tc.institution")
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Result delete(@Valid String id) {
|
public Result delete(@Valid String id) {
|
||||||
Teacher_congress_institution institution = dao.fetch(Teacher_congress_institution.class, id);
|
|
||||||
if (ObjectUtil.isEmpty(institution)) {
|
|
||||||
return Result.error("机构不存在");
|
|
||||||
}
|
|
||||||
List<Teacher_congress_institution> siblingList = dao.query(Teacher_congress_institution.class, Cnd.where(Teacher_congress_institution::getParentId, "=", institution.getParentId()).and(Teacher_congress_institution::getSessionId, "=", institution.getSessionId()).asc(Teacher_congress_institution::getLocation).asc(Teacher_congress_institution::getCode));
|
|
||||||
for (int i = 0; i < siblingList.size() && i < 6; i++) {
|
|
||||||
if (id.equals(siblingList.get(i).getId())) {
|
|
||||||
return Result.error("你选择的组织机构是两代会基本机构,不允许删除。");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dao.delete(Teacher_congress_institution.class, id);
|
dao.delete(Teacher_congress_institution.class, id);
|
||||||
dao.clear(Teacher_congress_institution_user.class, Cnd.where("institutionId", "=", id));
|
dao.clear(Teacher_congress_institution_user.class, Cnd.where("institutionId", "=", id));
|
||||||
return Result.success();
|
return Result.success();
|
||||||
@@ -263,8 +214,8 @@ public class TeacherCongressInstitutionController {
|
|||||||
@SaCheckPermission("tc.institution")
|
@SaCheckPermission("tc.institution")
|
||||||
@SLog(tag = "教代会-机构设置", msg = "添加人员")
|
@SLog(tag = "教代会-机构设置", msg = "添加人员")
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public Result userInsert(@Valid String userId, @Valid String institutionId, @Valid String sessionId, @Valid String identity, String roleCode) {
|
public Result userInsert(@Valid String userId, @Valid String institutionId, @Valid String sessionId, @Valid String identity) {
|
||||||
teacherCongressInstitutionUserService.userInsert(userId, institutionId, sessionId, identity, roleCode);
|
teacherCongressInstitutionUserService.userInsert(userId, institutionId, sessionId, identity);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,7 +227,6 @@ public class TeacherCongressInstitutionController {
|
|||||||
*/
|
*/
|
||||||
@At
|
@At
|
||||||
@SaCheckPermission("tc.institution")
|
@SaCheckPermission("tc.institution")
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
|
||||||
public Result userDelete(@Valid String id) {
|
public Result userDelete(@Valid String id) {
|
||||||
teacherCongressInstitutionUserService.userDelete(id);
|
teacherCongressInstitutionUserService.userDelete(id);
|
||||||
return Result.success();
|
return Result.success();
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@ public interface TeacherCongressInstitutionUserService extends BaseService<Teach
|
|||||||
* @param sessionId 届次id
|
* @param sessionId 届次id
|
||||||
* @param identity 身份 主任|副主任|成员
|
* @param identity 身份 主任|副主任|成员
|
||||||
*/
|
*/
|
||||||
void userInsert(String userId, String institutionId, String sessionId, String identity, String roleCode);
|
void userInsert(String userId, String institutionId, String sessionId, String identity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除机构成员
|
* 删除机构成员
|
||||||
|
|||||||
+1
-24
@@ -1,6 +1,5 @@
|
|||||||
package com.budwk.app.zhgh.democratic.teachercongress.institution.service.impl;
|
package com.budwk.app.zhgh.democratic.teachercongress.institution.service.impl;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import com.budwk.app.base.constant.RoleConstant;
|
import com.budwk.app.base.constant.RoleConstant;
|
||||||
import com.budwk.app.base.exception.BaseException;
|
import com.budwk.app.base.exception.BaseException;
|
||||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||||
@@ -31,7 +30,7 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
public void userInsert(String userId, String institutionId, String sessionId, String identity, String roleCode) {
|
public void userInsert(String userId, String institutionId, String sessionId, String identity) {
|
||||||
int count = dao().count(Teacher_congress_institution_user.class,
|
int count = dao().count(Teacher_congress_institution_user.class,
|
||||||
Cnd.where(Teacher_congress_institution_user::getInstitutionId, "=", institutionId)
|
Cnd.where(Teacher_congress_institution_user::getInstitutionId, "=", institutionId)
|
||||||
.and(Teacher_congress_institution_user::getUserId, "=", userId)
|
.and(Teacher_congress_institution_user::getUserId, "=", userId)
|
||||||
@@ -50,28 +49,6 @@ public class TeacherCongressInstitutionUserServiceImpl extends BaseServiceImpl<T
|
|||||||
dao().insert(institutionUser);
|
dao().insert(institutionUser);
|
||||||
|
|
||||||
Teacher_congress_institution institution = dao().fetch(Teacher_congress_institution.class, institutionId);
|
Teacher_congress_institution institution = dao().fetch(Teacher_congress_institution.class, institutionId);
|
||||||
if ("ZWH001".equals(institution.getCode()) || "ZXWYH".equals(institution.getCode()) || "DBZGSCXZ".equals(institution.getCode())) {
|
|
||||||
if (StrUtil.isBlank(roleCode)) {
|
|
||||||
throw new BaseException("请选择角色");
|
|
||||||
}
|
|
||||||
Sys_role sysRole = sysRoleService.fetch(Cnd.where(Sys_role::getCode, "=", roleCode));
|
|
||||||
if (sysRole == null) {
|
|
||||||
throw new BaseException("无法找到" + roleCode + "对应编码的角色");
|
|
||||||
}
|
|
||||||
int existsRole = dao().count(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
|
||||||
.and(Sys_user_role::getTcSessionId, "=", sessionId)
|
|
||||||
.and(Sys_user_role::getRoleId, "=", sysRole.getId())
|
|
||||||
);
|
|
||||||
if (existsRole == 0) {
|
|
||||||
Sys_user_role insertSysUserRole = new Sys_user_role();
|
|
||||||
insertSysUserRole.setRoleId(sysRole.getId());
|
|
||||||
insertSysUserRole.setUserId(userId);
|
|
||||||
insertSysUserRole.setTcSessionId(sessionId);
|
|
||||||
dao().insert(insertSysUserRole);
|
|
||||||
sysRoleService.clearCache();
|
|
||||||
sysUserService.clearCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (institution.getCode().contains("TEACHER_CONGRESS_INSTITUTION_PROPOSAL_COMMITTEE") && identity.equals("主任")) {
|
if (institution.getCode().contains("TEACHER_CONGRESS_INSTITUTION_PROPOSAL_COMMITTEE") && identity.equals("主任")) {
|
||||||
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DIRECTOR);
|
Sys_role sysRole = sysRoleService.getByCode(RoleConstant.PROPOSAL_COMMITTEE_DIRECTOR);
|
||||||
int existsRole = dao().count(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
int existsRole = dao().count(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "=", userId)
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ const act = {
|
|||||||
},
|
},
|
||||||
/*初始化Swiper*/
|
/*初始化Swiper*/
|
||||||
initSwiper() {
|
initSwiper() {
|
||||||
|
if (this.swiper) {
|
||||||
|
this.swiper.destroy(true, true)
|
||||||
|
this.swiper = null
|
||||||
|
}
|
||||||
this.swiper = new Swiper('.activity-swiper', {
|
this.swiper = new Swiper('.activity-swiper', {
|
||||||
slidesPerView: 1,
|
slidesPerView: 1,
|
||||||
spaceBetween: 18,
|
spaceBetween: 18,
|
||||||
@@ -133,6 +137,7 @@ const act = {
|
|||||||
style: /*language=CSS*/ `
|
style: /*language=CSS*/ `
|
||||||
.activity-section-wrapper {
|
.activity-section-wrapper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section-act .section-act-title span {
|
.section-act .section-act-title span {
|
||||||
@@ -176,17 +181,23 @@ const act = {
|
|||||||
.activity-swiper-container {
|
.activity-swiper-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
padding: 9px 14px;
|
padding: 9px 14px;
|
||||||
/*margin-top: 30px;*/
|
/*margin-top: 30px;*/
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-swiper {
|
.activity-swiper {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
min-width: 0;
|
||||||
/*padding: 0 50px 20px 50px;*/
|
/*padding: 0 50px 20px 50px;*/
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-swiper .swiper-slide {
|
.activity-swiper .swiper-slide {
|
||||||
height: auto;
|
height: auto;
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 导航按钮样式 */
|
/* 导航按钮样式 */
|
||||||
@@ -235,6 +246,8 @@ const act = {
|
|||||||
height: auto;
|
height: auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-swiper .swiper-slide .item .img-box {
|
.activity-swiper .swiper-slide .item .img-box {
|
||||||
@@ -260,9 +273,12 @@ const act = {
|
|||||||
|
|
||||||
|
|
||||||
.activity-swiper .swiper-slide .item .img-box img {
|
.activity-swiper .swiper-slide .item .img-box img {
|
||||||
width: 100%;
|
display: block;
|
||||||
height: 100%;
|
width: 100% !important;
|
||||||
object-fit: cover;
|
height: 100% !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
max-height: 128px !important;
|
||||||
|
object-fit: cover !important;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,6 +314,9 @@ const act = {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
color: #666;
|
color: #666;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.activity-swiper .swiper-slide .item .time i {
|
.activity-swiper .swiper-slide .item .time i {
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ const entry = {
|
|||||||
:key="item.id || index"
|
:key="item.id || index"
|
||||||
@click="openService(item, section.key)">
|
@click="openService(item, section.key)">
|
||||||
<div class="app-icon">
|
<div class="app-icon">
|
||||||
<img :src="item.picIcon" alt="" />
|
<img v-if="item.picIcon" class="app-icon-img" :src="item.picIcon" alt="" />
|
||||||
|
<i v-else class="fa fa-cube app-icon-fallback"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="app-name">{{ item.name }}</div>
|
<div class="app-name">{{ item.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -167,7 +168,7 @@ const entry = {
|
|||||||
|
|
||||||
.app-grid {
|
.app-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(108px, 1fr));
|
||||||
justify-items: center;
|
justify-items: center;
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
gap: 12px 18px;
|
gap: 12px 18px;
|
||||||
@@ -185,13 +186,17 @@ const entry = {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 100%;
|
max-width: 108px;
|
||||||
|
min-width: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-item:hover {
|
.app-item:hover {
|
||||||
@@ -200,24 +205,46 @@ const entry = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.app-icon {
|
.app-icon {
|
||||||
width: 46px;
|
width: 56px;
|
||||||
height: 46px;
|
height: 56px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 0 0 56px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #f5f8ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-icon img {
|
.app-icon img,
|
||||||
width: 100%;
|
.app-icon-img {
|
||||||
height: 100%;
|
display: block;
|
||||||
object-fit: contain;
|
width: 56px !important;
|
||||||
|
height: 56px !important;
|
||||||
|
max-width: 56px !important;
|
||||||
|
max-height: 56px !important;
|
||||||
|
object-fit: contain !important;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-icon-fallback {
|
||||||
|
color: #409eff;
|
||||||
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-name {
|
.app-name {
|
||||||
min-height: 34px;
|
min-height: 34px;
|
||||||
|
width: 100%;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #333;
|
color: #333;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
overflow: hidden;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-empty {
|
.app-empty {
|
||||||
|
|||||||
@@ -4,225 +4,268 @@ layout("/layouts/platform.html"){
|
|||||||
<style>
|
<style>
|
||||||
#app {
|
#app {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
min-height: calc(100vh - 64px);
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
min-height: calc(100vh - 40px);
|
background-color: #f0f2f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tool-card {
|
.box-card {
|
||||||
width: calc(100% - 20px);
|
width: calc(100% - 20px);
|
||||||
min-height: calc(100vh - 60px);
|
min-height: calc(100vh - 84px);
|
||||||
}
|
|
||||||
|
|
||||||
.tool-card .el-card__body {
|
|
||||||
height: calc(100% - 57px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-body {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
min-height: calc(100vh - 180px);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tool-body-center {
|
|
||||||
width: 70%;
|
|
||||||
min-width: 900px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wizard-box {
|
.box-card .el-card__body {
|
||||||
margin-top: 20px;
|
min-height: calc(100vh - 170px);
|
||||||
border: 1px solid #ebeef5;
|
position: relative;
|
||||||
border-radius: 8px;
|
}
|
||||||
background: #fff;
|
|
||||||
|
.box-card-title {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
min-height: calc(100vh - 170px);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body-center {
|
||||||
|
width: 60%;
|
||||||
|
min-width: 800px;
|
||||||
|
min-height: calc(100vh - 170px);
|
||||||
|
position: relative;
|
||||||
|
padding-bottom: 70px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body-center-bottom {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body-center-bottom button {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body-center > .el-carousel {
|
||||||
|
height: calc(100vh - 300px);
|
||||||
|
min-height: 560px;
|
||||||
|
position: relative;
|
||||||
|
overflow-y: hidden;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-body-center > .el-carousel > .el-carousel__container {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-table-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-table-item-center {
|
||||||
|
height: 100%;
|
||||||
|
width: 90%;
|
||||||
|
min-width: 800px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wizard-panel {
|
.carousel-table-item-center .el-card__body {
|
||||||
padding: 18px;
|
|
||||||
min-height: 520px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-toolbar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-list {
|
|
||||||
width: 100%;
|
|
||||||
display: block;
|
|
||||||
max-height: 470px;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding-right: 8px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-list .el-radio,
|
|
||||||
.option-list .el-checkbox {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0 0 12px 0 !important;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-list .el-radio.is-bordered,
|
|
||||||
.option-list .el-checkbox.is-bordered {
|
|
||||||
margin-left: 0 !important;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.option-list .el-radio__label,
|
|
||||||
.option-list .el-checkbox__label {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
flex: 1;
|
||||||
min-width: 0;
|
height: auto;
|
||||||
padding-right: 0;
|
min-height: 0;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-group {
|
||||||
|
display: block;
|
||||||
|
overflow: visible;
|
||||||
|
padding: 0 10px 5px 0;
|
||||||
|
height: auto;
|
||||||
|
min-height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-group .el-radio,
|
||||||
|
.check-group .el-checkbox {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 12px;
|
||||||
|
margin: 0 !important;
|
||||||
|
margin-top: 15px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-group .el-checkbox__label,
|
||||||
|
.check-group .el-radio__label {
|
||||||
|
width: calc(100% - 16px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-extra {
|
.option-extra {
|
||||||
|
float: right;
|
||||||
color: #f56c6c;
|
color: #f56c6c;
|
||||||
margin-left: auto;
|
|
||||||
padding-left: 12px;
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-item-content {
|
.carousel-table-item-relation .el-card__body,
|
||||||
display: flex;
|
.carousel-table-item-form .el-card__body {
|
||||||
align-items: center;
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carousel-table-item-form .el-card__body {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.result-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
margin-top: 6px;
|
||||||
gap: 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.option-item-main {
|
.result-card .el-card__body {
|
||||||
min-width: 0;
|
min-height: 170px;
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.relation-table {
|
|
||||||
height: 500px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.submit-panel {
|
|
||||||
max-width: 900px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.result-panel {
|
|
||||||
min-height: 420px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.wizard-footer {
|
.result-text {
|
||||||
display: flex;
|
font-size: 12px;
|
||||||
justify-content: center;
|
color: rgb(100, 100, 100);
|
||||||
gap: 12px;
|
margin-top: 20px;
|
||||||
margin-top: 18px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div id="app" v-cloak>
|
<div id="app" v-cloak>
|
||||||
<el-card class="tool-card" shadow="never">
|
<el-card class="box-card" shadow="never">
|
||||||
<div slot="header">
|
<div slot="header" class="clearfix">
|
||||||
<span>高级工具</span>
|
<span class="box-card-title">DataKid</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="tool-body">
|
<div class="card-body">
|
||||||
<div class="tool-body-center">
|
<div class="card-body-center">
|
||||||
<el-steps :active="active" align-center finish-status="success">
|
<el-steps :active="active" align-center>
|
||||||
<el-step title="选择数据表" icon="el-icon-coin"></el-step>
|
<el-step title="选择数据表" icon="el-icon-document-copy"></el-step>
|
||||||
<el-step title="选择字段" icon="el-icon-s-grid"></el-step>
|
<el-step title="选择数据列" icon="el-icon-s-unfold"></el-step>
|
||||||
<el-step title="字段对应" icon="el-icon-connection"></el-step>
|
<el-step title="数据列对应" icon="el-icon-s-operation"></el-step>
|
||||||
<el-step title="提交导入" icon="el-icon-upload2"></el-step>
|
<el-step title="提交数据" icon="el-icon-upload"></el-step>
|
||||||
<el-step title="导入结果" icon="el-icon-success"></el-step>
|
<el-step title="导入结果" icon="el-icon-bell"></el-step>
|
||||||
</el-steps>
|
</el-steps>
|
||||||
|
|
||||||
<div class="wizard-box">
|
<el-carousel indicator-position="none" :autoplay="false" arrow="never" ref="carousel" direction="vertical">
|
||||||
<div class="wizard-panel" v-if="active === 0">
|
<el-carousel-item class="carousel-table-item">
|
||||||
<div class="option-toolbar">
|
<el-card class="carousel-table-item-center">
|
||||||
<el-input
|
<div slot="header" class="clearfix">
|
||||||
v-model.trim="tableKeyword"
|
<el-input
|
||||||
clearable
|
style="width: 200px"
|
||||||
placeholder="输入表名或备注搜索"
|
v-model.trim="tableKeyword"
|
||||||
style="width: 260px">
|
placeholder="请输入关键字查询"
|
||||||
</el-input>
|
clearable>
|
||||||
<el-button type="primary" icon="el-icon-search" @click="filterTables">搜索</el-button>
|
</el-input>
|
||||||
<el-button v-if="formData.tableName" type="text">当前选择:{{ formData.tableName }}</el-button>
|
<el-button type="primary" icon="el-icon-search" @click="filterTables"></el-button>
|
||||||
</div>
|
<el-button v-if="formData.tableName" style="float: right; padding: 10px 0" type="text">
|
||||||
<el-radio-group v-model="formData.tableName" class="option-list">
|
当前选中:{{ formData.tableName }}
|
||||||
<el-radio
|
</el-button>
|
||||||
v-for="item in filteredTables"
|
</div>
|
||||||
:key="item.table_name"
|
|
||||||
:label="item.table_name"
|
<el-radio-group class="check-group" v-model="formData.tableName">
|
||||||
border>
|
<el-radio
|
||||||
<div class="option-item-content">
|
v-for="item in filteredTables"
|
||||||
<span class="option-item-main">{{ item.table_name }}</span>
|
:key="item.table_name"
|
||||||
<span v-if="item.table_comment" class="option-item-main">({{ item.table_comment }})</span>
|
:label="item.table_name"
|
||||||
|
border>
|
||||||
|
{{ item.table_name }}{{ item.table_comment ? " ( " + item.table_comment + " )" : "" }}
|
||||||
<span class="option-extra">rows: {{ item.table_rows || 0 }}</span>
|
<span class="option-extra">rows: {{ item.table_rows || 0 }}</span>
|
||||||
</div>
|
</el-radio>
|
||||||
</el-radio>
|
</el-radio-group>
|
||||||
</el-radio-group>
|
</el-card>
|
||||||
</div>
|
</el-carousel-item>
|
||||||
|
|
||||||
<div class="wizard-panel" v-if="active === 1">
|
<el-carousel-item class="carousel-table-item">
|
||||||
<div class="option-toolbar">
|
<el-card class="carousel-table-item-center">
|
||||||
<el-input
|
<div slot="header" class="clearfix">
|
||||||
v-model.trim="columnKeyword"
|
<el-input
|
||||||
clearable
|
style="width: 200px"
|
||||||
placeholder="输入字段名或备注搜索"
|
v-model.trim="columnKeyword"
|
||||||
style="width: 260px">
|
placeholder="请输入关键字查询"
|
||||||
</el-input>
|
clearable>
|
||||||
<el-button type="primary" icon="el-icon-search" @click="filterColumns">搜索</el-button>
|
</el-input>
|
||||||
<el-button type="text">{{ formData.tableName }}</el-button>
|
<el-button type="primary" icon="el-icon-search" @click="filterColumns"></el-button>
|
||||||
</div>
|
<el-button style="float: right; padding: 10px 0" type="text">
|
||||||
<el-checkbox-group v-model="formData.columns" class="option-list">
|
{{ formData.tableName }}
|
||||||
<el-checkbox
|
</el-button>
|
||||||
v-for="item in filteredColumns"
|
</div>
|
||||||
:key="item.column_name"
|
|
||||||
:label="item.column_name"
|
<el-checkbox-group class="check-group" v-model="formData.columns">
|
||||||
border>
|
<el-checkbox
|
||||||
<div class="option-item-content">
|
v-for="item in filteredColumns"
|
||||||
<span class="option-item-main">{{ item.column_name }}</span>
|
:key="item.column_name"
|
||||||
<span v-if="item.column_comment" class="option-item-main">({{ item.column_comment }})</span>
|
:label="item.column_name"
|
||||||
|
border>
|
||||||
|
{{ item.column_name }}{{ item.column_comment ? " ( " + item.column_comment + " )" : "" }}
|
||||||
<span class="option-extra">{{ item.column_type }}</span>
|
<span class="option-extra">{{ item.column_type }}</span>
|
||||||
</div>
|
</el-checkbox>
|
||||||
</el-checkbox>
|
</el-checkbox-group>
|
||||||
</el-checkbox-group>
|
</el-card>
|
||||||
</div>
|
</el-carousel-item>
|
||||||
|
|
||||||
<div class="wizard-panel" v-if="active === 2">
|
<el-carousel-item class="carousel-table-item">
|
||||||
<el-alert
|
<el-card style="width: 100%" class="carousel-table-item-relation">
|
||||||
title="这里填写 Excel 第一行表头名称,用来和数据库字段建立对应关系。"
|
<el-table :data="relation" height="100%" style="width: 100%" border size="medium">
|
||||||
type="info"
|
<el-table-column prop="column_name" label="列名"></el-table-column>
|
||||||
:closable="false"
|
<el-table-column prop="column_comment" label="描述" show-overflow-tooltip></el-table-column>
|
||||||
style="margin-bottom: 16px">
|
<el-table-column prop="is_nullable" label="可为空"></el-table-column>
|
||||||
</el-alert>
|
<el-table-column prop="column_type" label="类型"></el-table-column>
|
||||||
<el-table :data="relation" border class="relation-table">
|
<el-table-column prop="column_key" label="key"></el-table-column>
|
||||||
<el-table-column prop="column_name" label="字段名" min-width="180"></el-table-column>
|
<el-table-column min-width="200px">
|
||||||
<el-table-column prop="column_comment" label="字段备注" min-width="220" show-overflow-tooltip></el-table-column>
|
<template slot="header">
|
||||||
<el-table-column prop="column_type" label="字段类型" width="160"></el-table-column>
|
目标列
|
||||||
<el-table-column prop="column_key" label="键" width="80"></el-table-column>
|
<el-popover
|
||||||
<el-table-column label="Excel 表头" min-width="260">
|
placement="top-start"
|
||||||
<template slot-scope="{ row }">
|
title="提示"
|
||||||
<el-input v-model.trim="row.relation" placeholder="请输入 Excel 表头名称"></el-input>
|
trigger="hover"
|
||||||
</template>
|
content="Excel 对应的表头名称,用于和表数据列对应">
|
||||||
</el-table-column>
|
<i slot="reference" class="el-icon-question"></i>
|
||||||
</el-table>
|
</el-popover>
|
||||||
</div>
|
</template>
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-input
|
||||||
|
v-model.trim="row.relation"
|
||||||
|
size="medium"
|
||||||
|
placeholder="目标列">
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-card>
|
||||||
|
</el-carousel-item>
|
||||||
|
|
||||||
<div class="wizard-panel" v-if="active === 3">
|
<el-carousel-item class="carousel-table-item">
|
||||||
<div class="submit-panel">
|
<el-card style="width: 100%" class="carousel-table-item-form">
|
||||||
<el-form label-width="120px">
|
<el-form label-width="120px" :model="formData" ref="form" :rules="formRules">
|
||||||
<el-form-item label="导入方式">
|
<el-form-item label=" " label-width="135px" class="view-header"></el-form-item>
|
||||||
|
|
||||||
|
<el-form-item prop="method" label="导入方式">
|
||||||
<el-radio-group v-model="formData.method">
|
<el-radio-group v-model="formData.method">
|
||||||
<el-radio-button :label="1">追加或更新</el-radio-button>
|
<el-radio-button :label="1">追加或更新</el-radio-button>
|
||||||
<el-radio-button :label="2">仅追加</el-radio-button>
|
<el-radio-button :label="2">仅追加</el-radio-button>
|
||||||
@@ -230,13 +273,8 @@ layout("/layouts/platform.html"){
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="关键字段" v-if="[1, 3].includes(formData.method)">
|
<el-form-item v-if="[1, 3].includes(formData.method)" prop="field" label="关键字段">
|
||||||
<el-select
|
<el-select v-model="formData.field" clearable filterable placeholder="请选择" style="width: 50%">
|
||||||
v-model="formData.field"
|
|
||||||
clearable
|
|
||||||
filterable
|
|
||||||
placeholder="请选择关键字段"
|
|
||||||
style="width: 360px">
|
|
||||||
<el-option
|
<el-option
|
||||||
v-for="item in relation"
|
v-for="item in relation"
|
||||||
:key="item.column_name"
|
:key="item.column_name"
|
||||||
@@ -246,7 +284,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="可选插件">
|
<el-form-item prop="plugins" label="可选插件">
|
||||||
<el-checkbox-group v-model="formData.plugins">
|
<el-checkbox-group v-model="formData.plugins">
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
v-for="item in plugins"
|
v-for="item in plugins"
|
||||||
@@ -258,7 +296,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-checkbox-group>
|
</el-checkbox-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="Excel 文件" required>
|
<el-form-item label="文  件" class="is-required">
|
||||||
<el-upload
|
<el-upload
|
||||||
ref="upload"
|
ref="upload"
|
||||||
drag
|
drag
|
||||||
@@ -270,30 +308,35 @@ layout("/layouts/platform.html"){
|
|||||||
:on-remove="handleFileRemove">
|
:on-remove="handleFileRemove">
|
||||||
<i class="el-icon-upload"></i>
|
<i class="el-icon-upload"></i>
|
||||||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||||
<div slot="tip" class="el-upload__tip">仅支持 `xls`、`xlsx` 文件</div>
|
<div slot="tip" class="el-upload__tip" style="color: #F56C6C">只能上传 xls/xlsx 文件</div>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</el-card>
|
||||||
</div>
|
</el-carousel-item>
|
||||||
|
|
||||||
<div class="wizard-panel" v-if="active === 4">
|
<el-carousel-item style="padding: 10px">
|
||||||
<div class="result-panel">
|
<el-card class="result-card">
|
||||||
<el-progress type="circle" :percentage="resultPercentage" status="success"></el-progress>
|
<el-progress type="circle" :percentage="resultPercentage" :status="resultProgressStatus"></el-progress>
|
||||||
<div style="margin-top: 18px; color: #606266;">
|
<div class="result-text">{{ resultSummary }}</div>
|
||||||
共 {{ result.total || 0 }} 条,成功 {{ result.success || 0 }} 条
|
<div style="margin-top: 10px" v-if="result.cacheKey">
|
||||||
|
<el-link
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-download"
|
||||||
|
style="font-size: 13px;"
|
||||||
|
:href="loc() + '/exportErrors?cacheKey=' + result.cacheKey">
|
||||||
|
下载错误记录
|
||||||
|
</el-link>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="result.cacheKey" style="margin-top: 10px;">
|
</el-card>
|
||||||
<el-link type="primary" :href="loc() + '/exportErrors?cacheKey=' + result.cacheKey">下载错误记录</el-link>
|
</el-carousel-item>
|
||||||
</div>
|
</el-carousel>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="wizard-footer">
|
<div class="card-body-center-bottom">
|
||||||
<el-button :disabled="active === 0 || loading" @click="prevStep">上一步</el-button>
|
<el-button size="medium" @click="prev" :disabled="active === 0 || loading">上一步</el-button>
|
||||||
<el-button v-if="active < 4" type="primary" :loading="loading" @click="nextStep">下一步</el-button>
|
<el-button type="primary" size="medium" :loading="loading" @click="active < 4 ? next() : carry()">
|
||||||
<el-button v-else type="primary" @click="restart">重新开始</el-button>
|
{{ active < 4 ? primaryButtonText : "完成" }}
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -316,11 +359,16 @@ layout("/layouts/platform.html"){
|
|||||||
relation: [],
|
relation: [],
|
||||||
plugins: [],
|
plugins: [],
|
||||||
fileList: [],
|
fileList: [],
|
||||||
|
cacheTableName: "",
|
||||||
result: {
|
result: {
|
||||||
total: 0,
|
total: 0,
|
||||||
success: 0,
|
success: 0,
|
||||||
cacheKey: ""
|
cacheKey: ""
|
||||||
},
|
},
|
||||||
|
formRules: {
|
||||||
|
method: [{ required: true, message: "必填", trigger: ["blur", "change"] }],
|
||||||
|
field: [{ required: true, message: "必填", trigger: ["blur", "change"] }]
|
||||||
|
},
|
||||||
formData: {
|
formData: {
|
||||||
tableName: "",
|
tableName: "",
|
||||||
columns: [],
|
columns: [],
|
||||||
@@ -331,6 +379,29 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
primaryButtonText() {
|
||||||
|
if (this.active === 3 && this.formData.method === 3) {
|
||||||
|
return "更新"
|
||||||
|
}
|
||||||
|
return "下一步"
|
||||||
|
},
|
||||||
|
resultSummary() {
|
||||||
|
const total = this.result.total || 0
|
||||||
|
const success = this.result.success || 0
|
||||||
|
const fail = Math.max(total - success, 0)
|
||||||
|
if (fail > 0) {
|
||||||
|
return "总记录数 " + total + " 条,成功 " + success + " 条,失败 " + fail + " 条!"
|
||||||
|
}
|
||||||
|
return "总记录数 " + total + " 条,成功 " + success + " 条!"
|
||||||
|
},
|
||||||
|
resultProgressStatus() {
|
||||||
|
const total = this.result.total || 0
|
||||||
|
const success = this.result.success || 0
|
||||||
|
if (total > 0 && success < total) {
|
||||||
|
return "exception"
|
||||||
|
}
|
||||||
|
return "success"
|
||||||
|
},
|
||||||
resultPercentage() {
|
resultPercentage() {
|
||||||
if (!this.result.total) {
|
if (!this.result.total) {
|
||||||
return 0
|
return 0
|
||||||
@@ -339,6 +410,7 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
loc,
|
||||||
normalizeRecord(item) {
|
normalizeRecord(item) {
|
||||||
const normalized = {}
|
const normalized = {}
|
||||||
Object.keys(item || {}).forEach(key => {
|
Object.keys(item || {}).forEach(key => {
|
||||||
@@ -398,66 +470,75 @@ layout("/layouts/platform.html"){
|
|||||||
.filter(item => this.formData.columns.includes(item.column_name))
|
.filter(item => this.formData.columns.includes(item.column_name))
|
||||||
.map(item => Object.assign({}, item, { relation: "" }))
|
.map(item => Object.assign({}, item, { relation: "" }))
|
||||||
},
|
},
|
||||||
async nextStep() {
|
async next() {
|
||||||
if (this.active === 0) {
|
if (this.active === 0) {
|
||||||
if (!this.formData.tableName) {
|
if (!this.formData.tableName) {
|
||||||
this.$message.warning("请选择数据表")
|
this.$notify({
|
||||||
|
title: "警告",
|
||||||
|
message: "请选择数据表",
|
||||||
|
type: "warning"
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await this.loadColumns()
|
if (this.cacheTableName !== this.formData.tableName) {
|
||||||
this.formData.columns = []
|
await this.loadColumns()
|
||||||
this.formData.field = ""
|
this.formData.columns = []
|
||||||
|
this.formData.field = ""
|
||||||
|
this.cacheTableName = this.formData.tableName
|
||||||
|
}
|
||||||
} else if (this.active === 1) {
|
} else if (this.active === 1) {
|
||||||
if (!this.formData.columns.length) {
|
if (!this.formData.columns.length) {
|
||||||
this.$message.warning("请至少选择一个字段")
|
this.$notify({
|
||||||
|
title: "警告",
|
||||||
|
message: "请选择数据列",
|
||||||
|
type: "warning"
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.buildRelation()
|
this.buildRelation()
|
||||||
} else if (this.active === 2) {
|
} else if (this.active === 2) {
|
||||||
const hasEmptyRelation = this.relation.some(item => !item.relation)
|
if (this.relation.find(item => !item.relation)) {
|
||||||
if (hasEmptyRelation) {
|
this.$notify({
|
||||||
this.$message.warning("请填写所有 Excel 表头对应关系")
|
title: "警告",
|
||||||
|
message: "存在未填写的目标列",
|
||||||
|
type: "warning"
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if (this.active === 3) {
|
} else if (this.active === 3) {
|
||||||
const success = await this.submitImport()
|
const success = await this.doSubmit()
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.active += 1
|
|
||||||
|
this.$refs.carousel.next()
|
||||||
|
this.active++
|
||||||
},
|
},
|
||||||
prevStep() {
|
prev() {
|
||||||
if (this.active > 0) {
|
if (this.active <= 0) {
|
||||||
this.active -= 1
|
return
|
||||||
}
|
}
|
||||||
|
this.$refs.carousel.prev()
|
||||||
|
this.active--
|
||||||
},
|
},
|
||||||
handleFileRemove(file, fileList) {
|
validateSubmitForm() {
|
||||||
this.fileList = fileList
|
let validForm = true
|
||||||
},
|
this.$refs.form.validate(valid => {
|
||||||
handleFileChange(file, fileList) {
|
validForm = valid
|
||||||
const extension = ((file.name || "").split(".").pop() || "").toLowerCase()
|
})
|
||||||
const removeIndex = fileList.findIndex(item => item.uid === file.uid)
|
if (!validForm || !this.fileList.length) {
|
||||||
if (!["xls", "xlsx"].includes(extension)) {
|
this.$notify({
|
||||||
this.$message.warning("仅支持 xls、xlsx 文件")
|
title: "警告",
|
||||||
if (removeIndex > -1) {
|
message: "存在未填写的必填项",
|
||||||
fileList.splice(removeIndex, 1)
|
type: "warning"
|
||||||
}
|
})
|
||||||
} else if (file.size === 0) {
|
|
||||||
this.$message.warning("上传文件不能为空")
|
|
||||||
if (removeIndex > -1) {
|
|
||||||
fileList.splice(removeIndex, 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.fileList = fileList
|
|
||||||
},
|
|
||||||
async submitImport() {
|
|
||||||
if ([1, 3].includes(this.formData.method) && !this.formData.field) {
|
|
||||||
this.$message.warning("请选择关键字段")
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (!this.fileList.length) {
|
return true
|
||||||
this.$message.warning("请上传 Excel 文件")
|
},
|
||||||
|
async doSubmit() {
|
||||||
|
if (!this.validateSubmitForm()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,18 +557,45 @@ layout("/layouts/platform.html"){
|
|||||||
"Content-Type": "multipart/form-data"
|
"Content-Type": "multipart/form-data"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
if (resp.code !== 0) {
|
if (resp.code !== 0) {
|
||||||
this.$message.error(resp.msg)
|
this.$notify.error({
|
||||||
|
title: "错误",
|
||||||
|
message: resp.msg
|
||||||
|
})
|
||||||
|
this.result = { total: 0, success: 0, cacheKey: "" }
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.result = resp.data || { total: 0, success: 0, cacheKey: "" }
|
this.result = resp.data || { total: 0, success: 0, cacheKey: "" }
|
||||||
this.$message.success(resp.msg)
|
|
||||||
return true
|
return true
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false
|
this.loading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
restart() {
|
handleFileRemove(file, fileList) {
|
||||||
|
this.fileList = fileList
|
||||||
|
},
|
||||||
|
handleFileChange(file, fileList) {
|
||||||
|
const extension = ((file.name || "").split(".").pop() || "").toLowerCase()
|
||||||
|
const remove = () => {
|
||||||
|
const removeIndex = fileList.findIndex(item => item.uid === file.uid)
|
||||||
|
if (removeIndex > -1) {
|
||||||
|
fileList.splice(removeIndex, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.size === 0) {
|
||||||
|
this.$message.warning("您选择的是空文件")
|
||||||
|
remove()
|
||||||
|
} else if (!["xls", "xlsx"].includes(extension)) {
|
||||||
|
this.$message.warning("上传文件只能是 xls/xlsx 格式")
|
||||||
|
remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fileList = fileList
|
||||||
|
},
|
||||||
|
carry() {
|
||||||
this.active = 0
|
this.active = 0
|
||||||
this.tableKeyword = ""
|
this.tableKeyword = ""
|
||||||
this.columnKeyword = ""
|
this.columnKeyword = ""
|
||||||
@@ -495,6 +603,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.filteredColumns = []
|
this.filteredColumns = []
|
||||||
this.relation = []
|
this.relation = []
|
||||||
this.fileList = []
|
this.fileList = []
|
||||||
|
this.cacheTableName = ""
|
||||||
this.result = {
|
this.result = {
|
||||||
total: 0,
|
total: 0,
|
||||||
success: 0,
|
success: 0,
|
||||||
@@ -511,6 +620,7 @@ layout("/layouts/platform.html"){
|
|||||||
this.$refs.upload.clearFiles()
|
this.$refs.upload.clearFiles()
|
||||||
}
|
}
|
||||||
this.filterTables()
|
this.filterTables()
|
||||||
|
this.$refs.carousel.setActiveItem(0)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
|
|||||||
@@ -161,6 +161,12 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
|
||||||
|
<el-col :span="8">
|
||||||
|
<el-form-item label="是否推送待办事项">
|
||||||
|
<el-checkbox v-model="pushTodoFlag">是</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
|
||||||
<!-- <el-col :span="8">
|
<!-- <el-col :span="8">
|
||||||
<el-form-item prop="funding" label="经费预算">
|
<el-form-item prop="funding" label="经费预算">
|
||||||
<el-input-number style="width: 100%" v-model="formData.funding"
|
<el-input-number style="width: 100%" v-model="formData.funding"
|
||||||
@@ -586,6 +592,7 @@
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
formData: { applyWay: [] },
|
formData: { applyWay: [] },
|
||||||
|
pushTodoFlag: false,
|
||||||
unionUserNumOneKeyRatio: null,
|
unionUserNumOneKeyRatio: null,
|
||||||
summaryCount: 0,
|
summaryCount: 0,
|
||||||
unionUserNumCalc: [{ startNum: 1, endNum: 1, resultNum: 1 }],
|
unionUserNumCalc: [{ startNum: 1, endNum: 1, resultNum: 1 }],
|
||||||
@@ -941,6 +948,7 @@
|
|||||||
async openAdd() {
|
async openAdd() {
|
||||||
this.copyTemplateMode = false
|
this.copyTemplateMode = false
|
||||||
this.copyTemplateName = ""
|
this.copyTemplateName = ""
|
||||||
|
this.pushTodoFlag = false
|
||||||
this.events = await this.getEvents(2)
|
this.events = await this.getEvents(2)
|
||||||
await this.getActivityGroup()
|
await this.getActivityGroup()
|
||||||
this.active = 0
|
this.active = 0
|
||||||
@@ -1019,6 +1027,7 @@
|
|||||||
},
|
},
|
||||||
async openEdit(row, flag, copyTemplateMode = false) {
|
async openEdit(row, flag, copyTemplateMode = false) {
|
||||||
this.copyTemplateMode = !!copyTemplateMode
|
this.copyTemplateMode = !!copyTemplateMode
|
||||||
|
this.pushTodoFlag = false
|
||||||
this.active = flag ? 0 : this.active
|
this.active = flag ? 0 : this.active
|
||||||
await this.getActivityGroup()
|
await this.getActivityGroup()
|
||||||
const { id } = row
|
const { id } = row
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ layout("/layouts/platform.html"){
|
|||||||
<el-card class="mt10" shadow="never">
|
<el-card class="mt10" shadow="never">
|
||||||
<table-tool label="分工会列表">
|
<table-tool label="分工会列表">
|
||||||
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')">
|
<template v-if="$auth.hasRoleOr('SYSADMIN, SCHOOL_UNION_ADMIN')">
|
||||||
|
<el-button @click="pushUnregisteredTodo" size="small" type="primary">未报名人员推送待办</el-button>
|
||||||
<el-button @click="openImport" size="small" type="primary">导入报名人员</el-button>
|
<el-button @click="openImport" size="small" type="primary">导入报名人员</el-button>
|
||||||
<el-button @click="doExportByEnroll" size="small" type="primary">导出报名信息</el-button>
|
<el-button @click="doExportByEnroll" size="small" type="primary">导出报名信息</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -371,10 +372,6 @@ layout("/layouts/platform.html"){
|
|||||||
this.notifyWarning("请先选择活动名称")
|
this.notifyWarning("请先选择活动名称")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!this.pageForm.unionid) {
|
|
||||||
this.notifyWarning("请选择所属工会")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$downLoad(loc() + "/doExportByEnroll", {
|
this.$downLoad(loc() + "/doExportByEnroll", {
|
||||||
id: this.pageForm.id,
|
id: this.pageForm.id,
|
||||||
unionId: this.pageForm.unionid
|
unionId: this.pageForm.unionid
|
||||||
@@ -392,6 +389,9 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
pushUnregisteredTodo() {
|
||||||
|
this.$message.info("未报名人员推送待办功能开发中")
|
||||||
|
},
|
||||||
successImport() {
|
successImport() {
|
||||||
this.pageData()
|
this.pageData()
|
||||||
},
|
},
|
||||||
|
|||||||
+11
@@ -35,6 +35,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool :columns.sync="tableColumns">
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
<el-radio-button :label="true">已审核</el-radio-button>
|
<el-radio-button :label="true">已审核</el-radio-button>
|
||||||
<el-radio-button :label="false">未审核</el-radio-button>
|
<el-radio-button :label="false">未审核</el-radio-button>
|
||||||
@@ -147,6 +148,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{label: "提案编号", prop: "code"},
|
{label: "提案编号", prop: "code"},
|
||||||
|
{label: "立案编号", prop: "caseFilingCode"},
|
||||||
{label: "提案名称", prop: "name", width: "200px"},
|
{label: "提案名称", prop: "name", width: "200px"},
|
||||||
{label: "提案人", prop: "createUserName", width: "80px"},
|
{label: "提案人", prop: "createUserName", width: "80px"},
|
||||||
{label: "提案类别", prop: "typeName"},
|
{label: "提案类别", prop: "typeName"},
|
||||||
@@ -172,6 +174,15 @@ layout("/layouts/platform.html"){
|
|||||||
this.listUnion()
|
this.listUnion()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
openView(row) {
|
openView(row) {
|
||||||
this.$refs.guava.edit(() => {
|
this.$refs.guava.edit(() => {
|
||||||
this.showApprovalForm = false
|
this.showApprovalForm = false
|
||||||
|
|||||||
+11
@@ -59,6 +59,7 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool :columns.sync="tableColumns">
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<el-button type="primary" icon="el-icon-plus" size="small" @click="openMerge">并案审核</el-button>
|
<el-button type="primary" icon="el-icon-plus" size="small" @click="openMerge">并案审核</el-button>
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
<el-radio-button :label="true">已审核</el-radio-button>
|
<el-radio-button :label="true">已审核</el-radio-button>
|
||||||
@@ -200,6 +201,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{ label: "提案编号", prop: "code" },
|
{ label: "提案编号", prop: "code" },
|
||||||
|
{ label: "立案编号", prop: "caseFilingCode" },
|
||||||
{ label: "提案名称", prop: "name", width: "200px" },
|
{ label: "提案名称", prop: "name", width: "200px" },
|
||||||
{ label: "提案类别", prop: "typeName" },
|
{ label: "提案类别", prop: "typeName" },
|
||||||
{ label: "届次", prop: "sessionName" },
|
{ label: "届次", prop: "sessionName" },
|
||||||
@@ -229,6 +231,15 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* “作为建议”不再区分主办/协办,只保留办理单位;
|
* “作为建议”不再区分主办/协办,只保留办理单位;
|
||||||
* 切到“不予立案”等结果时,同时清空已选单位,避免旧值被误提交。
|
* 切到“不予立案”等结果时,同时清空已选单位,避免旧值被误提交。
|
||||||
|
|||||||
+11
@@ -59,6 +59,7 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool :columns.sync="tableColumns">
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<!-- <el-button type="primary" icon="el-icon-plus" size="small" @click="openMerge">并案审核</el-button>-->
|
<!-- <el-button type="primary" icon="el-icon-plus" size="small" @click="openMerge">并案审核</el-button>-->
|
||||||
<!-- <el-button type="primary" icon="el-icon-plus" size="small" @click="doUpData">更新</el-button>-->
|
<!-- <el-button type="primary" icon="el-icon-plus" size="small" @click="doUpData">更新</el-button>-->
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
@@ -208,6 +209,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{label: "提案编号", prop: "code"},
|
{label: "提案编号", prop: "code"},
|
||||||
|
{label: "立案编号", prop: "caseFilingCode"},
|
||||||
{label: "提案名称", prop: "name", width: "200px"},
|
{label: "提案名称", prop: "name", width: "200px"},
|
||||||
{label: "提案类别", prop: "typeName"},
|
{label: "提案类别", prop: "typeName"},
|
||||||
{label: "届次", prop: "sessionName"},
|
{label: "届次", prop: "sessionName"},
|
||||||
@@ -231,6 +233,15 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* “作为建议”场景下只保留办理单位,协办单位和立案类型都要及时清空,
|
* “作为建议”场景下只保留办理单位,协办单位和立案类型都要及时清空,
|
||||||
* 避免旧表单值跟着一起提交到流程里。
|
* 避免旧表单值跟着一起提交到流程里。
|
||||||
|
|||||||
+11
@@ -25,6 +25,7 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool :columns.sync="tableColumns">
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
<el-radio-button :label="true">已审核</el-radio-button>
|
<el-radio-button :label="true">已审核</el-radio-button>
|
||||||
<el-radio-button :label="false">未审核</el-radio-button>
|
<el-radio-button :label="false">未审核</el-radio-button>
|
||||||
@@ -107,6 +108,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{label: "提案编号", prop: "code"},
|
{label: "提案编号", prop: "code"},
|
||||||
|
{label: "立案编号", prop: "caseFilingCode"},
|
||||||
{label: "提案名称", prop: "name", width: "200px"},
|
{label: "提案名称", prop: "name", width: "200px"},
|
||||||
{label: "提案人", prop: "createUserName", width: "80px"},
|
{label: "提案人", prop: "createUserName", width: "80px"},
|
||||||
{label: "提案类别", prop: "typeName"},
|
{label: "提案类别", prop: "typeName"},
|
||||||
@@ -122,6 +124,15 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
openView(row) {
|
openView(row) {
|
||||||
this.$refs.guava.edit(() => {
|
this.$refs.guava.edit(() => {
|
||||||
this.showApprovalForm = false
|
this.showApprovalForm = false
|
||||||
|
|||||||
+12
-1
@@ -25,7 +25,8 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool>
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
<el-radio-button :label="true">已审核</el-radio-button>
|
<el-radio-button :label="true">已审核</el-radio-button>
|
||||||
<el-radio-button :label="false">未审核</el-radio-button>
|
<el-radio-button :label="false">未审核</el-radio-button>
|
||||||
@@ -119,6 +120,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{label: "提案编号", prop: "code"},
|
{label: "提案编号", prop: "code"},
|
||||||
|
{label: "立案编号", prop: "caseFilingCode"},
|
||||||
{label: "提案名称", prop: "name", width: "200px"},
|
{label: "提案名称", prop: "name", width: "200px"},
|
||||||
{label: "提案类别", prop: "typeName"},
|
{label: "提案类别", prop: "typeName"},
|
||||||
{label: "是否并案", prop: "merge"},
|
{label: "是否并案", prop: "merge"},
|
||||||
@@ -135,6 +137,15 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
openView(row) {
|
openView(row) {
|
||||||
this.$refs.guava.edit(() => {
|
this.$refs.guava.edit(() => {
|
||||||
this.showApprovalForm = false
|
this.showApprovalForm = false
|
||||||
|
|||||||
+11
@@ -36,6 +36,7 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool :columns.sync="tableColumns">
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
<el-radio-button :label="true">已审核</el-radio-button>
|
<el-radio-button :label="true">已审核</el-radio-button>
|
||||||
<el-radio-button :label="false">未审核</el-radio-button>
|
<el-radio-button :label="false">未审核</el-radio-button>
|
||||||
@@ -111,6 +112,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{label: "提案编号", prop: "code"},
|
{label: "提案编号", prop: "code"},
|
||||||
|
{label: "立案编号", prop: "caseFilingCode"},
|
||||||
{label: "提案名称", prop: "name", width: "200px"},
|
{label: "提案名称", prop: "name", width: "200px"},
|
||||||
{label: "提案人", prop: "createUserName", width: "80px"},
|
{label: "提案人", prop: "createUserName", width: "80px"},
|
||||||
{label: "提案类别", prop: "typeName"},
|
{label: "提案类别", prop: "typeName"},
|
||||||
@@ -134,6 +136,15 @@ layout("/layouts/platform.html"){
|
|||||||
this.listUnion()
|
this.listUnion()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
openView(row) {
|
openView(row) {
|
||||||
this.$refs.guava.edit(() => {
|
this.$refs.guava.edit(() => {
|
||||||
this.showApprovalForm = false
|
this.showApprovalForm = false
|
||||||
|
|||||||
+12
-1
@@ -58,7 +58,8 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool>
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
<el-radio-button :label="true">已审核</el-radio-button>
|
<el-radio-button :label="true">已审核</el-radio-button>
|
||||||
<el-radio-button :label="false">未审核</el-radio-button>
|
<el-radio-button :label="false">未审核</el-radio-button>
|
||||||
@@ -145,6 +146,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{label: "提案编号", prop: "code"},
|
{label: "提案编号", prop: "code"},
|
||||||
|
{label: "立案编号", prop: "caseFilingCode"},
|
||||||
{label: "提案名称", prop: "name", width: "200px"},
|
{label: "提案名称", prop: "name", width: "200px"},
|
||||||
{label: "提案类别", prop: "typeName"},
|
{label: "提案类别", prop: "typeName"},
|
||||||
{label: "办理单位", prop: "undertakeUnits", width: "260px"},
|
{label: "办理单位", prop: "undertakeUnits", width: "260px"},
|
||||||
@@ -164,6 +166,15 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* 校领导审批列表需要按立案结果切换办理单位展示口径:
|
* 校领导审批列表需要按立案结果切换办理单位展示口径:
|
||||||
* 确定立案显示主办/协办,作为建议只显示办理单位。
|
* 确定立案显示主办/协办,作为建议只显示办理单位。
|
||||||
|
|||||||
+11
@@ -97,6 +97,7 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<el-card shadow="never">
|
<el-card shadow="never">
|
||||||
<table-tool :columns.sync="tableColumns">
|
<table-tool :columns.sync="tableColumns">
|
||||||
|
<el-button type="primary" size="small" @click="exportList">导出</el-button>
|
||||||
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
<el-radio-group v-model="pageForm.approval" size="small" @change="doSearch">
|
||||||
<el-radio-button :label="true">已审核</el-radio-button>
|
<el-radio-button :label="true">已审核</el-radio-button>
|
||||||
<el-radio-button :label="false">未审核</el-radio-button>
|
<el-radio-button :label="false">未审核</el-radio-button>
|
||||||
@@ -288,6 +289,7 @@ layout("/layouts/platform.html"){
|
|||||||
return {
|
return {
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{label: "提案编号", prop: "code"},
|
{label: "提案编号", prop: "code"},
|
||||||
|
{label: "立案编号", prop: "caseFilingCode"},
|
||||||
{label: "提案名称", prop: "name", width: "200px"},
|
{label: "提案名称", prop: "name", width: "200px"},
|
||||||
{label: "提案类别", prop: "typeName"},
|
{label: "提案类别", prop: "typeName"},
|
||||||
{label: "立案结果", prop: "caseFilingResult"},
|
{label: "立案结果", prop: "caseFilingResult"},
|
||||||
@@ -319,6 +321,15 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportList() {
|
||||||
|
this.$downLoad(loc() + "/exportList", {
|
||||||
|
pageForm: JSON.stringify(this.pageForm),
|
||||||
|
approval: this.pageForm.approval,
|
||||||
|
tableColumns: JSON.stringify(this.tableColumns.filter(function (item) {
|
||||||
|
return item.visible !== false
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
},
|
||||||
openView(row) {
|
openView(row) {
|
||||||
this.$refs.guava.edit(() => {
|
this.$refs.guava.edit(() => {
|
||||||
this.showApprovalForm = false
|
this.showApprovalForm = false
|
||||||
|
|||||||
+58
-141
@@ -2,74 +2,47 @@ const BASIC_TABLE_COMPONENT = {
|
|||||||
template: `
|
template: `
|
||||||
<div>
|
<div>
|
||||||
<el-row type="flex">
|
<el-row type="flex">
|
||||||
<el-col></el-col>
|
<el-col></el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<table-tool>
|
<table-tool>
|
||||||
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd()">新建机构</el-button>
|
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd()">新建机构</el-button>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
<el-table key="1" :data="tableData" ref="tableRef">
|
<el-table key="1" :data="tableData" ref="tableRef">
|
||||||
<el-table-column label="序号" width="100px" type="index" :index="indexMethod"></el-table-column>
|
<el-table-column label="序号" width="100px" type="index" :index="indexMethod"></el-table-column>
|
||||||
<el-table-column prop="name" label="机构名称"></el-table-column>
|
<el-table-column prop="name" label="机构名称"></el-table-column>
|
||||||
<el-table-column prop="code" label="机构代码"></el-table-column>
|
<el-table-column prop="introduce" label="描述"></el-table-column>
|
||||||
<el-table-column prop="introduce" label="描述" min-width="220px">
|
<el-table-column label="操作" width="100px">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<div class="institution-description">{{row.introduce}}</div>
|
<el-link size="mini" type="danger" @click="del(row.id)">删除</el-link>
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作" width="140px">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<template>
|
|
||||||
<el-link size="mini" type="primary" @click="openEdit(scope.row)">修改</el-link>
|
|
||||||
</template>
|
|
||||||
<el-divider direction="vertical"></el-divider>
|
|
||||||
<el-tooltip v-if="isBasicInstitution(scope.$index)"
|
|
||||||
content="你选择的组织机构是两代会基本机构,不允许删除。"
|
|
||||||
placement="top">
|
|
||||||
<span class="disabled-delete-link">删除</span>
|
|
||||||
</el-tooltip>
|
|
||||||
<el-link v-else size="mini" type="danger" @click="del(scope.row.id)">删除</el-link>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<el-dialog :visible.sync="dialogFormVisible" :title="isEdit ? '编辑' : '新增'" width="40%">
|
<el-dialog :visible.sync="dialogFormVisible" :title="formData.id?'编辑':'新增'" width="40%">
|
||||||
<el-form :model="formData" ref="formRef" :rules="rules" label-width="100px">
|
<el-form :model="formData" ref="formRef" :rules="rules" label-width="100px">
|
||||||
<template v-if="!isEdit">
|
<el-form-item label="机构名称" prop="ids">
|
||||||
<el-form-item label="机构名称" prop="institutionPath">
|
<el-cascader
|
||||||
<el-cascader
|
v-model="ids"
|
||||||
v-model="formData.institutionPath"
|
:options="treeList"
|
||||||
:options="treeList"
|
:props="props"
|
||||||
:props="cascaderProps"
|
@change="parentChange"
|
||||||
@change="institutionChange"
|
placeholder="请选择机构"
|
||||||
placeholder="请选择机构"
|
style="width: 100%"
|
||||||
style="width: 100%"
|
></el-cascader>
|
||||||
></el-cascader>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="机构代码" prop="code">
|
||||||
<el-form-item label="机构代码">
|
<el-input placeholder="请输入机构代码" v-model="formData.code" disabled></el-input>
|
||||||
<el-input :value="formData.code" disabled placeholder="选择机构后自动带出"></el-input>
|
</el-form-item>
|
||||||
</el-form-item>
|
<el-form-item label="描述" prop="introduce">
|
||||||
</template>
|
<el-input v-model="formData.introduce" placeholder="请输入描述"></el-input>
|
||||||
<template v-else>
|
</el-form-item>
|
||||||
<el-form-item label="上级机构名称">
|
<el-form-item label="备注" prop="notes">
|
||||||
<el-input :value="parentName || '-'" disabled></el-input>
|
<el-input v-model="formData.notes" placeholder="请输入备注"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="机构名称" prop="name">
|
</el-form>
|
||||||
<el-input placeholder="请输入机构名称" v-model="formData.name"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="机构代码" prop="code">
|
|
||||||
<el-input placeholder="请输入机构代码" v-model="formData.code" disabled></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
<el-form-item label="排序编码" prop="location">
|
|
||||||
<el-input-number v-model="formData.location" :min="0" :step="1" style="width: 100%"></el-input-number>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="描述" prop="introduce">
|
|
||||||
<el-input v-model="formData.introduce" placeholder="请输入描述"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<div slot="footer" class="dialog-footer">
|
<div slot="footer" class="dialog-footer">
|
||||||
<el-button @click="dialogFormVisible = false">取消</el-button>
|
<el-button @click="dialogFormVisible = false">取 消</el-button>
|
||||||
<el-button type="primary" @click="doSubmit">确定</el-button>
|
<el-button type="primary" @click="doSubmit">确 定</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,33 +56,27 @@ const BASIC_TABLE_COMPONENT = {
|
|||||||
parentId: {
|
parentId: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true
|
||||||
},
|
|
||||||
parentName: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
rules: {
|
rules: {
|
||||||
institutionPath: [{ type: "array", required: true, message: "请选择机构", trigger: "change" }],
|
|
||||||
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
name: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
code: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
parentId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
parentId: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
|
||||||
location: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
|
|
||||||
},
|
},
|
||||||
parentData: {},
|
parentData: {},
|
||||||
parentIds: [],
|
parentIds: [],
|
||||||
|
ids: [],
|
||||||
treeList: [],
|
treeList: [],
|
||||||
treeFlat: [],
|
treeFlat: [],
|
||||||
cascaderProps: {
|
props: {
|
||||||
checkStrictly: true,
|
checkStrictly: true,
|
||||||
multiple: false,
|
multiple: false,
|
||||||
label: "name",
|
label: "name",
|
||||||
value: "id"
|
value: "id"
|
||||||
},
|
},
|
||||||
dialogFormVisible: false,
|
dialogFormVisible: false
|
||||||
isEdit: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -128,75 +95,38 @@ const BASIC_TABLE_COMPONENT = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
openAdd() {
|
openAdd() {
|
||||||
this.isEdit = false
|
|
||||||
this.dialogFormVisible = true
|
this.dialogFormVisible = true
|
||||||
this.formData = {
|
this.formData = {}
|
||||||
institutionPath: [],
|
this.ids = []
|
||||||
parentId: this.parentId,
|
$.post("/platform/teacherCongress/institution/formTree", { sessionId: this.sessionId }).then((res) => {
|
||||||
location: 0
|
|
||||||
}
|
|
||||||
this.listFormTree()
|
|
||||||
},
|
|
||||||
openEdit(row) {
|
|
||||||
this.isEdit = true
|
|
||||||
this.dialogFormVisible = true
|
|
||||||
this.formData = {
|
|
||||||
...row,
|
|
||||||
location: row.location || 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* 加载“双代会固定机构”字典树,新增机构只能从该树中选择。
|
|
||||||
* 接口返回 treeList 用于级联展示,treeFlat 用于按所选字典ID回填名称和代码。
|
|
||||||
*/
|
|
||||||
listFormTree() {
|
|
||||||
this.$axios.post("/platform/teacherCongress/institution/formTree", {
|
|
||||||
sessionId: this.sessionId
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.treeList = res.data.treeList || []
|
this.treeList = res.data.treeList
|
||||||
this.treeFlat = res.data.treeFlat || []
|
this.treeFlat = res.data.treeFlat
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
/**
|
// 上级机构选择变化
|
||||||
* 固定机构选择变化后回填业务名称和机构代码;清空选择时同步清空旧值。
|
parentChange(val) {
|
||||||
*/
|
const id = val[val.length - 1]
|
||||||
institutionChange(institutionPath) {
|
const tree = this.treeFlat.find((tree) => tree.id === id)
|
||||||
const institutionId = institutionPath.length ? institutionPath[institutionPath.length - 1] : null
|
this.$set(this.formData, "code", tree?.code)
|
||||||
const institution = this.treeFlat.find(item => item.id === institutionId)
|
this.$set(this.formData, "name", tree?.name)
|
||||||
this.$set(this.formData, "name", institution ? institution.name : "")
|
|
||||||
this.$set(this.formData, "code", institution ? institution.code : "")
|
|
||||||
},
|
|
||||||
isBasicInstitution(index) {
|
|
||||||
const pageNumber = this.pageForm.pageNumber || 1
|
|
||||||
const pageSize = this.pageForm.pageSize || 10
|
|
||||||
return (pageNumber - 1) * pageSize + index < 6
|
|
||||||
},
|
},
|
||||||
doSubmit() {
|
doSubmit() {
|
||||||
this.$refs.formRef.validate((valid) => {
|
this.$refs.formRef.validate((valid) => {
|
||||||
if (!valid) {
|
this.formData.id = this.ids[this.ids.length - 1]
|
||||||
return
|
this.formData.parentId = this.ids[this.ids.length - 2] || this.parentId
|
||||||
|
this.formData.sessionId = this.sessionId
|
||||||
|
if (valid) {
|
||||||
|
this.$axios.post(loc() + "/insert", this.formData).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.dialogFormVisible = false
|
||||||
|
this.$message.success(res.msg)
|
||||||
|
this.doSearch()
|
||||||
|
this.$emit("refresh", null)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const params = {
|
|
||||||
...this.formData,
|
|
||||||
sessionId: this.sessionId
|
|
||||||
}
|
|
||||||
if (!this.isEdit) {
|
|
||||||
const institutionPath = this.formData.institutionPath || []
|
|
||||||
// 下级机构先提交固定字典中的父级ID,由后端转换为当前届次的实际父机构ID。
|
|
||||||
params.parentId = institutionPath.length > 1 ? institutionPath[institutionPath.length - 2] : this.parentId
|
|
||||||
delete params.institutionPath
|
|
||||||
}
|
|
||||||
const url = this.isEdit ? loc() + "/update" : loc() + "/insert"
|
|
||||||
this.$axios.post(url, params).then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.dialogFormVisible = false
|
|
||||||
this.$message.success(res.msg)
|
|
||||||
this.doSearch()
|
|
||||||
this.$emit("refresh", null)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -215,18 +145,5 @@ const BASIC_TABLE_COMPONENT = {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
style: /*language=CSS*/ `
|
|
||||||
.institution-description {
|
|
||||||
white-space: pre-wrap;
|
|
||||||
word-break: break-word;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.disabled-delete-link {
|
|
||||||
color: #c0c4cc;
|
|
||||||
cursor: not-allowed;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-41
@@ -9,27 +9,21 @@ layout("/layouts/platform.html"){
|
|||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="19">
|
<el-col :span="19">
|
||||||
<el-card shadow="never" style="height: 100%">
|
<el-card shadow="never" style="height: 100%">
|
||||||
<el-tabs v-model="activeTab" @tab-click="handleTabClick">
|
<template>
|
||||||
<el-tab-pane v-if="hasChildInstitution" label="机构列表" name="institution">
|
<basic-table
|
||||||
<basic-table
|
:session-id="sessionId"
|
||||||
:session-id="sessionId"
|
:parent-id="currentTreeData.id"
|
||||||
:parent-id="currentTreeData && currentTreeData.id"
|
v-if="showInstitutionTable || (currentTreeData && currentTreeData.id==='0')"
|
||||||
:parent-name="currentTreeData && currentTreeData.name"
|
ref="basicTableRef"
|
||||||
v-if="activeTab === 'institution' && sessionId && currentTreeData"
|
@refresh="$refs.treeRef.listTree()"
|
||||||
ref="basicTableRef"
|
></basic-table>
|
||||||
@refresh="refreshTree"
|
</template>
|
||||||
></basic-table>
|
<user-table
|
||||||
</el-tab-pane>
|
:session-id="sessionId"
|
||||||
<el-tab-pane label="人员列表" name="user">
|
:institution-id="currentTreeData.id"
|
||||||
<user-table
|
ref="userTableRef"
|
||||||
:session-id="sessionId"
|
v-if="!showInstitutionTable && sessionId"
|
||||||
:institution-id="currentTreeData && currentTreeData.id"
|
></user-table>
|
||||||
:institution-code="currentTreeData && currentTreeData.code"
|
|
||||||
ref="userTableRef"
|
|
||||||
v-if="activeTab === 'user' && sessionId && currentTreeData"
|
|
||||||
></user-table>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</el-card>
|
</el-card>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
@@ -49,17 +43,16 @@ layout("/layouts/platform.html"){
|
|||||||
"basic-table": BASIC_TABLE_COMPONENT
|
"basic-table": BASIC_TABLE_COMPONENT
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
// 根节点即使尚无子机构也要展示机构列表,确保空届次可以创建第一条机构。
|
showInstitutionTable() {
|
||||||
hasChildInstitution() {
|
const hasChildren = this.currentTreeData?.children?.length > 0
|
||||||
return this.currentTreeData && (this.currentTreeData.id === "0" || (this.currentTreeData.children && this.currentTreeData.children.length > 0))
|
return hasChildren
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
currentTreeNode: null,
|
currentTreeNode: null,
|
||||||
currentTreeData: null,
|
currentTreeData: null,
|
||||||
sessionId: null,
|
sessionId: null
|
||||||
activeTab: "institution"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -67,28 +60,14 @@ layout("/layouts/platform.html"){
|
|||||||
this.currentTreeData = data
|
this.currentTreeData = data
|
||||||
this.currentTreeNode = node
|
this.currentTreeNode = node
|
||||||
this.sessionId = sessionId
|
this.sessionId = sessionId
|
||||||
if (this.hasChildInstitution) {
|
|
||||||
this.activeTab = "institution"
|
|
||||||
} else if (this.activeTab === "institution") {
|
|
||||||
this.activeTab = "user"
|
|
||||||
}
|
|
||||||
this.refreshActiveTab()
|
|
||||||
},
|
|
||||||
handleTabClick() {
|
|
||||||
this.refreshActiveTab()
|
|
||||||
},
|
|
||||||
refreshActiveTab() {
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
if (this.activeTab === "institution") {
|
if (this.showInstitutionTable) {
|
||||||
this.$refs.basicTableRef && this.$refs.basicTableRef.doSearch()
|
this.$refs.basicTableRef && this.$refs.basicTableRef.doSearch()
|
||||||
} else {
|
} else {
|
||||||
this.$refs.userTableRef && this.$refs.userTableRef.doSearch()
|
this.$refs.userTableRef && this.$refs.userTableRef.doSearch()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
refreshTree() {
|
|
||||||
this.$refs.treeRef.listTree(this.currentTreeData && this.currentTreeData.id)
|
|
||||||
},
|
|
||||||
openEdit(row) {}
|
openEdit(row) {}
|
||||||
},
|
},
|
||||||
created() {}
|
created() {}
|
||||||
|
|||||||
+2
-21
@@ -46,30 +46,11 @@ const TREE_COMPONENT = {
|
|||||||
this.$emit("node-click", data, node, this.sessionId)
|
this.$emit("node-click", data, node, this.sessionId)
|
||||||
},
|
},
|
||||||
filterNode() {},
|
filterNode() {},
|
||||||
findTreeNode(list, id) {
|
listTree() {
|
||||||
if (!id || !list) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
for (const item of list) {
|
|
||||||
if (item.id === id) {
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
const child = this.findTreeNode(item.children, id)
|
|
||||||
if (child) {
|
|
||||||
return child
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
listTree(selectedId) {
|
|
||||||
this.$axios.post("/platform/teacherCongress/institution/leftTree", { sessionId: this.sessionId }).then((res) => {
|
this.$axios.post("/platform/teacherCongress/institution/leftTree", { sessionId: this.sessionId }).then((res) => {
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
this.treeData = res.data
|
this.treeData = res.data
|
||||||
if (this.treeData && this.treeData.length > 0) {
|
this.$emit("node-click", this.treeData[0], null, this.sessionId)
|
||||||
this.treeData[0].name = "两代会组织机构"
|
|
||||||
}
|
|
||||||
const selectedNode = this.findTreeNode(this.treeData, selectedId) || this.treeData[0]
|
|
||||||
this.$emit("node-click", selectedNode, null, this.sessionId)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|||||||
+35
-74
@@ -3,73 +3,58 @@ const USER_TABLE_COMPONENT = {
|
|||||||
<div>
|
<div>
|
||||||
<el-card shadow="never" style="height: 100%">
|
<el-card shadow="never" style="height: 100%">
|
||||||
<el-row type="flex" :gutter="20">
|
<el-row type="flex" :gutter="20">
|
||||||
<el-col :span="4">
|
<el-col :span="4">
|
||||||
<el-input v-model="pageForm.searchKeyword"
|
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入姓名或者工号">" @keyup.enter.native="doSearch">
|
||||||
clearable
|
</el-input>
|
||||||
placeholder="请输入姓名或者工号"
|
</el-col>
|
||||||
@keyup.enter.native="doSearch">
|
<el-col :span="4">
|
||||||
</el-input>
|
<div class="search-query">
|
||||||
</el-col>
|
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
||||||
<el-col :span="4">
|
</div>
|
||||||
<div class="search-query">
|
</el-col>
|
||||||
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
|
||||||
</div>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-divider class="mb10 mt10"></el-divider>
|
<el-divider class="mb10 mt10"></el-divider>
|
||||||
<table-tool>
|
<table-tool>
|
||||||
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd()">设置人员</el-button>
|
<el-button type="primary" size="small" icon="el-icon-plus" @click="openAdd()">设置人员</el-button>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
<el-table key="1" :data="tableData" ref="tableRef">
|
<el-table key="1" :data="tableData" ref="tableRef">
|
||||||
<el-table-column label="序号" width="100px" type="index" :index="indexMethod"></el-table-column>
|
<el-table-column label="序号" width="100px" type="index" :index="indexMethod"></el-table-column>
|
||||||
<el-table-column prop="username" label="姓名"></el-table-column>
|
<el-table-column prop="username" label="姓名"></el-table-column>
|
||||||
<el-table-column prop="loginname" label="工号"></el-table-column>
|
<el-table-column prop="loginname" label="工号"></el-table-column>
|
||||||
<el-table-column prop="sex" label="性别"></el-table-column>
|
<el-table-column prop="sex" label="性别"></el-table-column>
|
||||||
<el-table-column prop="mobile" label="手机号码"></el-table-column>
|
<el-table-column prop="mobile" label="手机号码"></el-table-column>
|
||||||
<el-table-column prop="unitName" label="单位" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="unitName" label="单位" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column prop="identity" label="身份" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="identity" label="身份" show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column label="操作" width="100px">
|
<el-table-column label="操作" width="100px">
|
||||||
<template slot-scope="{row}">
|
<template slot-scope="{row}">
|
||||||
<el-link size="mini" type="danger" @click="del(row.id)">删除</el-link>
|
<el-link size="mini" type="danger" @click="del(row.id)">删除</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<!--#include("/layouts/pagination.html"){}#-->
|
<!--#include("/layouts/pagination.html"){}#-->
|
||||||
</el-card>
|
</el-card>
|
||||||
<el-dialog title="设置人员" width="50%" :visible.sync="dialogVisible">
|
<el-dialog title="设置人员" width="50%" :visible.sync="dialogVisible">
|
||||||
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules">
|
<el-form :model="formData" ref="formRef" label-width="120px" :rules="formRules">
|
||||||
<el-form-item label="届次" prop="sessionId">
|
<el-form-item label="届次" prop="sessionId">
|
||||||
<el-select v-model="formData.sessionId" disabled>
|
<el-select v-model="formData.sessionId" disabled>
|
||||||
<el-option v-for="i in sessionOptions" :label="i.fullName" :value="i.id" :key="i.id"></el-option>
|
<el-option v-for="i in sessionOptions" :label="i.fullName" :value="i.id" :key="i.id"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item v-if="needRole" label="角色" prop="roleCode">
|
<el-form-item label="工号或姓名" prop="userId">
|
||||||
<el-select v-model="formData.roleCode" placeholder="请选择角色" style="width: 100%">
|
|
||||||
<el-option v-for="item in roleOptions"
|
|
||||||
:key="item.code"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.code">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="工号或者姓名" prop="userId">
|
|
||||||
<user-select
|
<user-select
|
||||||
v-model="formData.userId"
|
v-model="formData.userId"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
api_input_key_name="query"
|
api_input_key_name="query"
|
||||||
:option_label_func="(item)=>{return item.username + item.loginname}"
|
:option_label_func="(item)=>{return item.username + item.loginname}"
|
||||||
></user-select>
|
></user-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="身份" prop="identity">
|
<el-form-item label="身份" prop="identity">
|
||||||
<dict-select v-model="formData.identity" code="TEACHER_CONGRESS_INSTITUTION_USER_ROLE"></dict-select>
|
<dict-select v-model="formData.identity" code="TEACHER_CONGRESS_INSTITUTION_USER_ROLE"></dict-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<div style="color: #e6a23c; line-height: 22px; margin: 0 0 12px 120px;">
|
<div slot="footer" class="dialog-footer">
|
||||||
注意:如果需要跟角色绑定,请在数据字典双代会组织机构中添加对应的角色标识。
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
</div>
|
<el-button type="primary" @click="doSubmit">确 定</el-button>
|
||||||
<div slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="doSubmit">确定</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -83,10 +68,6 @@ const USER_TABLE_COMPONENT = {
|
|||||||
institutionId: {
|
institutionId: {
|
||||||
required: true,
|
required: true,
|
||||||
type: String
|
type: String
|
||||||
},
|
|
||||||
institutionCode: {
|
|
||||||
type: String,
|
|
||||||
default: ""
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
@@ -94,17 +75,10 @@ const USER_TABLE_COMPONENT = {
|
|||||||
formRules: {
|
formRules: {
|
||||||
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
sessionId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
userId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
userId: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
||||||
identity: [{ required: true, message: "必填", trigger: ["change", "blur"] }],
|
identity: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
|
||||||
roleCode: [{ required: true, message: "必填", trigger: ["change", "blur"] }]
|
|
||||||
},
|
},
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
sessionOptions: [],
|
sessionOptions: []
|
||||||
roleOptions: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
needRole() {
|
|
||||||
return ["ZWH001", "ZXWYH", "DBZGSCXZ"].includes(this.institutionCode)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -162,18 +136,6 @@ const USER_TABLE_COMPONENT = {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
listRoleOptions() {
|
|
||||||
if (!this.needRole) {
|
|
||||||
this.roleOptions = []
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$axios.post("/platform/teacherCongress/institution/specialCommitteeRoleOptions").then((res) => {
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.roleOptions = res.data || []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
openAdd() {
|
openAdd() {
|
||||||
this.dialogVisible = true
|
this.dialogVisible = true
|
||||||
this.formData = {
|
this.formData = {
|
||||||
@@ -181,7 +143,6 @@ const USER_TABLE_COMPONENT = {
|
|||||||
institutionId: this.institutionId
|
institutionId: this.institutionId
|
||||||
}
|
}
|
||||||
this.listSession()
|
this.listSession()
|
||||||
this.listRoleOptions()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -36,10 +36,10 @@
|
|||||||
code="USER_PREPARED_BY_TYPE" multiple collapse-tags></dict-select>
|
code="USER_PREPARED_BY_TYPE" multiple collapse-tags></dict-select>
|
||||||
</search-item>
|
</search-item>
|
||||||
-->
|
-->
|
||||||
<search-item label="人员分类">
|
<!-- <search-item label="人员分类">
|
||||||
<dict-select v-model="pageForm.aidFundMemberUserType" code="AIDFUND_MEMBER_USER_TYPE"
|
<dict-select v-model="pageForm.aidFundMemberUserType" code="AIDFUND_MEMBER_USER_TYPE"
|
||||||
style="width: 100%"></dict-select>
|
style="width: 100%"></dict-select>
|
||||||
</search-item>
|
</search-item>-->
|
||||||
<search-item label="人员属性">
|
<search-item label="人员属性">
|
||||||
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes" code="USER_ATTRIBUTE"
|
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes" code="USER_ATTRIBUTE"
|
||||||
multiple collapse-tags clearable style="width: 100%"></dict-select>
|
multiple collapse-tags clearable style="width: 100%"></dict-select>
|
||||||
|
|||||||
+2
-2
@@ -25,10 +25,10 @@
|
|||||||
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
|
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
|
||||||
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
|
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
|
||||||
</search-item>
|
</search-item>
|
||||||
<search-item label="人员分类">
|
<!-- <search-item label="人员分类">
|
||||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||||
</search-item>
|
</search-item>-->
|
||||||
<search-item label="人员属性">
|
<search-item label="人员属性">
|
||||||
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes"
|
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes"
|
||||||
placeholder="请选择人员属性" @change="doSearch" code="USER_ATTRIBUTE"
|
placeholder="请选择人员属性" @change="doSearch" code="USER_ATTRIBUTE"
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ layout("/layouts/platform.html"){
|
|||||||
v-for="item in changeTypeData"></el-option>
|
v-for="item in changeTypeData"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</search-item>
|
</search-item>
|
||||||
<search-item label="人员分类">
|
<!--<search-item label="人员分类">
|
||||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||||
</search-item>
|
</search-item>-->
|
||||||
<search-item label="人员属性">
|
<search-item label="人员属性">
|
||||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||||
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
||||||
|
|||||||
+2
-2
@@ -39,10 +39,10 @@
|
|||||||
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
|
<dict-select v-model="pageForm.personTypes" placeholder="请选择人员类型" @change="doSearch"
|
||||||
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
|
code="USER_PERSON_TYPE" multiple collapse-tags></dict-select>
|
||||||
</search-item>
|
</search-item>
|
||||||
<search-item label="人员分类">
|
<!--<search-item label="人员分类">
|
||||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||||
</search-item>
|
</search-item>-->
|
||||||
<search-item label="人员属性">
|
<search-item label="人员属性">
|
||||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||||
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
||||||
|
|||||||
Reference in New Issue
Block a user