整改单位
移植生日祝福 移植拉取人员 移植拉取单位
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package com.budwk.app.base.config;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.ioc.impl.PropertiesProxy;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
@@ -16,7 +15,6 @@ import java.util.Map;
|
||||
* @Date 2025/9/15 15:34
|
||||
* @注释 数据中心配置文件,存放接口地址和参数配置
|
||||
*/
|
||||
@Slf4j
|
||||
@Data
|
||||
@IocBean(create = "init")
|
||||
public class DataCenterProperties {
|
||||
@@ -24,16 +22,14 @@ public class DataCenterProperties {
|
||||
@Inject
|
||||
private PropertiesProxy conf;
|
||||
|
||||
private String tokenUrl;
|
||||
private String key;
|
||||
private String secret;
|
||||
private String appId;
|
||||
private String appSecret;
|
||||
private Map<String, String> urls = new HashMap<>();
|
||||
|
||||
public void init() {
|
||||
Map<String, String> all = conf.toMap();
|
||||
tokenUrl = all.get("data-center.token-url");
|
||||
key = all.get("data-center.key");
|
||||
secret = all.get("data-center.secret");
|
||||
appId = all.get("data-center.app-id");
|
||||
appSecret = all.get("data-center.app-secret");
|
||||
extract(all, "data-center.urls.", urls);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@ import java.util.Map;
|
||||
@At("/platform/sys/unit")
|
||||
public class SysUnitController {
|
||||
private static final Log log = Logs.get();
|
||||
/** 浙江交通职业技术学院在 sys_unit 中的单位主键,作为单位树未指定 pid 时的默认根。 */
|
||||
private static final String DEFAULT_UNIT_ROOT_ID = "4133012036";
|
||||
@Inject
|
||||
private SysUnitService sysUnitService;
|
||||
@Inject
|
||||
@@ -300,7 +302,7 @@ public class SysUnitController {
|
||||
@SaCheckLogin
|
||||
public Object tree(@Param("pid") String pid, HttpServletRequest req) {
|
||||
try {
|
||||
String rootId = StrUtil.blankToDefault(pid, "0");
|
||||
String rootId = StrUtil.blankToDefault(pid, DEFAULT_UNIT_ROOT_ID);
|
||||
String virtualRootId = "root";
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.asc("unitcode");
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package com.budwk.app.sys.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author zzr
|
||||
* @name:Api2FinanceFiledMap
|
||||
* @Date 2025/9/16 9:51
|
||||
* @注释 财务会费字段映射
|
||||
*/
|
||||
@Getter
|
||||
public enum Api2FinanceFiledMap {
|
||||
|
||||
// 工号
|
||||
RYDM("rydm", "loginname"),
|
||||
// 人员名称
|
||||
RYMC("rymc", "username"),
|
||||
// 编制会费
|
||||
HF("hf", "name"),
|
||||
// 合同制会费
|
||||
HF2("hf2", "unitType");
|
||||
|
||||
public final String apiField;
|
||||
public final String dbColumn;
|
||||
|
||||
Api2FinanceFiledMap(String apiField, String dbColumn) {
|
||||
this.apiField = apiField;
|
||||
this.dbColumn = dbColumn;
|
||||
}
|
||||
}
|
||||
@@ -130,4 +130,9 @@ public class Sys_unit extends BaseModel implements Serializable {
|
||||
@Comment("部门类别区分(部门类设置 1, 其他设置 0)")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer unitTypeCode;
|
||||
|
||||
@Column
|
||||
@Comment("生日祝福排序")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer birthdaySortNo;
|
||||
}
|
||||
|
||||
@@ -37,19 +37,19 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("工号")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 120)
|
||||
@DataCenterColumn(name = "工号", key = "ZGH")
|
||||
@DataCenterColumn(name = "工号", key = "gh")
|
||||
private String loginname;
|
||||
|
||||
@Column
|
||||
@Comment("姓名")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
@DataCenterColumn(name = "姓名", key = "XM")
|
||||
@DataCenterColumn(name = "姓名", key = "xm")
|
||||
private String username;
|
||||
|
||||
@Column
|
||||
@Comment("性别")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 10)
|
||||
@DataCenterColumn(name = "性别", key = "XB", dict = "USER_SEX")
|
||||
@DataCenterColumn(name = "性别", key = "xb", dict = "USER_SEX")
|
||||
private String sex;
|
||||
|
||||
@Column
|
||||
@@ -65,12 +65,13 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("出生日期")
|
||||
@ColDefine(type = ColType.DATE)
|
||||
@DataCenterColumn(name = "出生日期", key = "csrq")
|
||||
private Date birthday;
|
||||
|
||||
@Column
|
||||
@Comment("政治面貌")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
@DataCenterColumn(name = "政治面貌", key = "ZZMMM", dict = "USER_POLITICAL")
|
||||
@DataCenterColumn(name = "政治面貌", key = "zzmm", dict = "USER_POLITICAL")
|
||||
private String political;
|
||||
|
||||
@Column
|
||||
@@ -81,7 +82,6 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("民族")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
@DataCenterColumn(name = "民族", key = "MZM", dict = "USER_NATION")
|
||||
private String nation;
|
||||
|
||||
@Column
|
||||
@@ -102,13 +102,12 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("证件号码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
@DataCenterColumn(name = "证件号码", key = "SFZJH")
|
||||
private String idCard;
|
||||
|
||||
@Column
|
||||
@Comment("手机号码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@DataCenterColumn(name = "手机号码", key = "YDDH")
|
||||
@DataCenterColumn(name = "手机号码", key = "sjh")
|
||||
private String mobile;
|
||||
|
||||
@Column
|
||||
@@ -124,7 +123,6 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("学位")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
// @DataCenterColumn(name = "学位", key = "zgxwmc")
|
||||
private String academicDegree;
|
||||
|
||||
@Column
|
||||
@@ -145,37 +143,32 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("职工来源")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
// @DataCenterColumn(name = "职工来源", key = "zgly")
|
||||
private String employeeSource;
|
||||
|
||||
@Column
|
||||
@Comment("行政级别(用于管理岗位)")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
// @DataCenterColumn(name = "行政级别(用于管理岗位)", key = "xzjb")
|
||||
private String administrativeLevel;
|
||||
|
||||
@Column
|
||||
@Comment("岗位系列")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
// @DataCenterColumn(name = "岗位系列", key = "gwxl")
|
||||
private String positionSeries;
|
||||
|
||||
@Column
|
||||
@Comment("岗级")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
// @DataCenterColumn(name = "岗级", key = "gj")
|
||||
private String positionLevel;
|
||||
|
||||
@Column
|
||||
@Comment("行政岗级")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
// @DataCenterColumn(name = "行政岗级", key = "xzgj")
|
||||
private String administrativePositionLevel;
|
||||
|
||||
@Column
|
||||
@Comment("来校时间")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 10)
|
||||
@DataCenterColumn(name = "来校时间", key = "LXNY")
|
||||
@DataCenterColumn(name = "来校时间", key = "jxrq")
|
||||
private String arrivalAtSchoolDate;
|
||||
|
||||
@Column
|
||||
@@ -191,7 +184,7 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("在职状态")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
@DataCenterColumn(name = "当前状态码", key = "DQZT", dict = "USER_STATE")
|
||||
@DataCenterColumn(name = "当前状态码", key = "zzzt", dict = "USER_STATE")
|
||||
private String userState;
|
||||
|
||||
@Column
|
||||
@@ -208,7 +201,7 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("教职工类别码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
@DataCenterColumn(name = "教职工类别码", key = "RYLX", dict = "USER_PERSON_TYPE")
|
||||
@DataCenterColumn(name = "教职工类别码", key = "rylb", dict = "USER_PERSON_TYPE")
|
||||
private String personType;
|
||||
|
||||
@Column
|
||||
@@ -230,6 +223,7 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
@Column
|
||||
@Comment("预计离校时间/最后离校时间")
|
||||
@ColDefine(type = ColType.DATE)
|
||||
@DataCenterColumn(name = "离校日期", key = "lxrq")
|
||||
private Date expectedLeaveSchoolDate;
|
||||
|
||||
@Column
|
||||
@@ -269,7 +263,7 @@ public class Sys_user extends BaseModel implements Serializable {
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@DataCenterColumn(name = "单位", key = "SZDWH")
|
||||
@DataCenterColumn(name = "单位", key = "bmdm")
|
||||
private String unitId;
|
||||
|
||||
@Column
|
||||
|
||||
@@ -6,7 +6,6 @@ import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface SysDataUserPullService extends BaseService<Sys_user_source> {
|
||||
|
||||
@@ -15,11 +14,6 @@ public interface SysDataUserPullService extends BaseService<Sys_user_source> {
|
||||
*/
|
||||
Date pull();
|
||||
|
||||
/**
|
||||
* 拉取人员博士后的信息
|
||||
*/
|
||||
Map<String, Date> pullPostDoctoral();
|
||||
|
||||
/**
|
||||
* 获取下拉框数据(单位、在职状态、编制类别、教职工类别)
|
||||
*/
|
||||
@@ -31,11 +25,4 @@ public interface SysDataUserPullService extends BaseService<Sys_user_source> {
|
||||
* @return
|
||||
*/
|
||||
List<NutMap> pullTimeOptions();
|
||||
|
||||
|
||||
/**
|
||||
* 获取财务数据
|
||||
* @return
|
||||
*/
|
||||
Map<String, NutMap> pullFinance();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
package com.budwk.app.sys.services.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
@@ -21,7 +19,6 @@ import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -41,8 +38,8 @@ import java.util.stream.Collectors;
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implements SysDataUnitPullService {
|
||||
|
||||
private static final String DMP_UNIT_KEY = "unit";
|
||||
private static final int DMP_PAGE_SIZE = 1000;
|
||||
private static final String CDSP_UNIT_KEY = "unit";
|
||||
private static final int CDSP_PAGE_SIZE = 1000;
|
||||
|
||||
@Inject
|
||||
private DataCenterProperties dataCenterProperties;
|
||||
@@ -64,10 +61,9 @@ public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implem
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void updateUnits(List<String> unitIds) {
|
||||
String accessToken = getDmpAccessToken();
|
||||
List<JSONObject> rawDataList = distinctDmpUnits(pullDmpUnits(getDmpUnitUrl(), accessToken));
|
||||
List<JSONObject> rawDataList = distinctCdspUnits(pullCdspUnits());
|
||||
Set<String> parentCodes = rawDataList.stream()
|
||||
.map(this::getNormalizedParentCode)
|
||||
.map(raw -> raw.getStr("sjbmbm"))
|
||||
.filter(StrUtil::isNotBlank)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
@@ -79,109 +75,45 @@ public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implem
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取信息中心开放平台访问令牌。
|
||||
* 参数来自 data-center.token-url、data-center.key、data-center.secret;
|
||||
* 返回值为后续单位接口 body 中 access_token 使用的字符串。
|
||||
* 严格按参考项目通过 CDSP V2 单位接口单次拉取数据。
|
||||
* 请求头包含 appId、timestamp、sign,请求体只包含 $top=1000 和 $count=true;
|
||||
* 返回值为响应 value 中的单位 JSON 列表。
|
||||
*/
|
||||
private String getDmpAccessToken() {
|
||||
String tokenUrl = dataCenterProperties.getTokenUrl();
|
||||
if (StrUtil.isBlank(tokenUrl)) {
|
||||
throw new BaseException("未配置信息中心token地址: data-center.token-url");
|
||||
}
|
||||
String key = dataCenterProperties.getKey();
|
||||
if (StrUtil.isBlank(key)) {
|
||||
throw new BaseException("未配置信息中心token key: data-center.key");
|
||||
}
|
||||
String secret = dataCenterProperties.getSecret();
|
||||
if (StrUtil.isBlank(secret)) {
|
||||
throw new BaseException("未配置信息中心token secret: data-center.secret");
|
||||
}
|
||||
|
||||
String params = URLUtil.buildQuery(Map.of("key", key, "secret", secret), StandardCharsets.UTF_8);
|
||||
String tokenResBody = HttpUtil.createGet(tokenUrl + "?" + params).execute().body();
|
||||
JSONObject tokenJsonBody = JSONUtil.parseObj(tokenResBody);
|
||||
String accessToken = tokenJsonBody.getStr("access_token");
|
||||
if (StrUtil.isBlank(accessToken) && tokenJsonBody.getJSONObject("result") != null) {
|
||||
accessToken = tokenJsonBody.getJSONObject("result").getStr("access_token");
|
||||
}
|
||||
if (StrUtil.isBlank(accessToken) && tokenJsonBody.getJSONObject("data") != null) {
|
||||
accessToken = tokenJsonBody.getJSONObject("data").getStr("access_token");
|
||||
}
|
||||
if (StrUtil.isBlank(accessToken)) {
|
||||
accessToken = tokenJsonBody.getStr("token");
|
||||
}
|
||||
if (StrUtil.isBlank(accessToken)) {
|
||||
throw new BaseException("获取信息中心token失败");
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取信息中心单位接口地址。
|
||||
* 配置项为 data-center.urls.unit,返回值为单位全量接口URL。
|
||||
*/
|
||||
private String getDmpUnitUrl() {
|
||||
String url = dataCenterProperties.getUrls().get(DMP_UNIT_KEY);
|
||||
private List<JSONObject> pullCdspUnits() {
|
||||
String url = dataCenterProperties.getUrls().get(CDSP_UNIT_KEY);
|
||||
String appId = dataCenterProperties.getAppId();
|
||||
String appSecret = dataCenterProperties.getAppSecret();
|
||||
if (StrUtil.isBlank(url)) {
|
||||
throw new BaseException("未配置信息中心单位接口地址: data-center.urls." + DMP_UNIT_KEY);
|
||||
throw new BaseException("未配置信息中心单位接口地址: data-center.urls." + CDSP_UNIT_KEY);
|
||||
}
|
||||
return url;
|
||||
if (StrUtil.isBlank(appId)) {
|
||||
throw new BaseException("未配置信息中心appId: data-center.app-id");
|
||||
}
|
||||
if (StrUtil.isBlank(appSecret)) {
|
||||
throw new BaseException("未配置信息中心appSecret: data-center.app-secret");
|
||||
}
|
||||
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String sign = Base64.encode(DigestUtil.md5Hex(appId + appSecret + timestamp));
|
||||
String resBody = HttpUtil.createPost(url)
|
||||
.addHeaders(Map.of("appId", appId, "timestamp", String.valueOf(timestamp), "sign", sign))
|
||||
.body(JSONUtil.toJsonStr(Map.of("$top", CDSP_PAGE_SIZE, "$count", true)))
|
||||
.execute().body();
|
||||
JSONObject jsonBody = JSONUtil.parseObj(resBody);
|
||||
JSONArray data = jsonBody.getJSONArray("value");
|
||||
if (data == null) {
|
||||
throw new BaseException("获取信息中心单位数据失败,响应中缺少value数组");
|
||||
}
|
||||
return data.stream().map(v -> (JSONObject) v).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页拉取单位接口数据。
|
||||
* 入参 url 为单位接口地址,accessToken 为信息中心令牌;
|
||||
* 请求 body 包含 access_token、per_page、page;
|
||||
* 返回值为 result.data 合并后的单位原始 JSON 列表。
|
||||
* 按新接口 bmbm(部门编码)去重,避免接口分页或源数据重复写入同一单位。
|
||||
*/
|
||||
private List<JSONObject> pullDmpUnits(String url, String accessToken) {
|
||||
List<JSONObject> rawDataList = new ArrayList<>();
|
||||
int page = 1;
|
||||
int maxPage = 1;
|
||||
int total = 0;
|
||||
|
||||
do {
|
||||
HttpRequest httpRequest = HttpUtil.createPost(url);
|
||||
httpRequest.header(Header.CONTENT_TYPE, "application/json");
|
||||
httpRequest.body(JSONUtil.toJsonStr(Map.of(
|
||||
"access_token", accessToken,
|
||||
"per_page", String.valueOf(DMP_PAGE_SIZE),
|
||||
"page", String.valueOf(page)
|
||||
)));
|
||||
|
||||
log.info("请求信息中心单位数据,第{}页: {}", page, httpRequest);
|
||||
String resBody = httpRequest.execute().body();
|
||||
log.info("请求信息中心单位数据第{}页结果: {}", page, resBody);
|
||||
JSONObject jsonBody = JSONUtil.parseObj(resBody);
|
||||
|
||||
if (jsonBody.getInt("code") != 10000) {
|
||||
throw new BaseException("获取信息中心单位数据失败,错误码: " + jsonBody.getInt("code") + ";错误原因:" + jsonBody.getStr("message"));
|
||||
}
|
||||
|
||||
JSONObject result = jsonBody.getJSONObject("result");
|
||||
if (result == null) {
|
||||
break;
|
||||
}
|
||||
total = result.getInt("total", total);
|
||||
maxPage = result.getInt("max_page", maxPage);
|
||||
JSONArray data = result.getJSONArray("data");
|
||||
if (CollUtil.isNotEmpty(data)) {
|
||||
rawDataList.addAll(data.stream().map(v -> (JSONObject) v).toList());
|
||||
}
|
||||
log.info("信息中心单位数据拉取进度: {}/{}", rawDataList.size(), total);
|
||||
page++;
|
||||
} while (page <= maxPage);
|
||||
|
||||
return rawDataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按单位代码去重,避免接口分页或源数据重复导致同一 DWDM 重复写入。
|
||||
*/
|
||||
private List<JSONObject> distinctDmpUnits(List<JSONObject> rawDataList) {
|
||||
private List<JSONObject> distinctCdspUnits(List<JSONObject> rawDataList) {
|
||||
Map<String, JSONObject> unitMap = new LinkedHashMap<>();
|
||||
for (JSONObject raw : rawDataList) {
|
||||
String unitCode = raw.getStr("DWDM");
|
||||
String unitCode = raw.getStr("bmbm");
|
||||
if (StrUtil.isBlank(unitCode)) {
|
||||
continue;
|
||||
}
|
||||
@@ -192,20 +124,21 @@ public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implem
|
||||
|
||||
/**
|
||||
* 保存或更新单位。
|
||||
* DWDM 对应系统单位 id/unitcode,DWMC 对应名称,LSDWH 对应父级单位号,DWCC 对应信息中心原始单位层级。
|
||||
* bmbm 对应系统单位 id/unitcode,bmmc 对应名称,sjbmbm 对应父级单位号,bmdj 对应单位层级。
|
||||
*/
|
||||
private void saveOrUpdateUnit(JSONObject raw, Set<String> parentCodes) {
|
||||
String unitCode = raw.getStr("DWDM");
|
||||
String unitCode = raw.getStr("bmbm");
|
||||
if (StrUtil.isBlank(unitCode)) {
|
||||
return;
|
||||
}
|
||||
|
||||
String parentId = getParentId(unitCode, getNormalizedParentCode(raw));
|
||||
String parentId = getParentId(unitCode, raw.getStr("sjbmbm"));
|
||||
Sys_unit unit = fetch(unitCode);
|
||||
if (unit == null) {
|
||||
unit = new Sys_unit();
|
||||
unit.setId(unitCode);
|
||||
unit.setUnitcode(unitCode);
|
||||
unit.setAliasName(raw.getStr("bmmc"));
|
||||
unit.setPath(getUnitPath(parentId));
|
||||
setUnitValue(unit, raw, parentId, parentCodes);
|
||||
dao().fastInsert(unit);
|
||||
@@ -220,39 +153,26 @@ public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implem
|
||||
|
||||
/**
|
||||
* 根据接口字段给系统单位赋值。
|
||||
* DWYXBS 表示单位是否有效,DWCC 表示信息中心原始单位层次;
|
||||
* 系统内置根单位占用一级层级,因此保存时统一将 DWCC 加一。
|
||||
* 新接口提供 bmbm、bmmc、bmdj、sjbmbm;未提供的别名、地址、工会和单位类别等本地字段保持原值。
|
||||
*/
|
||||
private void setUnitValue(Sys_unit unit, JSONObject raw, String parentId, Set<String> parentCodes) {
|
||||
String unitCode = raw.getStr("DWDM");
|
||||
String unitName = raw.getStr("DWMC");
|
||||
String aliasName = StrUtil.blankToDefault(raw.getStr("DWJC"), unitName);
|
||||
Integer rawUnitLevel = raw.getInt("DWCC");
|
||||
Integer unitLevel = getNormalizedUnitLevel(raw);
|
||||
boolean availableBusinessUnit = "是".equals(raw.getStr("DWYXBS")) && Integer.valueOf(2).equals(rawUnitLevel);
|
||||
String unitCode = raw.getStr("bmbm");
|
||||
|
||||
unit.setParentId(parentId);
|
||||
unit.setName(unitName);
|
||||
unit.setAliasName(aliasName);
|
||||
unit.setName(raw.getStr("bmmc"));
|
||||
unit.setUnitcode(unitCode);
|
||||
unit.setAddress(raw.getStr("DWDZ"));
|
||||
unit.setUnitLevel(unitLevel);
|
||||
unit.setUnitType(raw.getStr("DWLB"));
|
||||
unit.setUnitTypeCode(availableBusinessUnit ? 1 : 0);
|
||||
unit.setUnitLevel(raw.getInt("bmdj"));
|
||||
unit.setHasChildren(parentCodes.contains(unitCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算父级单位号。
|
||||
* LSDWH 为空、等于自身或本地不存在该父级时按根级处理;系统根单位 0 允许直接作为父级。
|
||||
* sjbmbm 为空、等于自身或本地不存在该父级时按根级处理;已存在的父单位直接作为 parentId。
|
||||
*/
|
||||
private String getParentId(String unitCode, String parentCode) {
|
||||
if (StrUtil.isBlank(parentCode) || unitCode.equals(parentCode)) {
|
||||
return "";
|
||||
}
|
||||
if ("0".equals(parentCode)) {
|
||||
return parentCode;
|
||||
}
|
||||
Sys_unit parentUnit = fetch(parentCode);
|
||||
return parentUnit == null ? "" : parentCode;
|
||||
}
|
||||
@@ -271,28 +191,9 @@ public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implem
|
||||
}
|
||||
|
||||
/**
|
||||
* 信息中心一级单位应挂在系统根单位 0 下,其余单位沿用接口返回的 LSDWH。
|
||||
*/
|
||||
private String getNormalizedParentCode(JSONObject raw) {
|
||||
Integer rawUnitLevel = raw.getInt("DWCC");
|
||||
if (Integer.valueOf(1).equals(rawUnitLevel)) {
|
||||
return "0";
|
||||
}
|
||||
return raw.getStr("LSDWH");
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统内置根单位占用一级层级,信息中心单位层次入库时统一加一。
|
||||
*/
|
||||
private Integer getNormalizedUnitLevel(JSONObject raw) {
|
||||
Integer rawUnitLevel = raw.getInt("DWCC");
|
||||
return rawUnitLevel == null ? null : rawUnitLevel + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* DWCC 为信息中心单位层次,排序时用于尽量先处理父级单位,便于后续子级找到父节点。
|
||||
* bmdj 为信息中心单位层级,排序后优先处理父级单位,便于子单位建立 parentId 和 path。
|
||||
*/
|
||||
private int getUnitLevel(JSONObject raw) {
|
||||
return raw.getInt("DWCC", 0);
|
||||
return raw.getInt("bmdj", 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,8 @@ package com.budwk.app.sys.services.impl;
|
||||
|
||||
import cn.hutool.core.codec.Base64;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.IdcardUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.core.util.URLUtil;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import cn.hutool.http.Header;
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
@@ -18,18 +12,13 @@ import com.budwk.app.base.config.DataCenterProperties;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.annotation.DataCenterColumn;
|
||||
import com.budwk.app.sys.enums.Api2FinanceFiledMap;
|
||||
import com.budwk.app.sys.models.Sys_data_dict;
|
||||
import com.budwk.app.sys.models.Sys_dict;
|
||||
import com.budwk.app.sys.models.Sys_unit;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.sys.models.Sys_user_source;
|
||||
import com.budwk.app.sys.services.SysDataUnitPullService;
|
||||
import com.budwk.app.sys.services.SysDataUserPullService;
|
||||
import com.budwk.app.sys.services.SysDictService;
|
||||
import com.budwk.app.sys.utils.DataCenterUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.aop.interceptor.async.Async;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
@@ -39,11 +28,8 @@ import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.math.BigDecimal;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -51,19 +37,13 @@ import java.util.stream.Collectors;
|
||||
@Slf4j
|
||||
public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source> implements SysDataUserPullService {
|
||||
|
||||
private static final String DMP_TEACHER_KEY = "teacher";
|
||||
private static final String DMP_DISPATCH_KEY = "dispatch";
|
||||
private static final int DMP_PAGE_SIZE = 1000;
|
||||
private static final String CDSP_USER_KEY = "user";
|
||||
private static final int CDSP_PAGE_SIZE = 1000;
|
||||
|
||||
@Inject
|
||||
private SysDictService sysDictService;
|
||||
@Inject
|
||||
private DataCenterProperties dataCenterProperties;
|
||||
@Inject
|
||||
private SysDataUnitPullService sysDataUnitPullService;
|
||||
@Inject
|
||||
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
|
||||
|
||||
public SysDataUserPullServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
@@ -120,22 +100,20 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
// 字典码表Map,key为父级编码,value为子级字典列表
|
||||
Map<String, List<Sys_data_dict>> dataDictMap = dataDictList.stream().collect(Collectors.groupingBy(Sys_data_dict::getParentCode));
|
||||
|
||||
String accessToken = getDmpAccessToken();
|
||||
List<JSONObject> rawDataList = new ArrayList<>();
|
||||
rawDataList.addAll(pullDmpUsers(getDmpUrl(DMP_TEACHER_KEY), accessToken, "在岗教职工"));
|
||||
rawDataList.addAll(pullDmpUsers(getDmpUrl(DMP_DISPATCH_KEY), accessToken, "在岗劳务派遣"));
|
||||
rawDataList = distinctDmpUsers(rawDataList);
|
||||
List<JSONObject> rawDataList = distinctCdspUsers(pullCdspUsers());
|
||||
|
||||
if (rawDataList.isEmpty()) {
|
||||
log.warn("当前未获取到人员数据");
|
||||
}
|
||||
|
||||
Date nowDate = new Date();
|
||||
Map<String, String> unitNameMap = dao().query(Sys_unit.class, Cnd.NEW()).stream()
|
||||
.filter(unit -> StrUtil.isNotBlank(unit.getId()))
|
||||
.collect(Collectors.toMap(Sys_unit::getId, Sys_unit::getName, (oldValue, newValue) -> oldValue));
|
||||
|
||||
// 赋值
|
||||
List<Sys_user_source> latestSourceList = rawDataList.stream().map(raw -> {
|
||||
Sys_user_source sysUser = new Sys_user_source();
|
||||
|
||||
// 使用缓存的字段映射
|
||||
for (FieldMapping mapping : getFieldMappings()) {
|
||||
try {
|
||||
@@ -149,17 +127,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
.findFirst().orElse(new Sys_data_dict());
|
||||
mapping.field.set(sysUser, StrUtil.blankToDefault(sysDataDict.getName(), raw.getStr(mapping.key)));
|
||||
} else {
|
||||
// 特殊处理 根据身份证号获取性别和出生年月
|
||||
if ("SFZJH".equals(mapping.key)) {
|
||||
String idCard = raw.getStr(mapping.key);
|
||||
mapping.field.set(sysUser, idCard);
|
||||
// 设置出生年月
|
||||
try {
|
||||
sysUser.setBirthday(IdcardUtil.getBirthDate(idCard));
|
||||
} catch (Exception e) {
|
||||
sysUser.setBirthday(null);
|
||||
}
|
||||
} else if ("LXNY".equals(mapping.key)) {
|
||||
if ("jxrq".equals(mapping.key)) {
|
||||
mapping.field.set(sysUser, normalizeArrivalAtSchoolDate(raw.getStr(mapping.key)));
|
||||
} else {
|
||||
mapping.field.set(sysUser, raw.getStr(mapping.key));
|
||||
@@ -173,8 +141,8 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
}
|
||||
}
|
||||
|
||||
sysUser.setUnitName(raw.getStr("SZDW"));
|
||||
sysUser.setUnitId(resolveSourceUnitId(raw.getStr("SZDWH")));
|
||||
sysUser.setUnitId(resolveSourceUnitId(raw.getStr("bmdm")));
|
||||
sysUser.setUnitName(unitNameMap.get(sysUser.getUnitId()));
|
||||
|
||||
// 设置拉取时间
|
||||
sysUser.setPullTime(nowDate);
|
||||
@@ -207,7 +175,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
|
||||
/**
|
||||
* 规范化信息中心返回的来校时间。
|
||||
* 入参 arrivalAtSchoolDate 对应信息中心 LXNY 字段,允许 yyyy-MM-dd 或 yyyy-MM;
|
||||
* 入参 arrivalAtSchoolDate 对应信息中心 jxrq 字段,允许 yyyy-MM-dd 或 yyyy-MM;
|
||||
* 返回值用于 sys_user_source.arrivalAtSchoolDate 和后续 sys_user.arrivalAtSchoolDate,年月格式统一补为当月 01 日。
|
||||
*/
|
||||
private String normalizeArrivalAtSchoolDate(String arrivalAtSchoolDate) {
|
||||
@@ -227,115 +195,68 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取信息中心开放平台访问令牌。
|
||||
* 返回值为接口后续调用使用的 access_token 字符串。
|
||||
* 从新 CDSP V2 人员接口分页拉取数据。
|
||||
* 签名在本次拉取开始时生成一次,全部分页复用同一个 timestamp 和 sign;
|
||||
* $skip 从 1 开始作为页码,$top 固定为 1000,并根据 @odata.count 计算总页数;
|
||||
* 返回值为各页 value 数组合并后的人员 JSON 列表。
|
||||
*/
|
||||
private String getDmpAccessToken() {
|
||||
String tokenUrl = dataCenterProperties.getTokenUrl();
|
||||
if (StrUtil.isBlank(tokenUrl)) {
|
||||
throw new BaseException("未配置信息中心token地址: data-center.token-url");
|
||||
}
|
||||
String key = dataCenterProperties.getKey();
|
||||
if (StrUtil.isBlank(key)) {
|
||||
throw new BaseException("未配置信息中心token key: data-center.key");
|
||||
}
|
||||
String secret = dataCenterProperties.getSecret();
|
||||
if (StrUtil.isBlank(secret)) {
|
||||
throw new BaseException("未配置信息中心token secret: data-center.secret");
|
||||
}
|
||||
// 信息中心token接口要求key和secret通过URL参数传入,配置中分开维护,调用时统一组装。
|
||||
String params = URLUtil.buildQuery(Map.of("key", key, "secret", secret), StandardCharsets.UTF_8);
|
||||
HttpRequest tokenHttpRequest = HttpUtil.createGet(tokenUrl + "?" + params);
|
||||
log.info("请求信息中心token: {}", tokenHttpRequest);
|
||||
String tokenResBody = tokenHttpRequest.execute().body();
|
||||
log.info("请求信息中心token结果: {}", tokenResBody);
|
||||
|
||||
JSONObject tokenJsonBody = JSONUtil.parseObj(tokenResBody);
|
||||
String accessToken = tokenJsonBody.getStr("access_token");
|
||||
if (StrUtil.isBlank(accessToken) && tokenJsonBody.getJSONObject("result") != null) {
|
||||
accessToken = tokenJsonBody.getJSONObject("result").getStr("access_token");
|
||||
}
|
||||
if (StrUtil.isBlank(accessToken) && tokenJsonBody.getJSONObject("data") != null) {
|
||||
accessToken = tokenJsonBody.getJSONObject("data").getStr("access_token");
|
||||
}
|
||||
if (StrUtil.isBlank(accessToken)) {
|
||||
accessToken = tokenJsonBody.getStr("token");
|
||||
}
|
||||
if (StrUtil.isBlank(accessToken)) {
|
||||
throw new BaseException("获取信息中心token失败");
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取信息中心人员接口地址。
|
||||
* 入参 key 对应 data-center.urls 下的配置项,返回值为具体接口URL。
|
||||
*/
|
||||
private String getDmpUrl(String key) {
|
||||
String url = dataCenterProperties.getUrls().get(key);
|
||||
private List<JSONObject> pullCdspUsers() {
|
||||
String url = dataCenterProperties.getUrls().get(CDSP_USER_KEY);
|
||||
String appId = dataCenterProperties.getAppId();
|
||||
String appSecret = dataCenterProperties.getAppSecret();
|
||||
if (StrUtil.isBlank(url)) {
|
||||
throw new BaseException("未配置信息中心人员接口地址: data-center.urls." + key);
|
||||
throw new BaseException("未配置信息中心人员接口地址: data-center.urls." + CDSP_USER_KEY);
|
||||
}
|
||||
if (StrUtil.isBlank(appId)) {
|
||||
throw new BaseException("未配置信息中心appId: data-center.app-id");
|
||||
}
|
||||
if (StrUtil.isBlank(appSecret)) {
|
||||
throw new BaseException("未配置信息中心appSecret: data-center.app-secret");
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页拉取单个人员接口数据。
|
||||
* 入参 url 为人员接口地址,accessToken 为信息中心令牌,sourceName 用于日志区分接口来源。
|
||||
* 返回值为该接口所有分页合并后的原始人员 JSON 列表。
|
||||
*/
|
||||
private List<JSONObject> pullDmpUsers(String url, String accessToken, String sourceName) {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
String sign = Base64.encode(DigestUtil.md5Hex(appId + appSecret + timestamp));
|
||||
List<JSONObject> rawDataList = new ArrayList<>();
|
||||
int page = 1;
|
||||
int maxPage = 1;
|
||||
int total = 0;
|
||||
int skip = 1;
|
||||
boolean hasRecords = true;
|
||||
|
||||
do {
|
||||
// 信息中心接口单页最多返回1000条,按page循环拉完当前接口全部数据。
|
||||
HttpRequest httpRequest = HttpUtil.createPost(url);
|
||||
httpRequest.header(Header.CONTENT_TYPE, "application/json");
|
||||
httpRequest.body(JSONUtil.toJsonStr(Map.of(
|
||||
"access_token", accessToken,
|
||||
"per_page", String.valueOf(DMP_PAGE_SIZE),
|
||||
"page", String.valueOf(page)
|
||||
)));
|
||||
|
||||
log.info("请求{}人员数据,第{}页: {}", sourceName, page, httpRequest);
|
||||
String resBody = httpRequest.execute().body();
|
||||
log.info("请求{}人员数据第{}页结果: {}", sourceName, page, resBody);
|
||||
while (hasRecords) {
|
||||
String resBody = HttpUtil.createPost(url)
|
||||
.addHeaders(Map.of("appId", appId, "timestamp", String.valueOf(timestamp), "sign", sign))
|
||||
.body(JSONUtil.toJsonStr(Map.of(
|
||||
"$skip", skip,
|
||||
"$top", CDSP_PAGE_SIZE,
|
||||
"$count", true
|
||||
)))
|
||||
.execute().body();
|
||||
JSONObject jsonBody = JSONUtil.parseObj(resBody);
|
||||
|
||||
if (jsonBody.getInt("code") != 10000) {
|
||||
throw new BaseException("获取" + sourceName + "人员数据失败,错误码: " + jsonBody.getInt("code") + ";错误原因:" + jsonBody.getStr("message"));
|
||||
JSONArray data = jsonBody.getJSONArray("value");
|
||||
if (data == null) {
|
||||
throw new BaseException("获取信息中心人员数据失败,响应中缺少value数组");
|
||||
}
|
||||
|
||||
JSONObject result = jsonBody.getJSONObject("result");
|
||||
if (result == null) {
|
||||
break;
|
||||
rawDataList.addAll(data.stream().map(v -> (JSONObject) v).toList());
|
||||
int totalCount = jsonBody.getInt("@odata.count", 0);
|
||||
int maxPage = (int) Math.ceil((double) totalCount / CDSP_PAGE_SIZE);
|
||||
log.info("信息中心人员数据拉取进度: {}/{}", rawDataList.size(), totalCount);
|
||||
skip++;
|
||||
if (skip > maxPage) {
|
||||
hasRecords = false;
|
||||
}
|
||||
total = result.getInt("total", total);
|
||||
maxPage = result.getInt("max_page", maxPage);
|
||||
JSONArray data = result.getJSONArray("data");
|
||||
if (CollUtil.isNotEmpty(data)) {
|
||||
rawDataList.addAll(data.stream().map(v -> (JSONObject) v).toList());
|
||||
}
|
||||
log.info("{}人员数据拉取进度: {}/{}", sourceName, rawDataList.size(), total);
|
||||
page++;
|
||||
} while (page <= maxPage);
|
||||
}
|
||||
|
||||
return rawDataList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并两个接口数据时按职工号去重,避免同一批次出现重复人员。
|
||||
* 按新接口 gh(工号)去重,避免分页或源数据重复导致同一批次出现重复人员。
|
||||
* 返回值保持第一次出现的数据,用于后续统一映射入库。
|
||||
*/
|
||||
private List<JSONObject> distinctDmpUsers(List<JSONObject> rawDataList) {
|
||||
private List<JSONObject> distinctCdspUsers(List<JSONObject> rawDataList) {
|
||||
Map<String, JSONObject> userMap = new LinkedHashMap<>();
|
||||
for (JSONObject raw : rawDataList) {
|
||||
String loginName = raw.getStr("ZGH");
|
||||
String loginName = raw.getStr("gh");
|
||||
if (StrUtil.isBlank(loginName)) {
|
||||
loginName = raw.getStr("ID");
|
||||
continue;
|
||||
}
|
||||
userMap.putIfAbsent(loginName, raw);
|
||||
}
|
||||
@@ -344,7 +265,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
|
||||
/**
|
||||
* 根据接口返回的所在单位号转换数据源用户单位。
|
||||
* 入参 rawUnitId 对应人员接口 SZDWH:5位表示三级单位,需要写入其二级父单位;其他长度保持接口原值。
|
||||
* 入参 rawUnitId 对应人员接口 bmdm:5位表示三级单位,需要写入其二级父单位;其他长度保持接口原值。
|
||||
* 返回值为 sys_user_source.unitId 使用的单位ID,找不到三级单位或父级为空时保留接口原始单位号,避免人员数据丢失。
|
||||
*/
|
||||
private String resolveSourceUnitId(String rawUnitId) {
|
||||
@@ -358,118 +279,6 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
return unit.getParentId();
|
||||
}
|
||||
|
||||
@Async
|
||||
private void updateDict(List<Sys_user_source> userSources) {
|
||||
//判断是否要更新在职状态字典
|
||||
List<String> sourceUserStates = userSources.stream().map(Sys_user::getUserState).filter(StrUtil::isNotBlank).distinct().toList();
|
||||
//判断是否要更新学历字典
|
||||
List<String> sourceEducations = userSources.stream().map(Sys_user::getEducation).filter(StrUtil::isNotBlank).distinct().toList();
|
||||
//判断是否要更新学位字典
|
||||
List<String> sourceAcademicDegrees = userSources.stream().map(Sys_user::getAcademicDegree).filter(StrUtil::isNotBlank).distinct().toList();
|
||||
//判断是否要更新教职工类别字典
|
||||
List<String> personTypes = userSources.stream().map(Sys_user::getPersonType).filter(StrUtil::isNotBlank).distinct().toList();
|
||||
//判断是否要更新身份类型字典
|
||||
List<String> sourceIdentityTypes = userSources.stream().map(Sys_user::getIdentityType).filter(StrUtil::isNotBlank).distinct().toList();
|
||||
|
||||
//系统在职状态字典
|
||||
List<Sys_dict> sysUserStates = sysDictService.getSubListByCode("USER_STATE");
|
||||
//系统学历字典
|
||||
List<Sys_dict> sysEducations = sysDictService.getSubListByCode("USER_EDUCATION");
|
||||
//系统学位字典
|
||||
List<Sys_dict> sysAcademicDegrees = sysDictService.getSubListByCode("USER_ACADEMIC_DEGREE");
|
||||
//系统教职工类别字典
|
||||
List<Sys_dict> sysStaffTypes = sysDictService.getSubListByCode("USER_STAFF_TYPE");
|
||||
//系统身份类型字典
|
||||
List<Sys_dict> sysIdentityTypes = sysDictService.getSubListByCode("USER_IDENTITY_TYPE");
|
||||
|
||||
//系统中不存在的就插入
|
||||
List<Sys_dict> insertUserStates = sourceUserStates.stream().filter(state -> sysUserStates.stream().noneMatch(dict -> dict.getCode().equals(state))).map(state -> {
|
||||
Sys_dict dict = new Sys_dict();
|
||||
dict.setCode(state);
|
||||
dict.setName(state);
|
||||
return dict;
|
||||
}).toList();
|
||||
|
||||
List<Sys_dict> insertEducations = sourceEducations.stream().filter(education -> sysEducations.stream().noneMatch(dict -> dict.getCode().equals(education))).map(education -> {
|
||||
Sys_dict dict = new Sys_dict();
|
||||
dict.setCode(education);
|
||||
dict.setName(education);
|
||||
return dict;
|
||||
}).toList();
|
||||
|
||||
List<Sys_dict> insertAcademicDegrees = sourceAcademicDegrees.stream().filter(academicDegree -> sysAcademicDegrees.stream().noneMatch(dict -> dict.getCode().equals(academicDegree))).map(academicDegree -> {
|
||||
Sys_dict dict = new Sys_dict();
|
||||
dict.setCode(academicDegree);
|
||||
dict.setName(academicDegree);
|
||||
return dict;
|
||||
}).toList();
|
||||
|
||||
for (Sys_dict dict : insertUserStates) {
|
||||
sysDictService.saveByParentCode(dict, "USER_STATE");
|
||||
}
|
||||
for (Sys_dict dict : insertEducations) {
|
||||
sysDictService.saveByParentCode(dict, "USER_EDUCATION");
|
||||
}
|
||||
for (Sys_dict dict : insertAcademicDegrees) {
|
||||
sysDictService.saveByParentCode(dict, "USER_ACADEMIC_DEGREE");
|
||||
}
|
||||
sysDictService.clearCache();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Date> pullPostDoctoral() {
|
||||
String appId = "1926887238437818370";
|
||||
String secret = "32df31fcf4fc43f9a647ee1f47134f36";
|
||||
|
||||
List<JSONObject> allUsers = new ArrayList<>();
|
||||
int skip = 0;
|
||||
int totalCount = 0;
|
||||
boolean firstRequest = true;
|
||||
|
||||
do {
|
||||
long ts = System.currentTimeMillis();
|
||||
String sign = Base64.encode(DigestUtil.md5Hex(appId + secret + ts, CharsetUtil.CHARSET_UTF_8));
|
||||
|
||||
HttpRequest httpRequest = HttpUtil.createPost("https://sjzcpt.nnu.edu.cn/cdsp/data-api/v2/DS0040");
|
||||
httpRequest.header("Content-Type", "application/json");
|
||||
httpRequest.header("appId", appId);
|
||||
httpRequest.header("timestamp", String.valueOf(ts));
|
||||
httpRequest.header("sign", sign);
|
||||
|
||||
HashMap<String, Object> reqBody = new HashMap<>();
|
||||
reqBody.put("$count", true);
|
||||
reqBody.put("$skip", skip);
|
||||
reqBody.put("$top", 1000);
|
||||
|
||||
httpRequest.body(JSONUtil.toJsonStr(reqBody));
|
||||
String resBody = httpRequest.execute().body();
|
||||
|
||||
JSONObject entries = JSONUtil.parseObj(resBody);
|
||||
|
||||
if (firstRequest) {
|
||||
totalCount = entries.getInt("@odata.count", 0);
|
||||
firstRequest = false;
|
||||
}
|
||||
|
||||
JSONArray value = entries.getJSONArray("value");
|
||||
|
||||
if (!value.isEmpty()) {
|
||||
List<JSONObject> list = value.stream().map(item -> (JSONObject) item).toList();
|
||||
allUsers.addAll(list);
|
||||
skip += list.size();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
} while (skip < totalCount);
|
||||
|
||||
Map<String, Date> data = allUsers.stream().filter(v -> v.getStr("进站日期") != null).collect(Collectors.toMap(v -> v.getStr("教职工号"), v -> v.getDate("进站日期")));
|
||||
|
||||
return data;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap searchOptions() {
|
||||
Sql sql = Sqls.create("""
|
||||
@@ -517,11 +326,4 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
|
||||
""");
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, NutMap> pullFinance() {
|
||||
// 旧数据中心财务接口已停用,避免继续调用旧token/code模式接口。
|
||||
throw new BaseException("旧数据中心财务拉取接口已停用");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package com.budwk.app.sys.utils;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.json.JSONObject;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
* @Author zzr
|
||||
* @name:DataCenterUtil
|
||||
* @Date 2025/9/16 9:34
|
||||
* @注释
|
||||
*/
|
||||
public class DataCenterUtil {
|
||||
|
||||
/**
|
||||
* 映射字段
|
||||
* @param obj
|
||||
* @param clazz
|
||||
* @param api2db
|
||||
* @return
|
||||
* @param <T>
|
||||
*/
|
||||
public static <T> T mapJsonToBean(JSONObject obj, Class<T> clazz, Map<String, String> api2db) {
|
||||
T bean = ReflectUtil.newInstance(clazz);
|
||||
api2db.forEach((apiField, dbColumn) -> {
|
||||
Object val = obj.getByPath(apiField);
|
||||
if (val == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Field field = ClassUtil.getDeclaredField(clazz, dbColumn);
|
||||
if (field != null) {
|
||||
Object castVal = Convert.convert(field.getType(), val);
|
||||
ReflectUtil.setFieldValue(bean, field, castVal);
|
||||
}
|
||||
});
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
+12
-5
@@ -42,6 +42,9 @@ import java.util.Map;
|
||||
@Ok("json:full")
|
||||
public class ActivityBasicUnitController {
|
||||
|
||||
/** 浙江交通职业技术学院在单位表中的主键,作为活动单位页面的默认根节点。 */
|
||||
private static final String DEFAULT_UNIT_ROOT_ID = "4133012036";
|
||||
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
@@ -59,7 +62,7 @@ public class ActivityBasicUnitController {
|
||||
public Result pageData(@Param(value = "parentId") String parentId, PageForm pageForm) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (StrUtil.isBlank(parentId)) {
|
||||
cnd.and("parentId", "=", "1");
|
||||
cnd.and("parentId", "=", DEFAULT_UNIT_ROOT_ID);
|
||||
} else {
|
||||
cnd.and("parentId", "=", parentId);
|
||||
}
|
||||
@@ -77,21 +80,25 @@ public class ActivityBasicUnitController {
|
||||
@SaCheckPermission("activity.basic.unit")
|
||||
public Result tree(@Param("pid") String pid) {
|
||||
try {
|
||||
String rootId = StrUtil.blankToDefault(pid, DEFAULT_UNIT_ROOT_ID);
|
||||
String virtualRootId = "root";
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("id", "=", pid);
|
||||
cnd.asc("unitcode");
|
||||
List<ActivityBasicUnit> list = baseService.dao().query(ActivityBasicUnit.class, cnd);
|
||||
|
||||
List<TreeNode<String>> nodeList = CollUtil.newArrayList();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
nodeList.add(new TreeNode<>(list.get(i).getId(), list.get(i).getParentId(), list.get(i).getName(), i)
|
||||
ActivityBasicUnit unit = list.get(i);
|
||||
// 将当前查询根节点挂到虚拟根下,兼容数据库根节点 parentId 为空的情况。
|
||||
String parentId = rootId.equals(unit.getId()) ? virtualRootId : unit.getParentId();
|
||||
nodeList.add(new TreeNode<>(unit.getId(), parentId, unit.getName(), i)
|
||||
.setExtra(
|
||||
Map.of(
|
||||
"unitTypeCode", list.get(i).getUnitTypeCode()
|
||||
"unitTypeCode", unit.getUnitTypeCode()
|
||||
)
|
||||
));
|
||||
}
|
||||
List<Tree<String>> treeList = TreeUtil.build(nodeList, StrUtil.blankToDefault(pid, "0"));
|
||||
List<Tree<String>> treeList = TreeUtil.build(nodeList, virtualRootId);
|
||||
return Result.success(treeList);
|
||||
} catch (Exception e) {
|
||||
return Result.error();
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import org.nutz.mvc.annotation.Ok;
|
||||
public class ActivityWorksCollectionNewController {
|
||||
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/activity/workscollection/manage/index.html")
|
||||
@Ok("beetl:/platform/zhgh/activity/workscollection/new/index.html")
|
||||
@SaCheckPermission(value = {"activity.workscollection.manage", "activity.workscollection.new"}, mode = SaMode.OR)
|
||||
public void index() {
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public class UserBirthdayManageController {
|
||||
/**
|
||||
* 查询生日人员。
|
||||
*
|
||||
* @param pageForm 分页、姓名/工号、工会、单位、人员状态及生日日期条件
|
||||
* @param pageForm 分页、姓名/工号、校区、工会、单位、人员状态及生日日期条件;校区使用 cx 或 hz
|
||||
* @return Result.data 为 Pagination,list 是人员数据,totalCount 是总数
|
||||
*/
|
||||
@At
|
||||
|
||||
@@ -25,6 +25,36 @@ public class UserBirthdayPageForm extends MemberInfoPageForm {
|
||||
@ApiModelProperty("生日结束日期,格式 yyyy-MM-dd")
|
||||
private String endDate;
|
||||
|
||||
@ApiModelProperty("所属校区,cx为长兴校区、hz为杭州校区")
|
||||
private String campusName;
|
||||
|
||||
/**
|
||||
* 将所属校区条件追加到生日人员查询。
|
||||
* 校区标记表中的 cx、hz 配置优先;未配置时,智能制造学院归入长兴校区,其余归入杭州校区。
|
||||
*
|
||||
* @param cnd 已包含人员范围和会员状态的查询条件
|
||||
* @param prefix 人员视图字段前缀,生日查询使用 u.
|
||||
*/
|
||||
public void buildCampusSearch(Cnd cnd, String prefix) {
|
||||
String campusValue = normalizeCampusValue(campusName);
|
||||
if (StrUtil.isBlank(campusValue)) {
|
||||
return;
|
||||
}
|
||||
String unitField = StrUtil.blankToDefault(prefix, "") + "unitName";
|
||||
String campusField = String.format(
|
||||
"CASE " +
|
||||
"WHEN birthdayCampus.campusId = 'cx' THEN 'cx' " +
|
||||
"WHEN birthdayCampus.campusId = 'hz' THEN 'hz' " +
|
||||
"WHEN TRIM(IFNULL(%s, '')) LIKE '智能制造学院%%' THEN 'cx' " +
|
||||
"ELSE 'hz' END",
|
||||
unitField);
|
||||
if (StrUtil.equals(campusValue, "cx")) {
|
||||
cnd.and(new Static(String.format("%s = 'cx'", campusField)));
|
||||
} else if (StrUtil.equals(campusValue, "hz")) {
|
||||
cnd.and(new Static(String.format("%s = 'hz'", campusField)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将生日日期条件追加到已有人员查询条件。
|
||||
* 未传日期时按配置天数查询,配置无效时默认十五天,跨年时自动使用 OR 条件。
|
||||
@@ -64,4 +94,17 @@ public class UserBirthdayPageForm extends MemberInfoPageForm {
|
||||
}
|
||||
return DateUtil.format(DateUtil.parse(value), "MM-dd");
|
||||
}
|
||||
|
||||
private String normalizeCampusValue(String value) {
|
||||
if (StrUtil.isBlank(value)) {
|
||||
return "";
|
||||
}
|
||||
if (StrUtil.equalsAnyIgnoreCase(value, "cx", "长兴校区")) {
|
||||
return "cx";
|
||||
}
|
||||
if (StrUtil.equalsAnyIgnoreCase(value, "hz", "杭州校区")) {
|
||||
return "hz";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
+16
@@ -30,6 +30,22 @@ public interface UserBirthdayService extends BaseService<Sys_user> {
|
||||
*/
|
||||
void exportXlsx(UserBirthdayPageForm pageForm, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 将符合条件的生日会员按杭州、长兴校区拆分为两个 Sheet 导出。
|
||||
*
|
||||
* @param pageForm 人员、组织、校区和生日日期查询条件
|
||||
* @param response XSSF 格式的 Excel 文件响应
|
||||
*/
|
||||
void exportCampusBirthdayXlsx(UserBirthdayPageForm pageForm, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 导出指定校区的生日签名表;未传生日日期时按业务默认月份计算导出范围。
|
||||
*
|
||||
* @param pageForm campusName 使用 cx 或 hz,startDate、endDate 使用 yyyy-MM-dd
|
||||
* @param response XSSF 格式的 Excel 文件响应
|
||||
*/
|
||||
void exportSignatureXlsx(UserBirthdayPageForm pageForm, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 按当前查询条件批量发送生日通知。
|
||||
*
|
||||
|
||||
+440
-2
@@ -17,7 +17,17 @@ import com.budwk.app.zhgh.staffmanage.birthday.param.UserBirthdaySendMsgForm;
|
||||
import com.budwk.app.zhgh.staffmanage.birthday.service.UserBirthdayMsgLogService;
|
||||
import com.budwk.app.zhgh.staffmanage.birthday.service.UserBirthdayService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.BorderStyle;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.VerticalAlignment;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
@@ -30,8 +40,17 @@ import org.nutz.lang.Times;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.time.YearMonth;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@IocBean(args = {"refer:dao"})
|
||||
@@ -60,6 +79,7 @@ public class UserBirthdayServiceImpl extends BaseServiceImpl<Sys_user> implement
|
||||
public void exportXlsx(UserBirthdayPageForm pageForm, HttpServletResponse response) {
|
||||
try {
|
||||
List<NutMap> list = listMap(buildBirthdaySql(pageForm));
|
||||
fillExportUnitName(list);
|
||||
List<ExcelExportEntity> columns = new ArrayList<>();
|
||||
columns.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||
columns.add(new ExcelExportEntity("姓名", "username", 20));
|
||||
@@ -67,16 +87,16 @@ public class UserBirthdayServiceImpl extends BaseServiceImpl<Sys_user> implement
|
||||
columns.add(new ExcelExportEntity("联系方式", "mobile", 20));
|
||||
columns.add(new ExcelExportEntity("出生日期", "birthday", 20));
|
||||
columns.add(new ExcelExportEntity("生日倒计时(天)", "daysUntilBirthday", 20));
|
||||
columns.add(new ExcelExportEntity("所属校区", "campusName", 20));
|
||||
columns.add(new ExcelExportEntity("在职状态", "userState", 20));
|
||||
columns.add(new ExcelExportEntity("人员类型", "personType", 20));
|
||||
columns.add(new ExcelExportEntity("人员性质", "preparedBy", 20));
|
||||
columns.add(new ExcelExportEntity("所属工会", "unionName", 25));
|
||||
columns.add(new ExcelExportEntity("所属单位", "unitName", 25));
|
||||
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
try (Workbook workbook = ExcelExportUtil.exportExcel(exportParams, columns, list)) {
|
||||
CommonDownloadUtil.download("生日人员名单.xlsx", workbook, response);
|
||||
CommonDownloadUtil.download("生日祝福人员名单.xlsx", workbook, response);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("导出生日人员名单失败", e);
|
||||
@@ -84,6 +104,47 @@ public class UserBirthdayServiceImpl extends BaseServiceImpl<Sys_user> implement
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportCampusBirthdayXlsx(UserBirthdayPageForm pageForm, HttpServletResponse response) {
|
||||
try {
|
||||
List<NutMap> list = listMap(buildBirthdaySql(pageForm));
|
||||
List<NutMap> hangzhouList = filterList(list, this::isHangzhouCampus);
|
||||
List<NutMap> changxingList = filterList(list, this::isChangxingCampus);
|
||||
fillExportUnitName(hangzhouList);
|
||||
fillExportUnitName(changxingList);
|
||||
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
try (Workbook workbook = createXssfWorkbook(exportParams)) {
|
||||
createBirthdaySheet(workbook, "杭州校区生日名单", hangzhouList);
|
||||
createBirthdaySheet(workbook, "长兴校区生日名单", changxingList);
|
||||
writeWorkbook(response, workbook, "职工生日名单.xlsx");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("导出职工生日名单失败", e);
|
||||
throw new RuntimeException("导出职工生日名单失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exportSignatureXlsx(UserBirthdayPageForm pageForm, HttpServletResponse response) {
|
||||
try {
|
||||
DateRange dateRange = buildSignatureDateRange(pageForm);
|
||||
String campusDisplayName = getCampusDisplayName(pageForm.getCampusName());
|
||||
String exportName = dateRange.fileName + StrUtil.blankToDefault(campusDisplayName, "") + "生日签名表";
|
||||
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
try (Workbook workbook = createXssfWorkbook(exportParams)) {
|
||||
createSignatureSheets(workbook, exportName, pageForm, dateRange, campusDisplayName);
|
||||
writeWorkbook(response, workbook, exportName + ".xlsx");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("导出生日签名表失败", e);
|
||||
throw new RuntimeException("导出生日签名表失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public int sendByQuery(UserBirthdaySendMsgForm form, String pushBy, String pushByName) {
|
||||
@@ -162,11 +223,21 @@ public class UserBirthdayServiceImpl extends BaseServiceImpl<Sys_user> implement
|
||||
u.sex AS sex,
|
||||
u.birthday AS birthday,
|
||||
u.mobile AS mobile,
|
||||
u.unitId AS unitId,
|
||||
u.unitCode AS unitCode,
|
||||
u.unitName AS unitName,
|
||||
u.unionName AS unionName,
|
||||
u.userState AS userState,
|
||||
u.personType AS personType,
|
||||
u.preparedBy AS preparedBy,
|
||||
CASE
|
||||
WHEN birthdayCampus.campusId = 'cx' THEN '长兴校区'
|
||||
WHEN birthdayCampus.campusId = 'hz' THEN '杭州校区'
|
||||
WHEN TRIM(IFNULL(u.unitName, '')) LIKE '智能制造学院%' THEN '长兴校区'
|
||||
ELSE '杭州校区'
|
||||
END AS campusName,
|
||||
birthdayCampus.campusId AS birthdayCampusId,
|
||||
COALESCE(birthdayUnit.birthdaySortNo, 999999) AS unitSortNo,
|
||||
DATEDIFF(
|
||||
CASE
|
||||
WHEN DATE_FORMAT(u.birthday, '%m-%d') >= DATE_FORMAT(NOW(), '%m-%d')
|
||||
@@ -176,18 +247,385 @@ public class UserBirthdayServiceImpl extends BaseServiceImpl<Sys_user> implement
|
||||
CURDATE()
|
||||
) AS daysUntilBirthday
|
||||
FROM vw_user u
|
||||
LEFT JOIN sys_unit birthdayUnit ON birthdayUnit.id = u.unitId
|
||||
LEFT JOIN user_birthday_campus birthdayCampus
|
||||
ON birthdayCampus.loginname = u.loginname
|
||||
AND IFNULL(birthdayCampus.delFlag, 0) = 0
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("u.birthday", "is not", null);
|
||||
cnd.and("u.member", "=", 1);
|
||||
pageForm.buildSearch(cnd, "u.");
|
||||
pageForm.buildCampusSearch(cnd, "u.");
|
||||
pageForm.buildBirthdaySearch(cnd, getConfig().getBirthdayDays());
|
||||
cnd.asc("unitSortNo");
|
||||
cnd.asc("u.unitCode");
|
||||
cnd.asc("daysUntilBirthday");
|
||||
sql.setCondition(cnd);
|
||||
return sql;
|
||||
}
|
||||
|
||||
private Workbook createXssfWorkbook(ExportParams exportParams) {
|
||||
if (!ExcelType.XSSF.equals(exportParams.getType())) {
|
||||
throw new IllegalArgumentException("生日名单只支持 XSSF 格式");
|
||||
}
|
||||
return new XSSFWorkbook();
|
||||
}
|
||||
|
||||
private List<NutMap> filterList(List<NutMap> list, Predicate<NutMap> predicate) {
|
||||
return list.stream().filter(predicate).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用单位别名替换导出数据中的原单位名称,未配置别名时保留查询结果。
|
||||
*/
|
||||
private void fillExportUnitName(List<NutMap> list) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> aliasMap = loadSysUnitAliasMap();
|
||||
for (NutMap row : list) {
|
||||
String aliasName = aliasMap.get(getMapString(row, "unitId"));
|
||||
if (StrUtil.isNotBlank(aliasName)) {
|
||||
row.setv("unitName", aliasName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, String> loadSysUnitAliasMap() {
|
||||
Map<String, String> aliasMap = new HashMap<>();
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
id,
|
||||
aliasName
|
||||
FROM sys_unit
|
||||
WHERE IFNULL(aliasName, '') <> ''
|
||||
""");
|
||||
sql.setCallback(Sqls.callback.maps());
|
||||
dao().execute(sql);
|
||||
for (NutMap item : sql.getList(NutMap.class)) {
|
||||
aliasMap.put(getMapString(item, "id"), getMapString(item, "aliasName"));
|
||||
}
|
||||
return aliasMap;
|
||||
}
|
||||
|
||||
private boolean isHangzhouCampus(NutMap row) {
|
||||
return !isChangxingCampus(row);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校区标记表优先;没有标记时,智能制造学院人员归入长兴校区,其余归入杭州校区。
|
||||
*/
|
||||
private boolean isChangxingCampus(NutMap row) {
|
||||
String campusName = getMapString(row, "campusName");
|
||||
if (StrUtil.equalsAnyIgnoreCase(campusName, "cx", "长兴校区")) {
|
||||
return true;
|
||||
}
|
||||
if (StrUtil.equalsAnyIgnoreCase(campusName, "hz", "杭州校区")) {
|
||||
return false;
|
||||
}
|
||||
String campusId = getMapString(row, "birthdayCampusId");
|
||||
if (StrUtil.equalsAnyIgnoreCase(campusId, "cx", "长兴校区")) {
|
||||
return true;
|
||||
}
|
||||
if (StrUtil.equalsAnyIgnoreCase(campusId, "hz", "杭州校区")) {
|
||||
return false;
|
||||
}
|
||||
String unitName = StrUtil.trim(getMapString(row, "unitName"));
|
||||
return StrUtil.isNotBlank(unitName) && unitName.startsWith("智能制造学院");
|
||||
}
|
||||
|
||||
private String getCampusDisplayName(NutMap row) {
|
||||
return isChangxingCampus(row) ? "长兴校区" : "杭州校区";
|
||||
}
|
||||
|
||||
private String getCampusDisplayName(String campusValue) {
|
||||
if (StrUtil.equalsAnyIgnoreCase(campusValue, "cx", "长兴校区")) {
|
||||
return "长兴校区";
|
||||
}
|
||||
if (StrUtil.equalsAnyIgnoreCase(campusValue, "hz", "杭州校区")) {
|
||||
return "杭州校区";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建带序号的校区生日名单 Sheet。
|
||||
*/
|
||||
private void createBirthdaySheet(Workbook workbook, String sheetName, List<NutMap> list) {
|
||||
Sheet sheet = workbook.createSheet(sheetName);
|
||||
String[] titles = {"序号", "工号", "姓名", "性别", "联系方式", "出生年月", "生日倒计时(天)", "所属校区", "所属工会", "所属单位"};
|
||||
String[] fields = {"loginname", "username", "sex", "mobile", "birthday", "daysUntilBirthday", "campusName", "unionName", "unitName"};
|
||||
|
||||
CellStyle headerStyle = workbook.createCellStyle();
|
||||
Font font = workbook.createFont();
|
||||
font.setBold(true);
|
||||
headerStyle.setFont(font);
|
||||
headerStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||
|
||||
Row header = sheet.createRow(0);
|
||||
for (int i = 0; i < titles.length; i++) {
|
||||
Cell cell = header.createCell(i);
|
||||
cell.setCellValue(titles[i]);
|
||||
cell.setCellStyle(headerStyle);
|
||||
sheet.setColumnWidth(i, 18 * 256);
|
||||
}
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
NutMap item = list.get(i);
|
||||
Row row = sheet.createRow(i + 1);
|
||||
row.createCell(0).setCellValue(i + 1);
|
||||
for (int j = 0; j < fields.length; j++) {
|
||||
String value = "campusName".equals(fields[j])
|
||||
? getCampusDisplayName(item)
|
||||
: getMapString(item, fields[j]);
|
||||
row.createCell(j + 1).setCellValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 签名表按校区和日期范围控制 Sheet:长兴校区保持单 Sheet,杭州校区跨月时按月份拆分。
|
||||
*/
|
||||
private void createSignatureSheets(Workbook workbook, String exportName, UserBirthdayPageForm pageForm,
|
||||
DateRange dateRange, String campusDisplayName) {
|
||||
if (StrUtil.equals(campusDisplayName, "长兴校区") || isSameMonth(dateRange.start, dateRange.end)) {
|
||||
createSignatureSheetByRange(workbook, exportName, pageForm, dateRange, campusDisplayName);
|
||||
return;
|
||||
}
|
||||
|
||||
YearMonth month = YearMonth.from(dateRange.start);
|
||||
YearMonth endMonth = YearMonth.from(dateRange.end);
|
||||
while (!month.isAfter(endMonth)) {
|
||||
LocalDate monthStart = month.equals(YearMonth.from(dateRange.start)) ? dateRange.start : month.atDay(1);
|
||||
LocalDate monthEnd = month.equals(endMonth) ? dateRange.end : month.atEndOfMonth();
|
||||
DateRange monthRange = new DateRange(monthStart, monthEnd,
|
||||
buildSignatureFileName(monthStart, monthEnd), buildSignatureDisplayPeriod(monthStart, monthEnd));
|
||||
createSignatureSheetByRange(workbook, month.format(DateTimeFormatter.ofPattern("M月")),
|
||||
pageForm, monthRange, campusDisplayName);
|
||||
month = month.plusMonths(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按指定 MM-dd 生日范围查询人员并创建签名表 Sheet。
|
||||
*/
|
||||
private void createSignatureSheetByRange(Workbook workbook, String sheetName, UserBirthdayPageForm pageForm,
|
||||
DateRange dateRange, String campusDisplayName) {
|
||||
pageForm.setStartDate(dateRange.start.format(DateTimeFormatter.ISO_LOCAL_DATE));
|
||||
pageForm.setEndDate(dateRange.end.format(DateTimeFormatter.ISO_LOCAL_DATE));
|
||||
List<NutMap> list = listMap(buildBirthdaySql(pageForm));
|
||||
fillExportUnitName(list);
|
||||
createSignatureSheet(workbook, sheetName, list, dateRange.displayPeriod, campusDisplayName);
|
||||
}
|
||||
|
||||
private void createSignatureSheet(Workbook workbook, String sheetName, List<NutMap> list,
|
||||
String displayPeriod, String campusDisplayName) {
|
||||
Sheet sheet = workbook.createSheet(sheetName);
|
||||
sheet.setColumnWidth(0, 8 * 256);
|
||||
sheet.setColumnWidth(1, 18 * 256);
|
||||
sheet.setColumnWidth(2, 12 * 256);
|
||||
sheet.setColumnWidth(3, 16 * 256);
|
||||
sheet.setColumnWidth(4, 8 * 256);
|
||||
sheet.setColumnWidth(5, 18 * 256);
|
||||
sheet.setColumnWidth(6, 12 * 256);
|
||||
sheet.setColumnWidth(7, 16 * 256);
|
||||
|
||||
CellStyle titleStyle = createCellStyle(workbook, true, (short) 16, false);
|
||||
CellStyle subtitleStyle = createCellStyle(workbook, false, (short) 12, false);
|
||||
CellStyle headerStyle = createCellStyle(workbook, true, (short) 11, true);
|
||||
CellStyle contentStyle = createCellStyle(workbook, false, (short) 11, true);
|
||||
|
||||
Row titleRow = sheet.createRow(0);
|
||||
titleRow.setHeightInPoints(28);
|
||||
createCell(titleRow, 0, buildSignatureTitle(campusDisplayName), titleStyle);
|
||||
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 7));
|
||||
|
||||
Row subtitleRow = sheet.createRow(1);
|
||||
subtitleRow.setHeightInPoints(22);
|
||||
createCell(subtitleRow, 0, buildSignatureSubtitle(displayPeriod), subtitleStyle);
|
||||
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, 7));
|
||||
|
||||
String[] headers = {"序号", "部门", "姓名", "签名", "序号", "部门", "姓名", "签名"};
|
||||
Row headerRow = sheet.createRow(2);
|
||||
headerRow.setHeightInPoints(22);
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
createCell(headerRow, i, headers[i], headerStyle);
|
||||
}
|
||||
|
||||
int leftSize = (list.size() + 1) / 2;
|
||||
for (int i = 0; i < leftSize; i++) {
|
||||
Row row = sheet.createRow(i + 3);
|
||||
row.setHeightInPoints(22);
|
||||
fillSignatureRow(row, 0, i, getListItem(list, i), contentStyle);
|
||||
fillSignatureRow(row, 4, i + leftSize, getListItem(list, i + leftSize), contentStyle);
|
||||
}
|
||||
}
|
||||
|
||||
private void fillSignatureRow(Row row, int startColumn, int index, NutMap item, CellStyle contentStyle) {
|
||||
if (item == null) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
createCell(row, startColumn + i, "", contentStyle);
|
||||
}
|
||||
return;
|
||||
}
|
||||
createCell(row, startColumn, String.valueOf(index + 1), contentStyle);
|
||||
createCell(row, startColumn + 1, getDepartmentName(item), contentStyle);
|
||||
createCell(row, startColumn + 2, getMapString(item, "username"), contentStyle);
|
||||
createCell(row, startColumn + 3, "", contentStyle);
|
||||
}
|
||||
|
||||
private NutMap getListItem(List<NutMap> list, int index) {
|
||||
if (index < 0 || index >= list.size()) {
|
||||
return null;
|
||||
}
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
private String getDepartmentName(NutMap item) {
|
||||
String departmentName = getMapString(item, "unitName");
|
||||
if (StrUtil.isBlank(departmentName)) {
|
||||
departmentName = getMapString(item, "unionName");
|
||||
}
|
||||
return departmentName;
|
||||
}
|
||||
|
||||
private CellStyle createCellStyle(Workbook workbook, boolean bold, short fontSize, boolean border) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setAlignment(HorizontalAlignment.CENTER);
|
||||
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||
if (border) {
|
||||
style.setBorderTop(BorderStyle.THIN);
|
||||
style.setBorderBottom(BorderStyle.THIN);
|
||||
style.setBorderLeft(BorderStyle.THIN);
|
||||
style.setBorderRight(BorderStyle.THIN);
|
||||
}
|
||||
Font font = workbook.createFont();
|
||||
font.setBold(bold);
|
||||
font.setFontHeightInPoints(fontSize);
|
||||
style.setFont(font);
|
||||
return style;
|
||||
}
|
||||
|
||||
private void createCell(Row row, int columnIndex, String value, CellStyle style) {
|
||||
Cell cell = row.createCell(columnIndex);
|
||||
cell.setCellValue(StrUtil.blankToDefault(value, ""));
|
||||
cell.setCellStyle(style);
|
||||
}
|
||||
|
||||
private boolean isSameMonth(LocalDate start, LocalDate end) {
|
||||
return start.getYear() == end.getYear() && start.getMonthValue() == end.getMonthValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 未指定日期时默认导出下月;下月为一月时覆盖一至二月,下月为六月时覆盖六至八月。
|
||||
*/
|
||||
private DateRange buildSignatureDateRange(UserBirthdayPageForm pageForm) {
|
||||
if (StrUtil.isAllNotBlank(pageForm.getStartDate(), pageForm.getEndDate())) {
|
||||
LocalDate start = LocalDate.parse(pageForm.getStartDate());
|
||||
LocalDate end = LocalDate.parse(pageForm.getEndDate());
|
||||
return new DateRange(start, end, buildSignatureFileName(start, end),
|
||||
buildSignatureDateDisplayPeriod(start, end));
|
||||
}
|
||||
|
||||
LocalDate now = LocalDate.now();
|
||||
YearMonth nextMonth = YearMonth.from(now).plusMonths(1);
|
||||
int month = nextMonth.getMonthValue();
|
||||
LocalDate start = nextMonth.atDay(1);
|
||||
LocalDate end;
|
||||
if (month == 1) {
|
||||
end = nextMonth.plusMonths(1).atEndOfMonth();
|
||||
} else if (month == 6) {
|
||||
end = nextMonth.plusMonths(2).atEndOfMonth();
|
||||
} else {
|
||||
end = nextMonth.atEndOfMonth();
|
||||
}
|
||||
return new DateRange(start, end, buildSignatureFileName(start, end),
|
||||
buildSignatureDisplayPeriod(start, end));
|
||||
}
|
||||
|
||||
private String buildSignatureFileName(LocalDate start, LocalDate end) {
|
||||
if (isSameMonth(start, end)) {
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月"));
|
||||
}
|
||||
if (start.getYear() == end.getYear()) {
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月")) + "-" +
|
||||
end.format(DateTimeFormatter.ofPattern("M月"));
|
||||
}
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月")) + "-" +
|
||||
end.format(DateTimeFormatter.ofPattern("yyyy年M月"));
|
||||
}
|
||||
|
||||
private String buildSignatureDisplayPeriod(LocalDate start, LocalDate end) {
|
||||
if (isSameMonth(start, end)) {
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月"));
|
||||
}
|
||||
if (start.getYear() == end.getYear()) {
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M")) + "-" +
|
||||
end.format(DateTimeFormatter.ofPattern("M月"));
|
||||
}
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月")) + "-" +
|
||||
end.format(DateTimeFormatter.ofPattern("yyyy年M月"));
|
||||
}
|
||||
|
||||
private String buildSignatureDateDisplayPeriod(LocalDate start, LocalDate end) {
|
||||
if (start.equals(end)) {
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月d日"));
|
||||
}
|
||||
if (isSameMonth(start, end)) {
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月d日")) + "-" +
|
||||
end.format(DateTimeFormatter.ofPattern("d日"));
|
||||
}
|
||||
if (start.getYear() == end.getYear()) {
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月d日")) + "-" +
|
||||
end.format(DateTimeFormatter.ofPattern("M月d日"));
|
||||
}
|
||||
return start.format(DateTimeFormatter.ofPattern("yyyy年M月d日")) + "-" +
|
||||
end.format(DateTimeFormatter.ofPattern("yyyy年M月d日"));
|
||||
}
|
||||
|
||||
private String buildSignatureTitle(String campusDisplayName) {
|
||||
if (StrUtil.isBlank(campusDisplayName)) {
|
||||
return "浙江交通职业技术学院职工生日蛋糕券发放名单";
|
||||
}
|
||||
return "浙江交通职业技术学院" + campusDisplayName + "职工生日蛋糕券发放名单";
|
||||
}
|
||||
|
||||
private String buildSignatureSubtitle(String displayPeriod) {
|
||||
return "(发放时间:" + displayPeriod + ")";
|
||||
}
|
||||
|
||||
private void writeWorkbook(HttpServletResponse response, Workbook workbook, String fileName) throws Exception {
|
||||
String encodeFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + encodeFileName);
|
||||
workbook.write(response.getOutputStream());
|
||||
}
|
||||
|
||||
private String getMapString(NutMap row, String key) {
|
||||
String value = row.getString(key);
|
||||
if (StrUtil.isBlank(value)) {
|
||||
value = row.getString(key.toLowerCase());
|
||||
}
|
||||
return StrUtil.blankToDefault(value, "");
|
||||
}
|
||||
|
||||
private static class DateRange {
|
||||
private final LocalDate start;
|
||||
private final LocalDate end;
|
||||
private final String fileName;
|
||||
private final String displayPeriod;
|
||||
|
||||
private DateRange(LocalDate start, LocalDate end, String fileName, String displayPeriod) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.fileName = fileName;
|
||||
this.displayPeriod = displayPeriod;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 补齐历史配置缺失的默认值,保证配置页、手动发送和定时任务使用同一套参数。
|
||||
*/
|
||||
|
||||
@@ -732,6 +732,7 @@
|
||||
</main>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<!--
|
||||
<footer class="v4-footer" id="v4-footer" style="display: none;">
|
||||
<div class="v4-footer-bottom">
|
||||
<div class="v4-footer-copyright">
|
||||
@@ -744,6 +745,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
-->
|
||||
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
|
||||
@@ -153,7 +153,7 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
|
||||
<work-template v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN'])"></work-template>
|
||||
|
||||
<jcdt :list="websiteNews"></jcdt>
|
||||
<!-- <jcdt :list="websiteNews"></jcdt> -->
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -184,7 +184,7 @@ layout("/layouts/v4/baseLayout.html"){
|
||||
'stats': stats,
|
||||
},
|
||||
mounted() {
|
||||
this.getWebSiteNews()
|
||||
// this.getWebSiteNews()
|
||||
},
|
||||
methods: {
|
||||
getWebSiteNews(){
|
||||
|
||||
@@ -174,10 +174,18 @@ layout("/layouts/platform.html"){
|
||||
methods: {
|
||||
getTreeData() {
|
||||
this.$axios.post(loc() + "/tree").then((res) => {
|
||||
this.treeData = res.data
|
||||
if (this.treeData) {
|
||||
this.currentTreeData = this.treeData[0]
|
||||
this.defaultExpandedKeys = this.treeData.length > 0 ? [this.treeData[0].id] : []
|
||||
this.$set(this, "treeData", res.data)
|
||||
if (this.treeData && this.treeData.length > 0) {
|
||||
const rootNode = this.treeData[0]
|
||||
this.$set(this, "currentTreeData", rootNode)
|
||||
this.$set(this, "defaultExpandedKeys", [rootNode.id])
|
||||
// 树节点异步渲染完成后选中根节点,保证首次进入页面时显示当前节点高亮。
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.treeRef) {
|
||||
this.$refs.treeRef.setCurrentKey(rootNode.id)
|
||||
this.$set(this, "currentTreeNode", this.$refs.treeRef.getNode(rootNode.id))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1,31 +1,92 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
<style scoped>
|
||||
.custom-tree {
|
||||
background: transparent;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* 统一单位树节点的间距、圆角和交互过渡效果。 */
|
||||
.custom-tree .el-tree-node {
|
||||
margin: 2px 0;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.custom-tree .el-tree-node.is-current > .el-tree-node__content {
|
||||
background: #e8f4ff;
|
||||
border-left: 3px solid #409eff;
|
||||
}
|
||||
|
||||
.custom-tree .el-tree-node__content {
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
padding: 0 8px;
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.custom-tree-node {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.el-icon-folder {
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.el-icon-folder-opened {
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.custom-tree .el-tree-node__expand-icon {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.custom-tree .el-tree-node__expand-icon.expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.node-label {
|
||||
flex: 1;
|
||||
font-size: 13px;
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.custom-tree .el-tree-node__expand-icon.is-leaf {
|
||||
color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-row :gutter="10" type="flex" style="height: calc(100vh - 126px)">
|
||||
<el-col :span="5">
|
||||
<el-card shadow="never" style="height: 100%" body-style="{ height: '100%' }">
|
||||
<div style="max-height: calc(100vh - 160px); overflow-y: auto">
|
||||
<el-card shadow="never">
|
||||
<el-input placeholder="输入关键字进行查找" v-model="filterText" clearable></el-input>
|
||||
<div style="max-height: calc(100vh - 200px); overflow-y: auto">
|
||||
<el-tree
|
||||
:data="treeData"
|
||||
:default-expanded-keys="['1']"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:expand-on-click-node="false"
|
||||
:props="{
|
||||
children: 'child',
|
||||
label: 'name'
|
||||
}"
|
||||
:filter-node-method="filterNode"
|
||||
:props="{children: 'children', label: 'name'}"
|
||||
@node-click="treeNodeClick"
|
||||
class="custom-tree"
|
||||
highlight-current
|
||||
node-key="id"
|
||||
ref="treeRef"
|
||||
>
|
||||
<template slot-scope="{ node, data }">
|
||||
<span class="el-tree-node__label">
|
||||
<i class="el-icon-folder-opened" v-if="node.level===1"></i>
|
||||
<i class="el-icon-folder" v-else></i>
|
||||
{{node.label}}
|
||||
</span>
|
||||
<span class="custom-tree-node">
|
||||
<i class="el-icon-folder-opened" v-if="node.level===1"></i>
|
||||
<i class="el-icon-folder" v-else></i>
|
||||
<span class="node-label">{{node.label}}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</div>
|
||||
@@ -97,44 +158,69 @@ layout("/layouts/platform.html"){
|
||||
pageForm: {
|
||||
searchName: "name"
|
||||
},
|
||||
filterText: null,
|
||||
defaultExpandedKeys: [],
|
||||
treeData: [],
|
||||
currentTreeNode: null,
|
||||
currentTreeData: null
|
||||
}
|
||||
},
|
||||
components: {},
|
||||
watch: {
|
||||
filterText(val) {
|
||||
this.$refs.treeRef.filter(val)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async doDelete(id) {
|
||||
const confirm = await this.$confirm("确定要删除该单位吗?", "提示", {
|
||||
doDelete(id) {
|
||||
this.$confirm("确定要删除该单位吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
if (confirm === "confirm") {
|
||||
const resp = await this.$axios.post(loc() + "/doDelete", { id })
|
||||
if (resp.code === 0) {
|
||||
this.getTreeData()
|
||||
this.doSearch()
|
||||
this.$message.success(resp.msg)
|
||||
} else {
|
||||
this.notifyWarning(resp.msg)
|
||||
}
|
||||
}
|
||||
}).then(() => {
|
||||
this.$set(this, "tableLoading", true)
|
||||
this.$axios.post(loc() + "/doDelete", {id: id}).then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.getTreeData()
|
||||
this.doSearch()
|
||||
this.$message.success(resp.msg)
|
||||
} else {
|
||||
this.notifyWarning(resp.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$set(this, "tableLoading", false)
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
treeNodeClick(data, node) {
|
||||
this.currentTreeData = data
|
||||
this.currentTreeNode = node
|
||||
this.pageForm.parentId = data.id
|
||||
this.$set(this, "currentTreeData", data)
|
||||
this.$set(this, "currentTreeNode", node)
|
||||
this.$set(this.pageForm, "parentId", data.id)
|
||||
this.doSearch()
|
||||
},
|
||||
getTreeData() {
|
||||
this.$axios.post(loc() + "/tree").then((res) => {
|
||||
this.treeData = res.data
|
||||
if (this.treeData) {
|
||||
this.currentTreeData = this.treeData[0]
|
||||
this.$set(this, "treeData", res.data)
|
||||
if (this.treeData && this.treeData.length > 0) {
|
||||
const rootNode = this.treeData[0]
|
||||
this.$set(this, "currentTreeData", rootNode)
|
||||
this.$set(this, "defaultExpandedKeys", [rootNode.id])
|
||||
// 树节点异步渲染完成后选中根节点,保证首次进入页面时显示当前节点高亮。
|
||||
this.$nextTick(() => {
|
||||
if (this.$refs.treeRef) {
|
||||
this.$refs.treeRef.setCurrentKey(rootNode.id)
|
||||
this.$set(this, "currentTreeNode", this.$refs.treeRef.getNode(rootNode.id))
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
filterNode(value, data) {
|
||||
if (!value) {
|
||||
return true
|
||||
}
|
||||
return data.name.indexOf(value) !== -1
|
||||
},
|
||||
openUnit() {}
|
||||
},
|
||||
created() {
|
||||
|
||||
@@ -57,12 +57,6 @@ layout("/layouts/platform.html"){
|
||||
<el-tab-pane label="活动模板列表" name="template"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<table-tool :label="canManageTemplate && activeTab === 'template' ? '活动模板列表' : '活动列表'">
|
||||
<el-button
|
||||
size="mini"
|
||||
type="primary"
|
||||
icon="el-icon-plus"
|
||||
@click="openAdd"
|
||||
v-if="!canManageTemplate || activeTab === 'activity'">创建活动</el-button>
|
||||
</table-tool>
|
||||
|
||||
<el-table :data="tableData" :height="tableHeight" @sort-change="pageOrder" ref="activityTableRef" style="width: 100%" row-key="id">
|
||||
@@ -444,38 +438,20 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
watch: {
|
||||
"formData.activityGroupId": {
|
||||
async handler(newVal, oldVal) {
|
||||
this.activityGroupList = await this.getActivityGroup()
|
||||
this.userScopeDialog = false
|
||||
handler(newVal, oldVal) {
|
||||
this.getActivityGroup().then((activityGroupList) => {
|
||||
this.activityGroupList = activityGroupList
|
||||
this.userScopeDialog = false
|
||||
})
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isNewPage() {
|
||||
return window.location.pathname.toLowerCase() === "/platform/activity/workscollection/new"
|
||||
},
|
||||
backToManage() {
|
||||
commonUtil.pjaxPush("/platform/activity/worksCollection/manage")
|
||||
},
|
||||
afterSaveSuccess() {
|
||||
this.formVisible = false
|
||||
if (this.isNewPage()) {
|
||||
this.backToManage()
|
||||
} else {
|
||||
this.doSearch()
|
||||
this.$refs.guava.index()
|
||||
}
|
||||
},
|
||||
initNewPage() {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const mode = params.get("mode")
|
||||
const id = params.get("id")
|
||||
if (mode === "edit" && id) {
|
||||
this.openEdit(id, true)
|
||||
} else {
|
||||
this.openAdd()
|
||||
}
|
||||
this.doSearch()
|
||||
this.$refs.guava.index()
|
||||
},
|
||||
getActivityGroup() {
|
||||
return this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup").then((res) => res.data)
|
||||
@@ -537,9 +513,9 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
})
|
||||
},
|
||||
async loadFormOptions() {
|
||||
loadFormOptions() {
|
||||
if (this.formOptionsLoaded) {
|
||||
return
|
||||
return Promise.resolve()
|
||||
}
|
||||
if (this.formOptionsPromise) {
|
||||
return this.formOptionsPromise
|
||||
@@ -589,22 +565,6 @@ layout("/layouts/platform.html"){
|
||||
|
||||
this.$set(worksType, "allowFileTypes", worksType.allowFileTypes ? worksType.allowFileTypes : [])
|
||||
},
|
||||
async openAdd() {
|
||||
this.copyTemplateMode = false
|
||||
this.copyTemplateName = ""
|
||||
await this.loadFormOptions()
|
||||
this.formVisible = true
|
||||
this.$refs.guava.edit()
|
||||
this.$nextTick(() => {
|
||||
this.formData = {
|
||||
nbCount: 0,
|
||||
activityColor: this.colorList[0],
|
||||
subjectTypes: [{worksTypes: [{}]}],
|
||||
enable: true
|
||||
}
|
||||
this.initData(this.formData.subjectTypes[0].worksTypes[0])
|
||||
})
|
||||
},
|
||||
cleanCopyTemplateData(data) {
|
||||
if (!data) {
|
||||
return
|
||||
@@ -666,37 +626,32 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
return data
|
||||
},
|
||||
async openEdit(id, copyTemplateMode = false) {
|
||||
openEdit(id, copyTemplateMode = false) {
|
||||
this.copyTemplateMode = !!copyTemplateMode
|
||||
const [resp] = await Promise.all([
|
||||
Promise.all([
|
||||
this.$axios.post("/platform/activity/worksCollection/manage/findOne", {id}),
|
||||
this.loadFormOptions()
|
||||
])
|
||||
this.formVisible = true
|
||||
this.formData = resp.data
|
||||
if (this.copyTemplateMode) {
|
||||
this.copyTemplateName = this.formData.name
|
||||
this.cleanCopyTemplateData(this.formData)
|
||||
} else {
|
||||
this.copyTemplateName = ""
|
||||
}
|
||||
this.$set(this.formData, "activityTime", [this.formData.startDateTime, this.formData.endDateTime])
|
||||
// this.formData.activityTime = [this.formData.startDateTime, this.formData.endDateTime]
|
||||
if (this.formData.nbStartDateTime && this.formData.nbEndDateTime) {
|
||||
// this.formData.nbTime = [this.formData.nbStartDateTime, this.formData.nbEndDateTime]
|
||||
this.$set(this.formData, "nbTime", [this.formData.nbStartDateTime, this.formData.nbEndDateTime])
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.guava.edit()
|
||||
]).then(([resp]) => {
|
||||
this.formVisible = true
|
||||
this.formData = resp.data
|
||||
if (this.copyTemplateMode) {
|
||||
this.copyTemplateName = this.formData.name
|
||||
this.cleanCopyTemplateData(this.formData)
|
||||
} else {
|
||||
this.copyTemplateName = ""
|
||||
}
|
||||
this.$set(this.formData, "activityTime", [this.formData.startDateTime, this.formData.endDateTime])
|
||||
if (this.formData.nbStartDateTime && this.formData.nbEndDateTime) {
|
||||
this.$set(this.formData, "nbTime", [this.formData.nbStartDateTime, this.formData.nbEndDateTime])
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.guava.edit()
|
||||
})
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.formVisible = false
|
||||
if (this.isNewPage()) {
|
||||
this.backToManage()
|
||||
} else {
|
||||
this.$refs.guava.index()
|
||||
}
|
||||
this.$refs.guava.index()
|
||||
},
|
||||
doSubmit() {
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
@@ -718,6 +673,7 @@ layout("/layouts/platform.html"){
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.close()
|
||||
})
|
||||
}
|
||||
@@ -741,6 +697,7 @@ layout("/layouts/platform.html"){
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.close()
|
||||
})
|
||||
},
|
||||
@@ -823,25 +780,15 @@ layout("/layouts/platform.html"){
|
||||
return this.$axios.post("/platform/club/examine/apply/getClubsByRole").then((resp) => resp.data)
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
if (!this.isNewPage() && this.canManageTemplate) {
|
||||
created() {
|
||||
if (this.canManageTemplate) {
|
||||
// 有模板管理角色时默认进入活动列表,只展示未设置模板的活动。
|
||||
this.$set(this.pageForm, "templateStatus", 0)
|
||||
}
|
||||
if (this.isNewPage()) {
|
||||
await this.loadFormOptions()
|
||||
this.$nextTick(() => {
|
||||
this.initNewPage()
|
||||
})
|
||||
} else {
|
||||
this.pageData()
|
||||
this.loadFormOptions()
|
||||
}
|
||||
this.pageData()
|
||||
this.loadFormOptions()
|
||||
},
|
||||
mounted() {
|
||||
if (this.isNewPage()) {
|
||||
return
|
||||
}
|
||||
const listCardBody = this.$el.querySelector(".works-collection-list-card > .el-card__body")
|
||||
if (listCardBody && window.ResizeObserver) {
|
||||
// 查询区换行、页签权限或窗口变化时同步调整表格内部滚动区域。
|
||||
|
||||
@@ -0,0 +1,570 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card v-loading="formLoading" shadow="never">
|
||||
<div slot="header">
|
||||
<span>{{pageTitle}}</span>
|
||||
</div>
|
||||
<div v-if="formVisible">
|
||||
<el-form :model="formData" ref="formRef" label-width="130px" :rules="formRules">
|
||||
<el-form-item label="活动主题" prop="name">
|
||||
<el-input placeholder="请输入活动主题" v-model="formData.name" clearable></el-input>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="活动时间" prop="activityTime">
|
||||
<el-date-picker
|
||||
:default-time="['00:00:00']"
|
||||
end-placeholder="结束时间"
|
||||
start-placeholder="开始时间"
|
||||
style="width: 100%"
|
||||
type="datetimerange"
|
||||
v-model="formData.activityTime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="点赞时间" prop="nbTime">
|
||||
<el-date-picker
|
||||
:default-time="['00:00:00']"
|
||||
end-placeholder="结束时间"
|
||||
start-placeholder="开始时间"
|
||||
style="width: 100%"
|
||||
type="datetimerange"
|
||||
v-model="formData.nbTime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="每人每日点赞次数" prop="nbCount">
|
||||
<el-input-number
|
||||
:min="0"
|
||||
placeholder="请输入每人每日点赞次数"
|
||||
style="width: 100%"
|
||||
v-model="formData.nbCount"
|
||||
></el-input-number>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="主题类型" prop="subjectTypes">
|
||||
<el-row class="pb5" v-for="(type,index) in formData.subjectTypes" :key="type.id">
|
||||
<el-col :span="20">
|
||||
<el-input placeholder="请输入名称" v-model="type.typeName"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="2" style="text-align: center">
|
||||
<el-button @click="addType(index)" icon="el-icon-plus" type="primary"></el-button>
|
||||
</el-col>
|
||||
<el-col :span="2" style="text-align: center">
|
||||
<el-button
|
||||
:disabled="index == 0"
|
||||
@click="formData.subjectTypes.splice(index,1)"
|
||||
icon="el-icon-delete"
|
||||
type="danger"
|
||||
></el-button>
|
||||
</el-col>
|
||||
<el-col class="pt5 pb5">
|
||||
<el-row class="pb5" v-for="(worksType,worksIndex) in type.worksTypes" :key="worksType.id">
|
||||
<el-col :span="18">
|
||||
<el-col :span="2">
|
||||
<span class="el-form-item__label" v-if="worksIndex === 0">作品类型</span>
|
||||
<span v-else> </span>
|
||||
</el-col>
|
||||
<el-col :span="22">
|
||||
<el-input placeholder="请输入名称" v-model="worksType.worksTypeName"></el-input>
|
||||
</el-col>
|
||||
</el-col>
|
||||
<el-col :span="2" style="text-align: center">
|
||||
<el-button @click="openSetting(worksType)" icon="el-icon-s-tools"
|
||||
type="primary"></el-button>
|
||||
</el-col>
|
||||
<el-col :span="2" style="text-align: center">
|
||||
<el-button @click="addWorksType(type, worksIndex)" icon="el-icon-plus"
|
||||
type="primary"></el-button>
|
||||
</el-col>
|
||||
<el-col :span="2" style="text-align: center">
|
||||
<el-button @click="type.worksTypes.splice(worksIndex, 1)" icon="el-icon-delete"
|
||||
type="danger"></el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item label="面向对象" prop="joinCnd">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<div style="width: 99%">
|
||||
<el-select clearable filterable placeholder="请选择参加人员范围" style="width: 99%"
|
||||
v-model="formData.activityGroupId">
|
||||
<el-option
|
||||
:label="item.groupName"
|
||||
:value="item.groupId"
|
||||
v-for="item in activityGroupList"
|
||||
:key="item.groupId"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="$refs.drawerUserScope.userScopeDialog = true" type="primary">设置
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="hostUnitIds" label="主办单位">
|
||||
<el-select v-model="formData.hostUnitIds" clearable filterable multiple
|
||||
placeholder="请选择主办单位"
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in unitOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="undertakeUnitIds" label="承办单位">
|
||||
<el-select v-model="formData.undertakeUnitIds" clearable filterable multiple
|
||||
placeholder="请选择承办单位"
|
||||
style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in unitOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item label="活动内容" prop="content">
|
||||
<text-editor v-model="formData.content"></text-editor>
|
||||
</el-form-item>
|
||||
<!--<el-form-item label="活动介绍" prop="introduce">
|
||||
<text-editor v-model="formData.introduce"></text-editor>
|
||||
</el-form-item>
|
||||
<el-form-item label="奖励方式" prop="rewardMethod">
|
||||
<text-editor v-model="formData.rewardMethod"></text-editor>
|
||||
</el-form-item>-->
|
||||
<el-form-item label="活动封面">
|
||||
<file-upload
|
||||
:upload_number="1"
|
||||
:value.sync="formData.cover"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
complete_result
|
||||
upload_mode="image"
|
||||
upload_result_category="interval"
|
||||
></file-upload>
|
||||
</el-form-item>
|
||||
<el-form-item label="配色" prop="activityColor">
|
||||
<el-color-picker v-model="formData.activityColor" show-alpha></el-color-picker>
|
||||
</el-form-item>
|
||||
<el-form-item prop="enable" label="状态">
|
||||
<el-radio-group v-model="formData.enable" size="small">
|
||||
<el-radio :label="true" border>开启</el-radio>
|
||||
<el-radio :label="false" border>关闭</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="close">取消</el-button>
|
||||
<el-button type="primary" v-if="copyTemplateMode || formData.isSubmit!=true" plain @click="doSave">{{ copyTemplateMode ? "另存为" : "保存" }}</el-button>
|
||||
<el-button type="primary" @click="doSubmit">{{ copyTemplateMode ? "新活动提交" : "确定" }}</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
|
||||
<drawer-user-scope v-if="formVisible" :group_id.sync="formData.activityGroupId" @group_change="getActivityGroup"
|
||||
ref="drawerUserScope"></drawer-user-scope>
|
||||
|
||||
<el-dialog v-if="formVisible" :close-on-click-modal="false" :visible.sync="settingDialogVisible" title="更多设置" top="4%" width="40%">
|
||||
<el-form :model="currentWorksType" label-width="160px" size="small">
|
||||
<el-form-item label="作品介绍最多字数">
|
||||
<el-input-number :max="10000" :min="1" style="width: 100%"
|
||||
v-model="currentWorksType.maxWordCount"></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="允许上传的文件类型" prop="allowFileTypes">
|
||||
<el-checkbox-group v-model="currentWorksType.allowFileTypes">
|
||||
<el-checkbox key="jpg" label="jpg">jpg</el-checkbox>
|
||||
<el-checkbox key="jpeg" label="jpeg">jpeg</el-checkbox>
|
||||
<el-checkbox key="png" label="png">png</el-checkbox>
|
||||
<el-checkbox key="mp3" label="mp3">mp3</el-checkbox>
|
||||
<el-checkbox key="mp4" label="mp4">mp4</el-checkbox>
|
||||
<el-checkbox key="docx" label="docx">docx</el-checkbox>
|
||||
<el-checkbox key="xlsx" label="xlsx">xlsx</el-checkbox>
|
||||
<el-checkbox key="pdf" label="pdf">pdf</el-checkbox>
|
||||
<el-checkbox key="zip" label="zip">zip</el-checkbox>
|
||||
</el-checkbox-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="允许上传的文件数量" prop="allowFileNum">
|
||||
<el-input-number :max="10000" :min="1" style="width: 100%"
|
||||
v-model="currentWorksType.allowFileNum"></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="单个文件大小(kb)" prop="allowSingleFileSize">
|
||||
<el-input-number :min="1" style="width: 100%"
|
||||
v-model="currentWorksType.allowSingleFileSize"></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="总文件大小(kb)" prop="allowTotalFileSize">
|
||||
<el-input-number :min="1" style="width: 100%"
|
||||
v-model="currentWorksType.allowTotalFileSize"></el-input-number>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <div class="left-span-label">上传图片设置</div>-->
|
||||
|
||||
<!-- <el-form-item label="是否上传图片">-->
|
||||
<!-- <el-radio :label="true" border v-model="currentWorksType.isUploadPhoto">上传</el-radio>-->
|
||||
<!-- <el-radio :label="false" border v-model="currentWorksType.isUploadPhoto">不上传</el-radio>-->
|
||||
<!-- </el-form-item>-->
|
||||
|
||||
<!-- <template v-if="currentWorksType.isUploadPhoto === true">-->
|
||||
<!-- <el-form-item label="上传图片数量">-->
|
||||
<!-- <el-input-number :max="5" :min="1" style="width: 100%" v-model="currentWorksType.photoNum"></el-input-number>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="上传图片格式">-->
|
||||
<!-- <el-checkbox-group v-model="currentWorksType.photoType">-->
|
||||
<!-- <el-checkbox border key="jpg" label="jpg">jpg</el-checkbox>-->
|
||||
<!-- <el-checkbox border key="png" label="png">png</el-checkbox>-->
|
||||
<!-- <el-checkbox border key="jpeg" label="jpeg">jpeg</el-checkbox>-->
|
||||
<!-- </el-checkbox-group>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="每张图片大小">-->
|
||||
<!-- <el-input placeholder="请填写每张图片大小" type="number" v-model="currentWorksType.photoSize">-->
|
||||
<!-- <template slot="append">Mb</template>-->
|
||||
<!-- </el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </template>-->
|
||||
|
||||
<!-- <div class="left-span-label">上传音/视频、文档设置</div>-->
|
||||
|
||||
<!-- <el-form-item label="是否上传音/视频、文档">-->
|
||||
<!-- <el-radio :label="true" border v-model="currentWorksType.isUploadOther">上传</el-radio>-->
|
||||
<!-- <el-radio :label="false" border v-model="currentWorksType.isUploadOther">不上传</el-radio>-->
|
||||
<!-- </el-form-item>-->
|
||||
|
||||
<!-- <template v-if="currentWorksType.isUploadOther === true">-->
|
||||
<!-- <el-form-item label="文件上传数量">-->
|
||||
<!-- <el-input-number :max="5" :min="1" style="width: 100%" v-model="currentWorksType.otherFileNum"></el-input-number>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="上传文件格式">-->
|
||||
<!-- <el-checkbox-group v-model="currentWorksType.otherType">-->
|
||||
<!-- <el-checkbox key="mp3" label="mp3">mp3</el-checkbox>-->
|
||||
<!-- <el-checkbox key="mp4" label="mp4">mp4</el-checkbox>-->
|
||||
<!-- <el-checkbox key="docx" label="docx">docx</el-checkbox>-->
|
||||
<!-- <el-checkbox key="xlsx" label="xlsx">xlsx</el-checkbox>-->
|
||||
<!-- <el-checkbox key="pdf" label="pdf">pdf</el-checkbox>-->
|
||||
<!-- </el-checkbox-group>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- <el-form-item label="每个文件大小">-->
|
||||
<!-- <el-input placeholder="请填写每个文件大小" type="number" v-model="currentWorksType.otherSize">-->
|
||||
<!-- <template slot="append">Mb</template>-->
|
||||
<!-- </el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
</template>
|
||||
</el-form>
|
||||
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="settingDialogVisible=false">取消</el-button>
|
||||
<el-button @click="settingDialogVisible = false" type="primary">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
data() {
|
||||
return {
|
||||
activityGroupList: [],
|
||||
formRules: {
|
||||
name: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
activityTime: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
content: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
subjectTypes: [{required: true, message: "必填", trigger: ["change", "blur"]}],
|
||||
enable: [{required: true, message: "必填", trigger: ["change", "blur"]}]
|
||||
},
|
||||
currentWorksType: {
|
||||
allowFileTypes: []
|
||||
},
|
||||
settingDialogVisible: false,
|
||||
colorList: ["#081776", "#31cab1", "#e54242", "#ff8939", "#ffb712", "#1dc47b", "#4495f7", "#ff5e8b", "#5d6e7f"],
|
||||
formData: {},
|
||||
formLoading: false,
|
||||
formVisible: true,
|
||||
copyTemplateMode: false,
|
||||
copyTemplateName: "",
|
||||
formOptionsLoaded: false,
|
||||
formOptionsPromise: null,
|
||||
unitOptions: [],
|
||||
clubOptions: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pageTitle() {
|
||||
return this.copyTemplateMode ? "从模板创建作品征集活动" : "新建作品征集活动"
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"drawer-user-scope": httpVueLoader("/components/module/activity/DrawerUserScope.vue")
|
||||
},
|
||||
watch: {
|
||||
"formData.activityGroupId": {
|
||||
handler() {
|
||||
this.getActivityGroup().then((activityGroupList) => {
|
||||
this.activityGroupList = activityGroupList
|
||||
})
|
||||
},
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 初始化独立新建页面。
|
||||
* mode=edit 且携带 id 时表示从指定模板创建新活动;其他情况初始化空白活动。
|
||||
*/
|
||||
initPage() {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const mode = params.get("mode")
|
||||
const id = params.get("id")
|
||||
if (mode === "edit" && id) {
|
||||
this.loadTemplate(id)
|
||||
return
|
||||
}
|
||||
this.formLoading = true
|
||||
this.loadFormOptions().then(() => {
|
||||
this.initNewForm()
|
||||
}).finally(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
},
|
||||
initNewForm() {
|
||||
const worksType = {}
|
||||
this.initData(worksType)
|
||||
this.formData = {
|
||||
nbCount: 0,
|
||||
activityColor: this.colorList[0],
|
||||
subjectTypes: [{worksTypes: [worksType]}],
|
||||
enable: true
|
||||
}
|
||||
},
|
||||
loadTemplate(id) {
|
||||
this.formLoading = true
|
||||
Promise.all([
|
||||
this.$axios.post("/platform/activity/worksCollection/manage/findOne", {id: id}),
|
||||
this.loadFormOptions()
|
||||
]).then(([resp]) => {
|
||||
if (resp.code !== 0 || !resp.data) {
|
||||
this.$message.warning(resp.msg)
|
||||
return
|
||||
}
|
||||
this.copyTemplateMode = true
|
||||
this.copyTemplateName = resp.data.name
|
||||
this.formData = resp.data
|
||||
this.cleanCopyTemplateData(this.formData)
|
||||
this.$set(this.formData, "activityTime", [this.formData.startDateTime, this.formData.endDateTime])
|
||||
if (this.formData.nbStartDateTime && this.formData.nbEndDateTime) {
|
||||
this.$set(this.formData, "nbTime", [this.formData.nbStartDateTime, this.formData.nbEndDateTime])
|
||||
}
|
||||
}).finally(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
},
|
||||
getActivityGroup() {
|
||||
return this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup").then((res) => res.data)
|
||||
},
|
||||
getClubsByRole() {
|
||||
return this.$axios.post("/platform/club/examine/apply/getClubsByRole").then((resp) => resp.data)
|
||||
},
|
||||
loadFormOptions() {
|
||||
if (this.formOptionsLoaded) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
if (this.formOptionsPromise) {
|
||||
return this.formOptionsPromise
|
||||
}
|
||||
this.formOptionsPromise = Promise.all([
|
||||
this.getActivityGroup(),
|
||||
this.getClubsByRole(),
|
||||
this.$businessTool.listUnit()
|
||||
]).then(([activityGroupList, clubOptions, units]) => {
|
||||
this.activityGroupList = activityGroupList
|
||||
this.clubOptions = clubOptions
|
||||
this.clubOptions.map((item) => {
|
||||
this.$set(item, "name", item.clubName)
|
||||
})
|
||||
this.unitOptions = this.clubOptions.concat(units)
|
||||
this.formOptionsLoaded = true
|
||||
}).finally(() => {
|
||||
this.formOptionsPromise = null
|
||||
})
|
||||
return this.formOptionsPromise
|
||||
},
|
||||
addType(index) {
|
||||
const worksType = {}
|
||||
this.initData(worksType)
|
||||
this.formData.subjectTypes.splice(index + 1, 0, {worksTypes: [worksType]})
|
||||
},
|
||||
openSetting(worksType) {
|
||||
this.currentWorksType = worksType
|
||||
this.settingDialogVisible = true
|
||||
},
|
||||
addWorksType(type, worksIndex) {
|
||||
const worksType = {}
|
||||
this.initData(worksType)
|
||||
type.worksTypes.splice(worksIndex + 1, 0, worksType)
|
||||
},
|
||||
/**
|
||||
* 为作品类型补齐上传限制默认值,保证新建类型和模板类型使用相同的数据结构。
|
||||
*/
|
||||
initData(worksType) {
|
||||
this.$set(worksType, "maxWordCount", worksType.maxWordCount ? worksType.maxWordCount : 100)
|
||||
this.$set(worksType, "isUploadPhoto", worksType.isUploadPhoto ? worksType.isUploadPhoto : false)
|
||||
this.$set(worksType, "photoType", worksType.photoType ? worksType.photoType : ["jpg"])
|
||||
this.$set(worksType, "photoNum", worksType.photoNum ? worksType.photoNum : 1)
|
||||
this.$set(worksType, "photoSize", worksType.photoSize ? worksType.photoSize : 2)
|
||||
this.$set(worksType, "isUploadOther", worksType.isUploadOther ? worksType.isUploadOther : false)
|
||||
this.$set(worksType, "otherType", worksType.otherType ? worksType.otherType : ["mp4", "docx"])
|
||||
this.$set(worksType, "otherFileNum", worksType.otherFileNum ? worksType.otherFileNum : 1)
|
||||
this.$set(worksType, "otherSize", worksType.otherSize ? worksType.otherSize : 2)
|
||||
this.$set(worksType, "allowFileTypes", worksType.allowFileTypes ? worksType.allowFileTypes : [])
|
||||
},
|
||||
/**
|
||||
* 从模板创建时清理活动、主题和作品类型的主键及审计字段,避免覆盖模板原数据。
|
||||
*/
|
||||
cleanCopyTemplateData(data) {
|
||||
if (!data) {
|
||||
return
|
||||
}
|
||||
this.$set(data, "id", null)
|
||||
this.$set(data, "isTemplate", false)
|
||||
this.$set(data, "templateStatus", 0)
|
||||
this.$set(data, "createdBy", null)
|
||||
this.$set(data, "createdAt", null)
|
||||
this.$set(data, "updatedBy", null)
|
||||
this.$set(data, "updatedAt", null)
|
||||
this.$set(data, "delFlag", null)
|
||||
if (Array.isArray(data.subjectTypes)) {
|
||||
this.$set(data, "subjectTypes", data.subjectTypes.map((subjectType) => {
|
||||
this.$set(subjectType, "id", null)
|
||||
this.$set(subjectType, "activityId", null)
|
||||
this.$set(subjectType, "createdBy", null)
|
||||
this.$set(subjectType, "createdAt", null)
|
||||
this.$set(subjectType, "updatedBy", null)
|
||||
this.$set(subjectType, "updatedAt", null)
|
||||
this.$set(subjectType, "delFlag", null)
|
||||
if (Array.isArray(subjectType.worksTypes)) {
|
||||
this.$set(subjectType, "worksTypes", subjectType.worksTypes.map((worksType) => {
|
||||
this.$set(worksType, "id", null)
|
||||
this.$set(worksType, "subjectId", null)
|
||||
this.$set(worksType, "createdBy", null)
|
||||
this.$set(worksType, "createdAt", null)
|
||||
this.$set(worksType, "updatedBy", null)
|
||||
this.$set(worksType, "updatedAt", null)
|
||||
this.$set(worksType, "delFlag", null)
|
||||
return worksType
|
||||
}))
|
||||
}
|
||||
return subjectType
|
||||
}))
|
||||
}
|
||||
},
|
||||
validateCopyTemplateName() {
|
||||
if (!this.copyTemplateMode) {
|
||||
return true
|
||||
}
|
||||
const currentName = (this.formData.name || "").trim()
|
||||
const templateName = (this.copyTemplateName || "").trim()
|
||||
if (currentName && templateName && currentName === templateName) {
|
||||
this.$message.warning("请修改活动名称,不能与模板名称一致")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
/**
|
||||
* 将页面时间区间转换为后端活动实体字段;新建页面只调用 save 或 insert,不执行更新。
|
||||
*/
|
||||
buildSubmitData() {
|
||||
const data = clone(this.formData)
|
||||
this.$set(data, "startDateTime", data.activityTime[0])
|
||||
this.$set(data, "endDateTime", data.activityTime[1])
|
||||
this.$set(data, "nbStartDateTime", data.nbTime ? data.nbTime[0] : null)
|
||||
this.$set(data, "nbEndDateTime", data.nbTime ? data.nbTime[1] : null)
|
||||
this.$set(data, "type", "1")
|
||||
if (this.copyTemplateMode) {
|
||||
this.cleanCopyTemplateData(data)
|
||||
}
|
||||
return data
|
||||
},
|
||||
backToManage() {
|
||||
commonUtil.pjaxPush("/platform/activity/worksCollection/manage")
|
||||
},
|
||||
close() {
|
||||
this.backToManage()
|
||||
},
|
||||
doSubmit() {
|
||||
this.$refs.formRef.validate((valid) => {
|
||||
if (!valid || !this.validateCopyTemplateName()) {
|
||||
return
|
||||
}
|
||||
const submitData = this.buildSubmitData()
|
||||
this.formLoading = true
|
||||
this.$axios.post("/platform/activity/worksCollection/manage/insert", {
|
||||
data: JSON.stringify(submitData)
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.backToManage()
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
})
|
||||
},
|
||||
doSave() {
|
||||
if (!this.validateCopyTemplateName()) {
|
||||
return
|
||||
}
|
||||
const submitData = this.buildSubmitData()
|
||||
this.formLoading = true
|
||||
this.$axios.post("/platform/activity/worksCollection/manage/save", {
|
||||
data: JSON.stringify(submitData)
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.backToManage()
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.formLoading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initPage()
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -6,6 +6,12 @@ layout("/layouts/platform.html"){
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<search @search="searchBirthday">
|
||||
<search-item label="所属校区">
|
||||
<el-select v-model="pageForm.campusName" clearable filterable placeholder="请选择所属校区"
|
||||
style="width:100%" @change="searchBirthday">
|
||||
<el-option v-for="item in campuses" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="姓名/工号">
|
||||
<el-input v-model="pageForm.searchKeyword" clearable placeholder="请输入姓名或工号"></el-input>
|
||||
</search-item>
|
||||
@@ -26,9 +32,6 @@ layout("/layouts/platform.html"){
|
||||
<search-item label="人员类型">
|
||||
<dict-select v-model="queryForm.personTypes" code="USER_PERSON_TYPE" multiple placeholder="请选择人员类型"></dict-select>
|
||||
</search-item>
|
||||
<search-item label="人员性质">
|
||||
<dict-select v-model="queryForm.preparedBys" code="PREPARED_BY" multiple placeholder="请选择人员性质"></dict-select>
|
||||
</search-item>
|
||||
<search-item label="生日日期">
|
||||
<el-date-picker v-model="birthdayRange" type="daterange" value-format="yyyy-MM-dd"
|
||||
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期"
|
||||
@@ -40,7 +43,7 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool :label="'生日人员(默认展示未来' + birthdayDays + '天,日期查询忽略年份)'"
|
||||
:columns.sync="tableColumns">
|
||||
<el-button size="small" type="primary" @click="doExport">导出Excel</el-button>
|
||||
<!-- <el-button size="small" type="primary" @click="doExport">导出Excel</el-button>-->
|
||||
<el-button size="small" type="primary" @click="openSendByQuery">发送通知</el-button>
|
||||
</table-tool>
|
||||
<el-table ref="table" v-loading="tableLoading" :data="tableData" :size="tableSize"
|
||||
@@ -118,11 +121,11 @@ layout("/layouts/platform.html"){
|
||||
return {
|
||||
pageForm: {
|
||||
searchKeyword: "",
|
||||
campusName: "",
|
||||
unionId: "",
|
||||
unitId: "",
|
||||
userStates: "[]",
|
||||
personTypes: "[]",
|
||||
preparedBys: "[]",
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
pageNumber: 1,
|
||||
@@ -131,8 +134,12 @@ layout("/layouts/platform.html"){
|
||||
pageOrderName: "",
|
||||
pageOrderBy: ""
|
||||
},
|
||||
queryForm: {userStates:[],personTypes:[],preparedBys:[]},
|
||||
queryForm: {userStates:[],personTypes:[]},
|
||||
birthdayRange: [],
|
||||
campuses: [
|
||||
{id:"hz",name:"杭州校区"},
|
||||
{id:"cx",name:"长兴校区"}
|
||||
],
|
||||
unions: [],
|
||||
units: [],
|
||||
tableColumns: [
|
||||
@@ -144,7 +151,6 @@ layout("/layouts/platform.html"){
|
||||
{prop:"daysUntilBirthday",label:"生日倒计时(天)",sortable:true,width:"150"},
|
||||
{prop:"userState",label:"在职状态",width:"100"},
|
||||
{prop:"personType",label:"人员类型",width:"130"},
|
||||
{prop:"preparedBy",label:"人员性质",width:"130"},
|
||||
{prop:"unionName",label:"所属工会",width:"180"},
|
||||
{prop:"unitName",label:"所属单位",width:"180"}
|
||||
],
|
||||
@@ -195,7 +201,6 @@ layout("/layouts/platform.html"){
|
||||
searchBirthday() {
|
||||
this.$set(this.pageForm, "userStates", JSON.stringify(this.queryForm.userStates || []))
|
||||
this.$set(this.pageForm, "personTypes", JSON.stringify(this.queryForm.personTypes || []))
|
||||
this.$set(this.pageForm, "preparedBys", JSON.stringify(this.queryForm.preparedBys || []))
|
||||
this.doSearch()
|
||||
},
|
||||
requestParams() {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
|
||||
<common-query ref="commonQueryRef" @search="search"></common-query>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="申请列表">
|
||||
|
||||
-6
@@ -40,12 +40,6 @@
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" code="AIDFUND_MEMBER_USER_TYPE"
|
||||
style="width: 100%"></dict-select>
|
||||
</search-item>-->
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes" code="USER_ATTRIBUTE"
|
||||
multiple collapse-tags clearable style="width: 100%"></dict-select>
|
||||
<dict-select v-else v-model="pageForm.userAttribute" code="USER_ATTRIBUTE"
|
||||
clearable style="width: 100%"></dict-select>
|
||||
</search-item>
|
||||
</template>
|
||||
</search>
|
||||
</script>
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
const COMMON_QUERY = {
|
||||
template: "#member-apply-common-query-template",
|
||||
props: {
|
||||
// 默认保持原单选行为,仅由明确传参的页面开启人员属性多选。
|
||||
userAttributeMultiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
@@ -21,8 +14,6 @@ const COMMON_QUERY = {
|
||||
personTypes: [],
|
||||
preparedBys: [],
|
||||
aidFundMemberUserType: '',
|
||||
userAttribute: '',
|
||||
userAttributes: [],
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -32,7 +23,6 @@ const COMMON_QUERY = {
|
||||
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
|
||||
this.$emit('search', pageForm)
|
||||
},
|
||||
async initData(){
|
||||
|
||||
@@ -4,7 +4,7 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
|
||||
<common-query ref="commonQueryRef" @search="search"></common-query>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
|
||||
<common-query ref="commonQueryRef" @search="search"></common-query>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
|
||||
<common-query ref="commonQueryRef" @search="search"></common-query>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
|
||||
-7
@@ -29,12 +29,5 @@
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||
</search-item>-->
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-if="userAttributeMultiple" v-model="pageForm.userAttributes"
|
||||
placeholder="请选择人员属性" @change="doSearch" code="USER_ATTRIBUTE"
|
||||
multiple collapse-tags clearable></dict-select>
|
||||
<dict-select v-else v-model="pageForm.userAttribute" placeholder="请选择人员属性"
|
||||
@change="doSearch" code="USER_ATTRIBUTE"></dict-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</script>
|
||||
|
||||
-11
@@ -1,12 +1,5 @@
|
||||
const COMMON_QUERY = {
|
||||
template: "#member-change-common-query-template",
|
||||
props: {
|
||||
// 未显式开启时保持原单选行为,避免影响未列入本次范围的页面。
|
||||
userAttributeMultiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
@@ -21,8 +14,6 @@ const COMMON_QUERY = {
|
||||
personTypes: [],
|
||||
preparedBys: [],
|
||||
aidFundMemberUserType: '',
|
||||
userAttribute: '',
|
||||
userAttributes: [],
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -32,8 +23,6 @@ const COMMON_QUERY = {
|
||||
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
|
||||
// 多选人员属性沿用现有数组查询参数的JSON提交方式。
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
|
||||
this.$emit('search', pageForm)
|
||||
},
|
||||
async initData(){
|
||||
|
||||
@@ -50,10 +50,6 @@ layout("/layouts/platform.html"){
|
||||
<!-- <dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"-->
|
||||
<!-- code="AIDFUND_MEMBER_USER_TYPE"></dict-select>-->
|
||||
<!-- </search-item>-->
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
||||
</search-item>
|
||||
<search-item label="更新日期">
|
||||
<el-date-picker :picker-options="pickerOptions" @change="changeDateRangeChange"
|
||||
align="right" end-placeholder="结束日期" format="yyyy-MM-dd"
|
||||
@@ -523,7 +519,6 @@ layout("/layouts/platform.html"){
|
||||
isMember: 1,
|
||||
changeTypes: [],
|
||||
aidFundMemberUserType: "",
|
||||
userAttributes: [],
|
||||
},
|
||||
unions: [],
|
||||
units: [],
|
||||
@@ -569,7 +564,6 @@ layout("/layouts/platform.html"){
|
||||
{ prop: "personType", label: "人员类型", width: 120, sortable: true },
|
||||
// 临时屏蔽“人员分类”列表字段,不删除配置,后续需要可恢复。
|
||||
// { prop: "aidFundMemberUserType", label: "人员分类", width: 120, sortable: true },
|
||||
{ prop: "userAttribute", label: "人员属性", width: 120, sortable: true },
|
||||
{ prop: "idCardType", label: "证件类型", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "idCard", label: "证件号码", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "marriage", label: "婚姻状况", width: 120, sortable: true, checked: 0 },
|
||||
@@ -597,16 +591,6 @@ layout("/layouts/platform.html"){
|
||||
"member-all-change": MEMBER_ALL_CHANGE_INFO,
|
||||
},
|
||||
methods: {
|
||||
// 分页和导出共用该参数构建方法,保证人员属性多选值始终按 JSON 数组提交。
|
||||
buildQueryPageForm(source = this.pageForm) {
|
||||
const pageForm = clone(source)
|
||||
pageForm.userAttributes = JSON.stringify(source.userAttributes || [])
|
||||
return pageForm
|
||||
},
|
||||
// 覆盖公共分页方法,使后端按人员属性集合执行查询。
|
||||
pageData(data = null) {
|
||||
return initTableMixins.methods.pageData.call(this, this.buildQueryPageForm(data || this.pageForm))
|
||||
},
|
||||
dropdownCommand(command) {
|
||||
const {type, data} = command
|
||||
if (type === 'view') {
|
||||
@@ -667,7 +651,7 @@ layout("/layouts/platform.html"){
|
||||
* 导出会员名单
|
||||
*/
|
||||
exportExcel() {
|
||||
const pageForm = this.buildQueryPageForm()
|
||||
const pageForm = clone(this.pageForm)
|
||||
const data = this.tableColumns.filter(item => this.checkedFields.includes(item.prop)).map(item => {
|
||||
return {prop: item.prop, label: item.label}
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ layout("/layouts/platform.html"){
|
||||
<div id="app">
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
|
||||
<common-query ref="commonQueryRef" @search="search"></common-query>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
|
||||
@@ -42,10 +42,6 @@ layout("/layouts/platform.html"){
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||
</search-item>-->
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
@@ -150,8 +146,7 @@ layout("/layouts/platform.html"){
|
||||
userState: "",
|
||||
personType: "",
|
||||
changeType: "",
|
||||
aidFundMemberUserType: "",
|
||||
userAttributes: []
|
||||
aidFundMemberUserType: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -198,9 +193,6 @@ layout("/layouts/platform.html"){
|
||||
pageForm.personTypes = JSON.stringify(pageForm.personTypes)
|
||||
pageForm.changeTypes = JSON.stringify(pageForm.changeTypes)
|
||||
pageForm.changeOrigins = JSON.stringify(pageForm.changeOrigins)
|
||||
// 人员属性为多选条件,提交前转换为后端可解析的 JSON 数组。
|
||||
pageForm.userAttributes = JSON.stringify(pageForm.userAttributes)
|
||||
|
||||
this.$axios.post(loc() + '/pageData', pageForm)
|
||||
.then(res => {
|
||||
if (res.code === 0) {
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<common-query ref="commonQueryRef" user-attribute-multiple @search="search"></common-query>
|
||||
<common-query ref="commonQueryRef" @search="search"></common-query>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
|
||||
@@ -43,9 +43,5 @@
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||
</search-item>-->
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</script>
|
||||
|
||||
@@ -22,7 +22,6 @@ const COMMON_QUERY = {
|
||||
personTypes: [],
|
||||
preparedBys: [],
|
||||
aidFundMemberUserType: '',
|
||||
userAttributes: [],
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -37,8 +36,6 @@ const COMMON_QUERY = {
|
||||
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
|
||||
// 人员属性多选值按现有数组查询参数口径提交。
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
|
||||
this.$emit('search', pageForm)
|
||||
},
|
||||
handleUnionChange() {
|
||||
|
||||
+1
-2
@@ -291,8 +291,7 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
search(pageForm) {
|
||||
if (pageForm) {
|
||||
// 当前页的在职状态、人员类型使用标签数组筛选,公共查询组件回传的是字符串,
|
||||
// 这里保留当前页数组,避免选择人员属性后把标签筛选状态覆盖掉。
|
||||
// 当前页的在职状态、人员类型使用标签数组筛选,需保留当前页已有筛选状态。
|
||||
const currentUserStates = this.pageForm.userStates
|
||||
const currentPersonTypes = this.pageForm.personTypes
|
||||
this.pageForm = {...this.pageForm, ...pageForm}
|
||||
|
||||
@@ -458,7 +458,6 @@ layout("/layouts/platform.html"){
|
||||
{ prop: "unionName", label: "所属工会", sortable: true },
|
||||
{ prop: "unitName", label: "所属单位",sortable: true },
|
||||
// { prop: "aidFundMemberUserType", label: "人员分类", width: 120, sortable: true },
|
||||
// { prop: "userAttribute", label: "人员属性", width: 120, sortable: true },
|
||||
{ prop: "idCardType", label: "证件类型", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "idCard", label: "证件号码", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "marriage", label: "婚姻状况", width: 120, sortable: true, checked: 0 },
|
||||
|
||||
@@ -49,10 +49,6 @@ layout("/layouts/platform.html"){
|
||||
<search-item label="人员分类" v-if="false">
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch" code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||
</search-item>
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
@@ -109,8 +105,7 @@ layout("/layouts/platform.html"){
|
||||
year: new Date().getFullYear() - 1 + "",
|
||||
memberSearchName: "",
|
||||
memberSearchKeyWord: "",
|
||||
aidFundMemberUserType: "",
|
||||
userAttributes: []
|
||||
aidFundMemberUserType: ""
|
||||
},
|
||||
userId: "",
|
||||
unions: [],
|
||||
@@ -133,16 +128,6 @@ layout("/layouts/platform.html"){
|
||||
"member-info": MEMBER_INFO
|
||||
},
|
||||
methods: {
|
||||
// 分页和导出共用该参数构建方法,保证人员属性多选值始终按 JSON 数组提交。
|
||||
buildQueryPageForm() {
|
||||
const pageForm = clone(this.pageForm)
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes || [])
|
||||
return pageForm
|
||||
},
|
||||
// 覆盖公共分页方法,使后端按人员属性集合执行查询。
|
||||
pageData() {
|
||||
return initTableMixins.methods.pageData.call(this, this.buildQueryPageForm())
|
||||
},
|
||||
openView(row) {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.memberInfoRef.onOpen(row.id)
|
||||
@@ -152,7 +137,7 @@ layout("/layouts/platform.html"){
|
||||
this.$downLoad("/platform/member/info/history/doExportByUnion", { year: this.pageForm.year })
|
||||
},
|
||||
doExport() {
|
||||
this.$downLoad("/platform/member/info/history/doExport", this.buildQueryPageForm())
|
||||
this.$downLoad("/platform/member/info/history/doExport", this.pageForm)
|
||||
},
|
||||
async initData() {
|
||||
if (this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])) {
|
||||
|
||||
@@ -49,10 +49,6 @@ layout("/layouts/platform.html"){
|
||||
<search-item label="人员分类" v-if="false">
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch" code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||
</search-item>
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||
code="USER_ATTRIBUTE" multiple collapse-tags clearable></dict-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
@@ -113,7 +109,6 @@ layout("/layouts/platform.html"){
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
userAttributes: [],
|
||||
year: new Date().getFullYear() + "",
|
||||
memberSearchName: "",
|
||||
memberSearchKeyWord: ""
|
||||
@@ -141,12 +136,6 @@ layout("/layouts/platform.html"){
|
||||
"member-add-form": MEMBER_ADD_FORM
|
||||
},
|
||||
methods: {
|
||||
// 人员属性为多选条件,分页查询前统一转换为后端可接收的 JSON 数组。
|
||||
pageData(data = null) {
|
||||
const pageForm = clone(data || this.pageForm)
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes || [])
|
||||
return initTableMixins.methods.pageData.call(this, pageForm)
|
||||
},
|
||||
openAdd() {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.memberAddFormRef.onOpen()
|
||||
|
||||
+1
-37
@@ -129,29 +129,6 @@ layout("/layouts/platform.html"){
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row type="flex" align="middle" class="query-row query-row-tag">
|
||||
<el-col class="query-row-title">人员属性:</el-col>
|
||||
<el-col class="query-row-content query-row-content-tag">
|
||||
<el-tag class="query-tag-item"
|
||||
v-for="item in userAttributeOptions"
|
||||
:key="item.code"
|
||||
:effect="pageForm.userAttributes.includes(item.code)?'dark':'plain'"
|
||||
@click="tagClick('userAttributes',item.code)">
|
||||
{{ item.name }}
|
||||
</el-tag>
|
||||
<span class="query-tag-actions">
|
||||
<el-link type="danger"
|
||||
v-if="userAttributeOptions.length&&pageForm.userAttributes.length"
|
||||
:underline="false"
|
||||
@click="pageForm.userAttributes=[];doSearch()">清空
|
||||
</el-link>
|
||||
<el-link :underline="false"
|
||||
@click="pageForm.userAttributes=userAttributeOptions.map(p=>p.code);doSearch()"
|
||||
type="success">全部
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
@@ -237,12 +214,10 @@ layout("/layouts/platform.html"){
|
||||
units: [],
|
||||
personTypeOptions: [],
|
||||
aidFundMemberUserTypeOptions: [],
|
||||
userAttributeOptions: [],
|
||||
pageForm: {
|
||||
currentYear: moment().format("YYYY"),
|
||||
queryType: "fgh",
|
||||
personTypes: [],
|
||||
userAttributes: [],
|
||||
aidFundMemberUserTypes: []
|
||||
},
|
||||
fullTableData: []
|
||||
@@ -271,16 +246,12 @@ layout("/layouts/platform.html"){
|
||||
this.$businessTool.getDictOptions("AIDFUND_MEMBER_USER_TYPE").then((data) => {
|
||||
this.aidFundMemberUserTypeOptions = data
|
||||
})
|
||||
this.$businessTool.getDictOptions("USER_ATTRIBUTE").then((data) => {
|
||||
this.userAttributeOptions = data
|
||||
})
|
||||
},
|
||||
pageData() {
|
||||
// 统计接口按 JSON 字符串接收多选条件,这里统一在提交前做转换,保证人员分类和人员属性都能正确过滤。
|
||||
// 统计接口按 JSON 字符串接收多选条件,提交前统一转换人员类型和人员分类。
|
||||
const pageForm = clone(this.pageForm)
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.aidFundMemberUserTypes = JSON.stringify(this.pageForm.aidFundMemberUserTypes)
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
|
||||
this.$axios.post(loc() + "/pageData", pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data
|
||||
@@ -296,13 +267,6 @@ layout("/layouts/platform.html"){
|
||||
this.pageForm.personTypes.push(code)
|
||||
}
|
||||
}
|
||||
if (key === "userAttributes") {
|
||||
if (this.pageForm.userAttributes.includes(code)) {
|
||||
this.pageForm.userAttributes.splice(this.pageForm.userAttributes.indexOf(code), 1)
|
||||
} else {
|
||||
this.pageForm.userAttributes.push(code)
|
||||
}
|
||||
}
|
||||
if (key === "aidFundMemberUserTypes") {
|
||||
if (this.pageForm.aidFundMemberUserTypes.includes(code)) {
|
||||
this.pageForm.aidFundMemberUserTypes.splice(this.pageForm.aidFundMemberUserTypes.indexOf(code), 1)
|
||||
|
||||
+1
-5
@@ -162,15 +162,13 @@ layout("/layouts/platform.html"){
|
||||
// { prop: "preparedBy", label: "编制类别", width: 120, sortable: true },
|
||||
{ prop: "postDoctoralJoinDate", label: "进站时间", sortable: true, checked: 0 },
|
||||
{ prop: "unionName", label: "所属工会", width: 120, sortable: true },
|
||||
{ prop: "unitName", label: "所属单位", width: 120, sortable: true },
|
||||
{ prop: "unitName", label: "所属单位", sortable: true },
|
||||
// 临时屏蔽“人员分类”列表字段,不删除配置,后续需要可恢复。
|
||||
// { prop: "aidFundMemberUserType", label: "人员分类", width: 120, sortable: true },
|
||||
{ prop: "userAttribute", label: "人员属性", width: 120, sortable: true },
|
||||
{ prop: "idCardType", label: "证件类型", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "idCard", label: "证件号码", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "marriage", label: "婚姻状况", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "jobCategory", label: "岗位类别", width: 120, sortable: true, checked: 0 },
|
||||
|
||||
{ prop: "professionalTitle", label: "职称", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "professionalLevel", label: "职级", width: 120, sortable: true, checked: 0 },
|
||||
{ prop: "employeeSource", label: "职工来源", width: 120, sortable: true, checked: 0 },
|
||||
@@ -205,7 +203,6 @@ layout("/layouts/platform.html"){
|
||||
pageForm.memberTypes = JSON.stringify(this.pageForm.memberTypes)
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.aidFundMemberUserTypes = JSON.stringify(this.pageForm.aidFundMemberUserTypes)
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
|
||||
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
|
||||
const data = this.tableColumns.filter(item => this.checkedFields.includes(item.prop)).map(item => {
|
||||
return {prop: item.prop, label: item.label}
|
||||
@@ -230,7 +227,6 @@ layout("/layouts/platform.html"){
|
||||
pageForm.memberTypes = JSON.stringify(this.pageForm.memberTypes)
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.aidFundMemberUserTypes = JSON.stringify(this.pageForm.aidFundMemberUserTypes)
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
|
||||
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
|
||||
pageForm.memberStatus = JSON.stringify(this.pageForm.memberStatus)
|
||||
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
|
||||
|
||||
-31
@@ -113,31 +113,6 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row type="flex" align="middle" class="query-row query-row-tag">
|
||||
<el-col class="query-row-title">人员属性:</el-col>
|
||||
<el-col class="query-row-content query-row-content-tag">
|
||||
<el-tag
|
||||
style="margin-right: 10px;cursor: pointer"
|
||||
v-for="item in userAttributeOptions"
|
||||
:key="item.code"
|
||||
:type="item.name"
|
||||
:effect="pageForm.userAttributes.includes(item.code)?'dark':'plain'"
|
||||
@click="tagClick('userAttributes',item.code)">
|
||||
{{ item.name }}
|
||||
</el-tag>
|
||||
|
||||
<el-link type="danger"
|
||||
v-if="userAttributeOptions.length&&pageForm.userAttributes.length"
|
||||
:underline="false"
|
||||
@click="pageForm.userAttributes=[];doSearch()">清空
|
||||
</el-link>
|
||||
<el-link :underline="false"
|
||||
@click="pageForm.userAttributes=userAttributeOptions.map(p=>p.code);doSearch()"
|
||||
type="success">全部
|
||||
</el-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row type="flex" align="middle" class="query-row">
|
||||
<el-col class="query-row-content">
|
||||
<el-row>
|
||||
@@ -235,7 +210,6 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
|
||||
personTypes: [],
|
||||
preparedBys: [],
|
||||
aidFundMemberUserTypes: [],
|
||||
userAttributes: [],
|
||||
userStates: [],
|
||||
memberStatus: [],
|
||||
year: moment().format("YYYY"),
|
||||
@@ -253,7 +227,6 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
|
||||
personTypeOptions: [],
|
||||
preparedByOptions: [],
|
||||
aidFundMemberUserTypeOptions: [],
|
||||
userAttributeOptions: [],
|
||||
userStateOptions: [],
|
||||
memberStatusOptions: [],
|
||||
unions: [],
|
||||
@@ -346,7 +319,6 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
|
||||
this.pageForm.personTypes = []
|
||||
this.pageForm.preparedBys = []
|
||||
this.pageForm.aidFundMemberUserTypes = []
|
||||
this.pageForm.userAttributes = []
|
||||
this.pageForm.memberStatus = []
|
||||
this.pageForm.userStates = []
|
||||
this.pageForm.unionId = []
|
||||
@@ -387,9 +359,6 @@ const MEMBER_STATISTICS_COMPREHENSIVE_QUERY_FORM = {
|
||||
this.$businessTool.getDictOptions("AIDFUND_MEMBER_USER_TYPE").then((data) => {
|
||||
this.aidFundMemberUserTypeOptions = data
|
||||
})
|
||||
this.$businessTool.getDictOptions("USER_ATTRIBUTE").then((data) => {
|
||||
this.userAttributeOptions = data
|
||||
})
|
||||
this.$businessTool.getDictOptions("USER_STATE").then((data) => {
|
||||
this.userStateOptions = data
|
||||
})
|
||||
|
||||
+1
-37
@@ -129,29 +129,6 @@ layout("/layouts/platform.html"){
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row type="flex" align="middle" class="query-row query-row-tag">
|
||||
<el-col class="query-row-title">人员属性:</el-col>
|
||||
<el-col class="query-row-content query-row-content-tag">
|
||||
<el-tag class="query-tag-item"
|
||||
v-for="item in userAttributeOptions"
|
||||
:key="item.code"
|
||||
:effect="pageForm.userAttributes.includes(item.code)?'dark':'plain'"
|
||||
@click="tagClick('userAttributes',item.code)">
|
||||
{{ item.name }}
|
||||
</el-tag>
|
||||
<span class="query-tag-actions">
|
||||
<el-link type="danger"
|
||||
v-if="userAttributeOptions.length&&pageForm.userAttributes.length"
|
||||
:underline="false"
|
||||
@click="pageForm.userAttributes=[];doSearch()">清空
|
||||
</el-link>
|
||||
<el-link :underline="false"
|
||||
@click="pageForm.userAttributes=userAttributeOptions.map(p=>p.code);doSearch()"
|
||||
type="success">全部
|
||||
</el-link>
|
||||
</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
@@ -198,12 +175,10 @@ layout("/layouts/platform.html"){
|
||||
unions: [],
|
||||
units: [],
|
||||
personTypeOptions: [],
|
||||
userAttributeOptions: [],
|
||||
pageForm: {
|
||||
currentYear: moment().format("YYYY"),
|
||||
queryType: "fgh",
|
||||
personTypes: [],
|
||||
userAttributes: [],
|
||||
aidFundMemberUserTypes: []
|
||||
},
|
||||
aidFundMemberUserTypeOptions: [],
|
||||
@@ -232,9 +207,6 @@ layout("/layouts/platform.html"){
|
||||
this.$businessTool.getDictOptions("AIDFUND_MEMBER_USER_TYPE").then((data) => {
|
||||
this.aidFundMemberUserTypeOptions = data
|
||||
})
|
||||
this.$businessTool.getDictOptions("USER_ATTRIBUTE").then((data) => {
|
||||
this.userAttributeOptions = data
|
||||
})
|
||||
},
|
||||
tagClick(key,code) {
|
||||
if (key === "personTypes") {
|
||||
@@ -244,13 +216,6 @@ layout("/layouts/platform.html"){
|
||||
this.pageForm.personTypes.push(code)
|
||||
}
|
||||
}
|
||||
if (key === "userAttributes") {
|
||||
if (this.pageForm.userAttributes.includes(code)) {
|
||||
this.pageForm.userAttributes.splice(this.pageForm.userAttributes.indexOf(code), 1)
|
||||
} else {
|
||||
this.pageForm.userAttributes.push(code)
|
||||
}
|
||||
}
|
||||
if (key === "aidFundMemberUserTypes") {
|
||||
if (this.pageForm.aidFundMemberUserTypes.includes(code)) {
|
||||
this.pageForm.aidFundMemberUserTypes.splice(this.pageForm.aidFundMemberUserTypes.indexOf(code), 1)
|
||||
@@ -262,10 +227,9 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
pageData() {
|
||||
const pageForm = clone(this.pageForm)
|
||||
// 统计接口按 JSON 字符串接收多选条件,这里把人员分类和人员属性统一成同一提交口径。
|
||||
// 统计接口按 JSON 字符串接收多选条件,提交前转换人员类型和人员分类。
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.aidFundMemberUserTypes = JSON.stringify(this.pageForm.aidFundMemberUserTypes)
|
||||
pageForm.userAttributes = JSON.stringify(this.pageForm.userAttributes)
|
||||
this.$axios.post(loc() + "/pageData", pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data
|
||||
|
||||
@@ -94,14 +94,6 @@ const filterUser = {
|
||||
v-model="pageForm.personTypes"></dict-select>
|
||||
</search-item>
|
||||
|
||||
<search-item label="人员属性:">
|
||||
<dict-select clearable code="USER_ATTRIBUTE"
|
||||
multiple
|
||||
collapse-tags
|
||||
placeholder="请选择人员属性"
|
||||
v-model="pageForm.userAttributes"></dict-select>
|
||||
</search-item>
|
||||
|
||||
<search-item label="在职状态:">
|
||||
<dict-select clearable code="USER_STATE"
|
||||
multiple
|
||||
@@ -169,7 +161,6 @@ const filterUser = {
|
||||
userStates: [],
|
||||
personTypes: [],
|
||||
preparedBys: [],
|
||||
userAttributes: [],
|
||||
unitId: null,
|
||||
threeUnitId: null
|
||||
},
|
||||
@@ -212,7 +203,6 @@ const filterUser = {
|
||||
this.threeUnitOptions = []
|
||||
this.$set(this.pageForm, "personTypes", [])
|
||||
this.$set(this.pageForm, "preparedBys", [])
|
||||
this.$set(this.pageForm, "userAttributes", [])
|
||||
this.$set(this.pageForm, "userStates", [])
|
||||
this.$set(this.pageForm, "isMember", null)
|
||||
},
|
||||
|
||||
@@ -65,10 +65,6 @@ layout("/layouts/platform.html"){
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||
</search-item>
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-model="pageForm.userAttribute" placeholder="请选择人员属性" @change="doSearch"
|
||||
code="USER_ATTRIBUTE"></dict-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
|
||||
@@ -96,14 +96,6 @@ const addUser = {
|
||||
v-model="pageForm.personTypes"></dict-select>
|
||||
</search-item>
|
||||
|
||||
<search-item label="人员属性:">
|
||||
<dict-select clearable code="USER_ATTRIBUTE"
|
||||
multiple
|
||||
collapse-tags
|
||||
placeholder="请选择人员属性"
|
||||
v-model="pageForm.userAttributes"></dict-select>
|
||||
</search-item>
|
||||
|
||||
<search-item label="在职状态:">
|
||||
<dict-select clearable code="USER_STATE"
|
||||
multiple
|
||||
@@ -173,7 +165,6 @@ const addUser = {
|
||||
unitId: null,
|
||||
threeUnitId: null,
|
||||
personTypes: [],
|
||||
userAttributes: [],
|
||||
preparedBys: [],
|
||||
userStates: [],
|
||||
isMember: null
|
||||
@@ -216,7 +207,6 @@ const addUser = {
|
||||
this.$set(this.pageForm, "threeUnitId", null)
|
||||
this.$set(this, "threeUnitOptions", [])
|
||||
this.$set(this.pageForm, "personTypes", [])
|
||||
this.$set(this.pageForm, "userAttributes", [])
|
||||
this.$set(this.pageForm, "preparedBys", [])
|
||||
this.$set(this.pageForm, "userStates", [])
|
||||
this.$set(this.pageForm, "isMember", null)
|
||||
|
||||
@@ -128,11 +128,6 @@ layout("/layouts/platform.html"){
|
||||
<dict-select v-model="pageForm.aidFundMemberUserType" placeholder="请选择人员分类" @change="doSearch"
|
||||
code="AIDFUND_MEMBER_USER_TYPE"></dict-select>
|
||||
</search-item>
|
||||
<search-item label="人员属性">
|
||||
<dict-select v-model="pageForm.userAttributes" placeholder="请选择人员属性" @change="doSearch"
|
||||
code="USER_ATTRIBUTE" clearable multiple collapse-tags></dict-select>
|
||||
</search-item>
|
||||
|
||||
<!-- <search-item label="所选福利:">-->
|
||||
<!-- <el-select clearable placeholder="请选择所选福利" style="width: 100%" v-model="pageForm.optionId">-->
|
||||
<!-- <el-option :key="item.id" :label="item.optionName" :value="item.id" v-for="item in pageFormProject"></el-option>-->
|
||||
|
||||
Reference in New Issue
Block a user