This commit is contained in:
zhouhefeng
2026-07-14 09:15:41 +08:00
105 changed files with 4556 additions and 3279 deletions
@@ -1,17 +1,7 @@
package com.budwk.app.base.config;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.budwk.app.base.constant.RedisConstant;
import com.budwk.app.base.exception.BaseException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.impl.PropertiesProxy;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
@@ -33,19 +23,17 @@ public class DataCenterProperties {
@Inject
private PropertiesProxy conf;
@Inject
private RedisService redisService;
private String appId;
private String tokenUrl;
private Map<String, String> codes = new HashMap<>();
private String key;
private String secret;
private Map<String, String> urls = new HashMap<>();
public void init() {
Map<String, String> all = conf.toMap();
appId = all.get("data-center.app-id");
tokenUrl = all.get("data-center.token-url");
extract(all, "data-center.codes.", codes);
key = all.get("data-center.key");
secret = all.get("data-center.secret");
extract(all, "data-center.urls.", urls);
}
@@ -61,59 +49,4 @@ public class DataCenterProperties {
}
});
}
/**
* 读取配置
* @param key 接口类型枚举
* @return 相关配置
*/
public Credential credential(String key) {
String code = codes.get(key);
String url = urls.get(key);
if (code == null || url == null) {
throw new BaseException("未知业务: " + key);
}
String token = getToken(Integer.parseInt(code), key);
return new Credential(url, token);
}
@Getter
@AllArgsConstructor
public static class Credential {
private String url;
private String token;
}
/**
* 获取token
* @param code
* @param keyPrefix
* @return token
*/
private String getToken(Integer code, String keyPrefix) {
String dateCenterPrefix = RedisConstant.DATE_CENTER_PREFIX + keyPrefix;
String token = redisService.get(dateCenterPrefix);
if (StrUtil.isNotBlank(token)) {
return token;
} else {
HttpRequest httpRequest = HttpUtil.createPost(tokenUrl);
Map<String, Object> reqBody = Map.of(
"appId", appId,
"code", code
);
httpRequest.body(JSONUtil.toJsonStr(reqBody));
JSONObject resp = JSONUtil.parseObj(httpRequest.execute().body());
if (resp.getInt("code") != 200) {
throw new BaseException("获取token失败: " + resp.getStr("msg"));
} else {
JSONObject data = resp.getJSONObject("data");
String tokenStr = data.getStr("token");
Integer expire = data.getInt("expire");
redisService.setex(dateCenterPrefix, expire, tokenStr);
return tokenStr;
}
}
}
}
@@ -37,7 +37,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("工号")
@ColDefine(type = ColType.VARCHAR, width = 120)
@DataCenterColumn(name = "工号", key = "JGH")
@DataCenterColumn(name = "工号", key = "ZGH")
private String loginname;
@Column
@@ -49,7 +49,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("性别")
@ColDefine(type = ColType.VARCHAR, width = 10)
@DataCenterColumn(name = "", key = "XBM", dict = "USER_SEX")
@DataCenterColumn(name = "", key = "XB", dict = "USER_SEX")
private String sex;
@Column
@@ -108,13 +108,12 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("手机号码")
@ColDefine(type = ColType.VARCHAR, width = 32)
@DataCenterColumn(name = "手机号码", key = "SJHM")
@DataCenterColumn(name = "手机号码", key = "YDDH")
private String mobile;
@Column
@Comment("学历")
@ColDefine(type = ColType.VARCHAR, width = 20)
@DataCenterColumn(name = "学历", key = "ZGXLM", dict = "USER_EDUCATION")
private String education;
@Column
@@ -131,19 +130,16 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("岗位类别")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "岗位类别", key = "JRGWDJM",dict = "USER_JOB_CATEGORY")
private String jobCategory;
@Column
@Comment("职称")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "职称", key = "DQZC", dict = "USER_PROFESSIONAL_TITLE")
private String professionalTitle;
@Column
@Comment("职级")
@ColDefine(type = ColType.VARCHAR, width = 50)
@DataCenterColumn(name = "取得职称等级码", key = "QDZCDJM", dict = "USER_PROFESSIONAL_LEVEL")
private String professionalLevel;
@Column
@@ -179,7 +175,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("来校时间")
@ColDefine(type = ColType.VARCHAR, width = 10)
@DataCenterColumn(name = "来校时间", key = "LXRQ")
@DataCenterColumn(name = "来校时间", key = "LXNY")
private String arrivalAtSchoolDate;
@Column
@@ -195,7 +191,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("在职状态")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "当前状态码", key = "DQZTM", dict = "USER_STATE")
@DataCenterColumn(name = "当前状态码", key = "DQZT", dict = "USER_STATE")
private String userState;
@Column
@@ -207,19 +203,17 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@Comment("在岗情况")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "在岗情况码", key = "ZGQKM", dict = "USER_DUTY_SITUATION")
private String dutySituation;
@Column
@Comment("教职工类别码")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "教职工类别码", key = "JZGLBM", dict = "USER_PERSON_TYPE")
@DataCenterColumn(name = "教职工类别码", key = "RYLX", dict = "USER_PERSON_TYPE")
private String personType;
@Column
@Comment("编制类别码")
@ColDefine(type = ColType.VARCHAR, width = 30)
@DataCenterColumn(name = "编制类别码", key = "BZLBM", dict = "USER_PREPARED_BY_TYPE")
private String preparedBy;
@Column
@@ -269,7 +263,7 @@ public class Sys_user extends BaseModel implements Serializable {
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@DataCenterColumn(name = "单位", key = "DWH")
@DataCenterColumn(name = "单位", key = "SZDWH")
private String unitId;
@Column
@@ -1,28 +1,14 @@
package com.budwk.app.sys.services.impl;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
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.models.Sys_data_dict;
import com.budwk.app.sys.models.Sys_dict;
import com.budwk.app.sys.services.SysDataDictPullService;
import com.budwk.app.sys.services.SysDictService;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.util.NutMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @version 1.0
@@ -35,14 +21,6 @@ import java.util.Map;
@IocBean(args = {"refer:dao"})
public class SysDataDictPullServiceImpl extends BaseServiceImpl<Sys_dict> implements SysDataDictPullService {
@Inject
private DataCenterProperties dcPro;
@Inject
private SysDictService dictService;
// code
private final static String KEY_PREFIX = "user_";
public SysDataDictPullServiceImpl(Dao dao) {
super(dao);
}
@@ -50,57 +28,7 @@ public class SysDataDictPullServiceImpl extends BaseServiceImpl<Sys_dict> implem
@Override
@Aop(TransAop.READ_COMMITTED)
public void pullDataDict() {
Map<String, String> urls = dcPro.getUrls();
List<String> list = urls.keySet().stream().filter(o -> o.startsWith(KEY_PREFIX.toUpperCase())).toList();
List<Sys_data_dict> dataDictList = new ArrayList<>();
for (String key : list) {
// 获取配置
DataCenterProperties.Credential credential = dcPro.credential(key);
String url = credential.getUrl();
String token = credential.getToken();
// 请求数据
HttpRequest httpRequest = HttpUtil.createPost(url);
httpRequest.header("Content-Type", "application/json");
httpRequest.header("X-H3C-TOKEN", token);
httpRequest.body(JSONUtil.toJsonStr(Map.of()));
String resBody = httpRequest.execute().body();
JSONObject jsonBody = JSONUtil.parseObj(resBody);
if (jsonBody.getInt("code") != 200) {
log.error("获取{}字典数据失败,错误码: {};错误原因:{}", key, jsonBody.getInt("code"), jsonBody.getStr("msg"));
}
List<NutMap> data = Json.fromJsonAsList(NutMap.class, jsonBody.getStr("data"));
// 先删除
Sys_dict sysDict = dao().fetch(Sys_dict.class, Cnd.where(Sys_dict::getCode, "=", key));
dao().clear(Sys_dict.class, Cnd.where(Sys_dict::getParentId, "=", sysDict.getId()));
// 组合数据
data.forEach(o -> {
Sys_dict dict = new Sys_dict();
dict.setParentId(sysDict.getId());
dict.setPath(dictService.getSubPath("sys_dict", "path", sysDict.getPath()));
dict.setName(o.getString("xbname"));
dict.setCode(o.getString("xbname"));
dict.setDisabled(false);
dict.setHasChildren(false);
dao().insert(dict);
Sys_data_dict sysDataDict = new Sys_data_dict();
sysDataDict.setParentCode(key);
sysDataDict.setCode(o.getString("xbcode"));
sysDataDict.setName(o.getString("xbname"));
dataDictList.add(sysDataDict);
});
dao().insert(dataDictList);
}
// 旧数据中心字典接口已停用,避免继续误调旧token/code模式接口。
throw new BaseException("旧数据中心字典拉取接口已停用");
}
}
@@ -1,32 +1,33 @@
package com.budwk.app.sys.services.impl;
import cn.hutool.core.collection.CollUtil;
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.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
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.enums.Api2UnitFiledMap;
import com.budwk.app.sys.models.Sys_unit;
import com.budwk.app.sys.services.SysDataUnitPullService;
import com.budwk.app.sys.utils.DataCenterUtil;
import lombok.extern.slf4j.Slf4j;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Dao;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
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.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
@@ -40,8 +41,11 @@ 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;
@Inject
private DataCenterProperties dcPro;
private DataCenterProperties dataCenterProperties;
public SysDataUnitPullServiceImpl(Dao dao) {
super(dao);
@@ -51,11 +55,7 @@ public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implem
@Override
@Aop(TransAop.READ_COMMITTED)
public void updateUnits() {
Sql sql = Sqls.create("select id from sys_unit group by id");
sql.setCallback(Sqls.callback.strList());
dao().execute(sql);
List<String> unitIds = sql.getList(String.class);
updateUnits(unitIds);
updateUnits(List.of());
}
/**
@@ -64,65 +64,235 @@ public class SysDataUnitPullServiceImpl extends BaseServiceImpl<Sys_unit> implem
@Override
@Aop(TransAop.READ_COMMITTED)
public void updateUnits(List<String> unitIds) {
// token url参数
Map<String, String> tokenParams = Map.of(
"grant_type", "password",
"scope", "read",
"username", "3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD",
"password", "3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD"
);
String accessToken = getDmpAccessToken();
List<JSONObject> rawDataList = distinctDmpUnits(pullDmpUnits(getDmpUnitUrl(), accessToken));
Set<String> parentCodes = rawDataList.stream()
.map(this::getNormalizedParentCode)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
String params = URLUtil.buildQuery(tokenParams, StandardCharsets.UTF_8);
String tokenUrl = "https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/oauth/token" + (StrUtil.isBlank(params) ? "" : "?" + params);
HttpRequest tokenHttpRequest = HttpUtil.createPost(tokenUrl);
tokenHttpRequest.header("Content-Type", "application/json");
tokenHttpRequest.header("Authorization", "Basic MTE0OjU5M2UwNGI4YTE4NWRlMzkyNjY4ZmY0ZDJhZGMyZTEw");
rawDataList.stream()
.sorted(Comparator.comparingInt(this::getUnitLevel))
.forEach(raw -> saveOrUpdateUnit(raw, parentCodes));
log.info("请求token: {}", tokenHttpRequest);
String tokenResBody = tokenHttpRequest.execute().body();
log.info("信息中心单位数据同步完成,本次接口返回单位数量: {},待检查单位编码数量: {}", rawDataList.size(), unitIds == null ? 0 : unitIds.size());
}
log.info("请求token结果: {}", tokenResBody);
/**
* 获取信息中心开放平台访问令牌。
* 参数来自 data-center.token-url、data-center.key、data-center.secret
* 返回值为后续单位接口 body 中 access_token 使用的字符串。
*/
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);
// 请求数据
HttpRequest httpRequest = HttpUtil.createGet("https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/get/YXSDWJBSJZLB");
httpRequest.form(Map.of("access_token", tokenJsonBody.getStr("access_token"), "pageSize", 100, "page", 1));
log.info("请求单位数据: {}", httpRequest);
String resBody = httpRequest.execute().body();
log.info("请求单位数据结果: {}", resBody);
JSONObject jsonBody = JSONUtil.parseObj(resBody);
if (jsonBody.getInt("code") != 200) {
throw new BaseException("获取单位数据失败,错误码: " + jsonBody.getInt("code") + ";错误原因:" + jsonBody.getStr("msg"));
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;
}
// 需要新增的单位
List<Sys_unit> insertList = new ArrayList<>();
// 需要更新的单位
List<Sys_unit> updateList = new ArrayList<>();
/**
* 读取信息中心单位接口地址。
* 配置项为 data-center.urls.unit,返回值为单位全量接口URL。
*/
private String getDmpUnitUrl() {
String url = dataCenterProperties.getUrls().get(DMP_UNIT_KEY);
if (StrUtil.isBlank(url)) {
throw new BaseException("未配置信息中心单位接口地址: data-center.urls." + DMP_UNIT_KEY);
}
return url;
}
// 拉取过来的数据,全部的单位,一万四千多条,这里只保留 “部门类”
List<JSONObject> data = jsonBody.getJSONArray("data").stream()
.map(o -> (JSONObject) o)
.toList();
/**
* 分页拉取单位接口数据。
* 入参 url 为单位接口地址,accessToken 为信息中心令牌;
* 请求 body 包含 access_token、per_page、page
* 返回值为 result.data 合并后的单位原始 JSON 列表。
*/
private List<JSONObject> pullDmpUnits(String url, String accessToken) {
List<JSONObject> rawDataList = new ArrayList<>();
int page = 1;
int maxPage = 1;
int total = 0;
Map<String, String> api2db = Arrays.stream(Api2UnitFiledMap.values())
.collect(Collectors.toMap(e -> e.apiField, e -> e.dbColumn));
for (JSONObject row : data) {
Sys_unit unit = DataCenterUtil.mapJsonToBean(row, Sys_unit.class, api2db);
unit.setUnitcode(unit.getId());
unit.setUnitTypeCode(1);
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)
)));
if (unitIds.contains(unit.getId())) {
// 存在则更新
updateList.add(unit);
} else {
// 不存在则新增
insertList.add(unit);
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) {
Map<String, JSONObject> unitMap = new LinkedHashMap<>();
for (JSONObject raw : rawDataList) {
String unitCode = raw.getStr("DWDM");
if (StrUtil.isBlank(unitCode)) {
continue;
}
unitMap.putIfAbsent(unitCode, raw);
}
log.info("本次拉取单位数据,新增{}条,更新{}条", insertList.size(), updateList.size());
dao().insert(insertList);
dao().update(updateList);
return new ArrayList<>(unitMap.values());
}
/**
* 保存或更新单位。
* DWDM 对应系统单位 id/unitcodeDWMC 对应名称,LSDWH 对应父级单位号,DWCC 对应信息中心原始单位层级。
*/
private void saveOrUpdateUnit(JSONObject raw, Set<String> parentCodes) {
String unitCode = raw.getStr("DWDM");
if (StrUtil.isBlank(unitCode)) {
return;
}
String parentId = getParentId(unitCode, getNormalizedParentCode(raw));
Sys_unit unit = fetch(unitCode);
if (unit == null) {
unit = new Sys_unit();
unit.setId(unitCode);
unit.setUnitcode(unitCode);
unit.setPath(getUnitPath(parentId));
setUnitValue(unit, raw, parentId, parentCodes);
dao().fastInsert(unit);
} else {
setUnitValue(unit, raw, parentId, parentCodes);
if (StrUtil.isBlank(unit.getPath())) {
unit.setPath(getUnitPath(parentId));
}
dao().updateIgnoreNull(unit);
}
}
/**
* 根据接口字段给系统单位赋值。
* DWYXBS 表示单位是否有效,DWCC 表示信息中心原始单位层次;
* 系统内置根单位占用一级层级,因此保存时统一将 DWCC 加一。
*/
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);
unit.setParentId(parentId);
unit.setName(unitName);
unit.setAliasName(aliasName);
unit.setUnitcode(unitCode);
unit.setAddress(raw.getStr("DWDZ"));
unit.setUnitLevel(unitLevel);
unit.setUnitType(raw.getStr("DWLB"));
unit.setUnitTypeCode(availableBusinessUnit ? 1 : 0);
unit.setHasChildren(parentCodes.contains(unitCode));
}
/**
* 计算父级单位号。
* LSDWH 为空、等于自身或本地不存在该父级时按根级处理;系统根单位 0 允许直接作为父级。
*/
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;
}
/**
* 根据父级 path 生成当前单位 path。
* 父级为空时生成根节点 path,父级存在时在父级 path 下生成子节点 path。
*/
private String getUnitPath(String parentId) {
String parentPath = "";
if (StrUtil.isNotBlank(parentId)) {
Sys_unit parentUnit = fetch(parentId);
parentPath = parentUnit == null ? "" : parentUnit.getPath();
}
return getSubPath("sys_unit", "path", parentPath);
}
/**
* 信息中心一级单位应挂在系统根单位 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 为信息中心单位层次,排序时用于尽量先处理父级单位,便于后续子级找到父节点。
*/
private int getUnitLevel(JSONObject raw) {
return raw.getInt("DWCC", 0);
}
}
@@ -5,6 +5,7 @@ import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.event.role.RoleEventMsg;
@@ -50,6 +51,8 @@ import java.util.stream.Collectors;
@Slf4j
@IocBean
public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService {
private static final int BATCH_SIZE = 500;
private static final int ROLE_DELETE_BATCH_SIZE = 50;
@Inject
private Dao dao;
@@ -180,6 +183,21 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
List<Sys_user_history> histories = new CopyOnWriteArrayList<>();
List<String> addMemberUserIds = Collections.synchronizedList(new ArrayList<>());
List<String> removeMemberUserIds = Collections.synchronizedList(new ArrayList<>());
Set<String> sourceLoginNames = sources.stream()
.map(Sys_user_source::getLoginname)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
List<String> leaveUserIds = sysUsers.stream()
.filter(user -> StrUtil.isNotBlank(user.getLoginname()))
.filter(user -> !sourceLoginNames.contains(user.getLoginname()))
.map(Sys_user::getId)
.toList();
List<String> leaveMemberUserIds = sysUsers.stream()
.filter(user -> StrUtil.isNotBlank(user.getLoginname()))
.filter(user -> !sourceLoginNames.contains(user.getLoginname()))
.filter(user -> Boolean.TRUE.equals(user.getMember()))
.map(Sys_user::getId)
.toList();
// 处理每条数据
for (Sys_user_source source : sources) {
@@ -235,7 +253,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
CompletableFuture<Void> insertTask = CompletableFuture.runAsync(() -> {
log.info("新增用户: {} 个", needInitUserList.size());
// 分批处理,每批200条
List<List<Sys_user>> batches = ListUtil.split(needInitUserList, 500);
List<List<Sys_user>> batches = ListUtil.split(needInitUserList, BATCH_SIZE);
batches.forEach(batch -> {
try {
dao.fastInsert(batch);
@@ -260,7 +278,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
if (!roleList.isEmpty()) {
// 分批处理角色分配
List<List<Sys_user_role>> roleBatches = ListUtil.split(roleList, 500);
List<List<Sys_user_role>> roleBatches = ListUtil.split(roleList, BATCH_SIZE);
roleBatches.forEach(batch -> {
try {
dao.fastInsert(batch);
@@ -282,7 +300,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
CompletableFuture<Void> updateTask = CompletableFuture.runAsync(() -> {
log.info("更新用户: {} 个", needDoUpdateList.size());
// 分批处理,每批200条
List<List<Sys_user>> batches = ListUtil.split(needDoUpdateList, 500);
List<List<Sys_user>> batches = ListUtil.split(needDoUpdateList, BATCH_SIZE);
batches.forEach(batch -> {
try {
dao.updateIgnoreNull(batch);
@@ -294,6 +312,65 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
updateTasks.add(updateTask);
}
if (Lang.isNotEmpty(leaveUserIds)) {
CompletableFuture<Void> leaveTask = CompletableFuture.runAsync(() -> {
log.info("数据源缺失用户转为不在岗并取消会员: {} 个", leaveUserIds.size());
List<List<String>> batches = ListUtil.split(leaveUserIds, BATCH_SIZE);
batches.forEach(batch -> {
try {
/*
* 本次拉取批次中没有出现、但系统用户表仍存在的人员,按离岗处理:
* 1. userState 写为“不在岗”,用于后续人员状态筛选和业务判断;
* 2. member 写为 false,避免仍按会员身份参与后续业务判断。
*/
dao.update(Sys_user.class, Chain.make("userState", "不在岗").add("member", false), Cnd.where("id", "in", batch));
} catch (Exception e) {
log.error("批量更新数据源缺失用户状态异常", e);
}
});
}, executorService);
updateTasks.add(leaveTask);
}
if (Lang.isNotEmpty(leaveMemberUserIds)) {
CompletableFuture<Void> leaveMemberRoleTask = CompletableFuture.runAsync(() -> {
log.info("数据源缺失会员移除会员角色: {} 个", leaveMemberUserIds.size());
List<List<String>> batches = ListUtil.split(leaveMemberUserIds, ROLE_DELETE_BATCH_SIZE);
batches.forEach(batch -> {
try {
/*
* 只对原本是会员的缺失人员移除会员角色,并缩小删除批次,
* 降低 sys_user_role 大批量 DELETE 时的锁等待概率。
*/
dao.clear(Sys_user_role.class, Cnd.where("userId", "in", batch).and("roleId", "=", memberRole.getId()));
} catch (Exception e) {
log.error("批量移除数据源缺失会员角色异常", e);
}
});
}, executorService);
updateTasks.add(leaveMemberRoleTask);
}
if (Lang.isNotEmpty(histories)) {
CompletableFuture<Void> historyTask = CompletableFuture.runAsync(() -> {
log.info("添加历史记录: {} 条", histories.size());
/*
* 历史记录基于更新前的 sys_user 与 sys_user_source 生成,必须纳入本次更新等待范围。
* 继续使用线程池和批量插入,避免主线程逐条写入拖慢更新接口。
*/
List<List<Sys_user_history>> batches = ListUtil.split(histories, 500);
batches.forEach(batch -> {
try {
dao.fastInsert(batch);
} catch (Exception e) {
log.error("批量添加历史记录异常", e);
throw new RuntimeException(e);
}
});
}, executorService);
updateTasks.add(historyTask);
}
// 等待用户数据更新完成
try {
// 设置超时时间,避免无限等待
@@ -307,22 +384,6 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
return "更新失败: " + e.getMessage();
}
// 3. 异步添加历史记录 - 不等待完成
if (Lang.isNotEmpty(histories)) {
executorService.execute(() -> {
log.info("添加历史记录: {} 条", histories.size());
// 分批处理历史记录
List<List<Sys_user_history>> batches = ListUtil.split(histories, 500);
batches.forEach(batch -> {
try {
dao.fastInsert(batch);
} catch (Exception e) {
log.error("批量添加历史记录异常", e);
}
});
});
}
/* // 4. 异步添加会员角色 - 不等待完成
if (Lang.isNotEmpty(addMemberUserIds)) {
executorService.execute(() -> {
@@ -384,7 +445,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
log.info("全量更新用户数据完成,耗时: {} 毫秒", (endTime - startTime));
return "更新完成: 新增用户 " + needInitUserList.size() + " 个, 更新用户 " + needDoUpdateList.size()
+ " 个, 待添加会员 " + addMemberUserIds.size() + " 个, 待移除会员 " + removeMemberUserIds.size() + "";
+ " 个, 数据源缺失转不在岗 " + leaveUserIds.size() + " 个, 待添加会员 " + addMemberUserIds.size() + " 个, 待移除会员 " + removeMemberUserIds.size() + "";
}
/**
@@ -453,8 +514,8 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
NutMap change = NutMap.NEW();
change.put("fieldName", "单位");
change.put("field", "unitId");
change.put("sourceValue", unitIdNameMap.get(user.getUnitId()));
change.put("newValue", unitIdNameMap.get(user.getUnitId()));
change.put("sourceValue", getUnitChangeValue(user.getUnitId()));
change.put("newValue", getUnitChangeValue(source.getUnitId()));
changeList.add(change);
// 单位异动发送订阅消息,清空原单位的所有角色
@@ -470,8 +531,8 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
// 生成变更信息描述
String changeInfos = changeList.stream()
.map(v -> v.getString("fieldName") + "" +
HtmlUtil.cleanHtmlTag(v.getString("sourceValue")) + "" +
HtmlUtil.cleanHtmlTag(v.getString("newValue")))
HtmlUtil.cleanHtmlTag(StrUtil.blankToDefault(v.getString("sourceValue"), "")) + "" +
HtmlUtil.cleanHtmlTag(StrUtil.blankToDefault(v.getString("newValue"), "")))
.collect(Collectors.joining(""));
// 设置历史记录信息
@@ -481,4 +542,15 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
return history;
}
/**
* 获取单位变更记录展示值。
* 入参 unitId 为系统用户旧单位或数据源新单位ID;返回值优先使用单位名称,查不到名称时保留单位ID,避免变更记录为空导致更新中断。
*/
private String getUnitChangeValue(String unitId) {
if (StrUtil.isBlank(unitId)) {
return "";
}
return StrUtil.blankToDefault(unitIdNameMap.get(unitId), unitId);
}
}
@@ -21,6 +21,7 @@ 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;
@@ -50,6 +51,10 @@ 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;
@Inject
private SysDictService sysDictService;
@Inject
@@ -115,48 +120,14 @@ 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));
// token url参数
Map<String, String> tokenParams = Map.of(
"grant_type", "password",
"scope", "read",
"username", "3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD",
"password", "3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD"
);
String params = URLUtil.buildQuery(tokenParams, StandardCharsets.UTF_8);
String tokenUrl = "https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/oauth/token" + (StrUtil.isBlank(params) ? "" : "?" + params);
HttpRequest tokenHttpRequest = HttpUtil.createPost(tokenUrl);
tokenHttpRequest.header("Content-Type", "application/json");
tokenHttpRequest.header("Authorization", "Basic MTE0OjU5M2UwNGI4YTE4NWRlMzkyNjY4ZmY0ZDJhZGMyZTEw");
log.info("请求token: {}", tokenHttpRequest);
String tokenResBody = tokenHttpRequest.execute().body();
log.info("请求token结果: {}", tokenResBody);
JSONObject tokenJsonBody = JSONUtil.parseObj(tokenResBody);
// 请求数据
HttpRequest httpRequest = HttpUtil.createGet("https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/get/JZGJCSJZLB");
httpRequest.form(Map.of("access_token", tokenJsonBody.getStr("access_token"), "pageSize", 5000, "page", 1));
log.info("请求人员数据: {}", httpRequest);
String resBody = httpRequest.execute().body();
log.info("请求人员数据结果: {}", resBody);
JSONObject jsonBody = JSONUtil.parseObj(resBody);
if (jsonBody.getInt("code") != 200) {
throw new BaseException("获取人员数据失败,错误码: " + jsonBody.getInt("code") + ";错误原因:" + jsonBody.getStr("msg"));
}
String accessToken = getDmpAccessToken();
List<JSONObject> rawDataList = new ArrayList<>();
JSONArray data = jsonBody.getJSONArray("data");
rawDataList.addAll(pullDmpUsers(getDmpUrl(DMP_TEACHER_KEY), accessToken, "在岗教职工"));
rawDataList.addAll(pullDmpUsers(getDmpUrl(DMP_DISPATCH_KEY), accessToken, "在岗劳务派遣"));
rawDataList = distinctDmpUsers(rawDataList);
if (!data.isEmpty()) {
// 先收集所有原始数据
rawDataList = data.stream().map(v -> (JSONObject) v).toList();
log.info("数据拉取进度: {}/{}", rawDataList.size(), jsonBody.getInt("total"));
} else {
log.warn("当前未获取到数据");
if (rawDataList.isEmpty()) {
log.warn("当前未获取到人员数据");
}
Date nowDate = new Date();
@@ -172,20 +143,24 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
if (mapping.field.getType() == String.class) {
if (StrUtil.isNotBlank(mapping.dict)) {
Sys_data_dict sysDataDict = dataDictMap.get(mapping.dict).stream()
.filter(v -> raw.getStr(mapping.key)
.equals(v.getCode())).findFirst().orElse(new Sys_data_dict());
mapping.field.set(sysUser, sysDataDict.getName());
List<Sys_data_dict> sysDataDicts = dataDictMap.getOrDefault(mapping.dict, Collections.emptyList());
Sys_data_dict sysDataDict = sysDataDicts.stream()
.filter(v -> raw.getStr(mapping.key, "").equals(v.getCode()))
.findFirst().orElse(new Sys_data_dict());
mapping.field.set(sysUser, StrUtil.blankToDefault(sysDataDict.getName(), raw.getStr(mapping.key)));
} else {
// 特殊处理 根据身份证号获取性别和出生年月
if ("SFZJH".equals(mapping.field.getName())) {
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)) {
mapping.field.set(sysUser, normalizeArrivalAtSchoolDate(raw.getStr(mapping.key)));
} else {
mapping.field.set(sysUser, raw.getStr(mapping.key));
}
@@ -198,6 +173,9 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
}
}
sysUser.setUnitName(raw.getStr("SZDW"));
sysUser.setUnitId(resolveSourceUnitId(raw.getStr("SZDWH")));
// 设置拉取时间
sysUser.setPullTime(nowDate);
@@ -206,10 +184,12 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
log.info("用户数据初始化完成,等待插入,当前数据条数{}", latestSourceList.size());
// 插入到数据库
dao().insert(latestSourceList);
if (CollUtil.isNotEmpty(latestSourceList)) {
dao().insert(latestSourceList);
}
// 人员的单位数据和数据库的单位数据比较,如果人员里面有单位不存在,去更新单位数据
List<String> sourceUnitIds = latestSourceList.stream().map(Sys_user_source::getUnitId).distinct().toList();
List<String> sourceUnitIds = latestSourceList.stream().map(Sys_user_source::getUnitId).filter(StrUtil::isNotBlank).distinct().toList();
Sql sql = Sqls.create("select id from sys_unit group by id");
sql.setCallback(Sqls.callback.strList());
dao().execute(sql);
@@ -225,6 +205,159 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
}
}
/**
* 规范化信息中心返回的来校时间。
* 入参 arrivalAtSchoolDate 对应信息中心 LXNY 字段,允许 yyyy-MM-dd 或 yyyy-MM
* 返回值用于 sys_user_source.arrivalAtSchoolDate 和后续 sys_user.arrivalAtSchoolDate,年月格式统一补为当月 01 日。
*/
private String normalizeArrivalAtSchoolDate(String arrivalAtSchoolDate) {
String dateText = StrUtil.trim(arrivalAtSchoolDate);
if (StrUtil.isBlank(dateText)) {
return dateText;
}
if (dateText.matches("\\d{4}-\\d{1,2}-\\d{1,2}")) {
String[] parts = dateText.split("-");
return parts[0] + "-" + StrUtil.padPre(parts[1], 2, '0') + "-" + StrUtil.padPre(parts[2], 2, '0');
}
if (dateText.matches("\\d{4}-\\d{1,2}")) {
String[] parts = dateText.split("-");
return parts[0] + "-" + StrUtil.padPre(parts[1], 2, '0') + "-01";
}
return dateText;
}
/**
* 获取信息中心开放平台访问令牌。
* 返回值为接口后续调用使用的 access_token 字符串。
*/
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);
if (StrUtil.isBlank(url)) {
throw new BaseException("未配置信息中心人员接口地址: data-center.urls." + key);
}
return url;
}
/**
* 分页拉取单个人员接口数据。
* 入参 url 为人员接口地址,accessToken 为信息中心令牌,sourceName 用于日志区分接口来源。
* 返回值为该接口所有分页合并后的原始人员 JSON 列表。
*/
private List<JSONObject> pullDmpUsers(String url, String accessToken, String sourceName) {
List<JSONObject> rawDataList = new ArrayList<>();
int page = 1;
int maxPage = 1;
int total = 0;
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);
JSONObject jsonBody = JSONUtil.parseObj(resBody);
if (jsonBody.getInt("code") != 10000) {
throw new BaseException("获取" + sourceName + "人员数据失败,错误码: " + 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("{}人员数据拉取进度: {}/{}", sourceName, rawDataList.size(), total);
page++;
} while (page <= maxPage);
return rawDataList;
}
/**
* 合并两个接口数据时按职工号去重,避免同一批次出现重复人员。
* 返回值保持第一次出现的数据,用于后续统一映射入库。
*/
private List<JSONObject> distinctDmpUsers(List<JSONObject> rawDataList) {
Map<String, JSONObject> userMap = new LinkedHashMap<>();
for (JSONObject raw : rawDataList) {
String loginName = raw.getStr("ZGH");
if (StrUtil.isBlank(loginName)) {
loginName = raw.getStr("ID");
}
userMap.putIfAbsent(loginName, raw);
}
return new ArrayList<>(userMap.values());
}
/**
* 根据接口返回的所在单位号转换数据源用户单位。
* 入参 rawUnitId 对应人员接口 SZDWH:5位表示三级单位,需要写入其二级父单位;其他长度保持接口原值。
* 返回值为 sys_user_source.unitId 使用的单位ID,找不到三级单位或父级为空时保留接口原始单位号,避免人员数据丢失。
*/
private String resolveSourceUnitId(String rawUnitId) {
if (StrUtil.isBlank(rawUnitId) || rawUnitId.length() != 5) {
return rawUnitId;
}
Sys_unit unit = dao().fetch(Sys_unit.class, rawUnitId);
if (unit == null || StrUtil.isBlank(unit.getParentId())) {
return rawUnitId;
}
return unit.getParentId();
}
@Async
private void updateDict(List<Sys_user_source> userSources) {
//判断是否要更新在职状态字典
@@ -388,70 +521,7 @@ public class SysDataUserPullServiceImpl extends BaseServiceImpl<Sys_user_source>
@Override
public Map<String, NutMap> pullFinance() {
// 获取配置文件 接口地址 和 token
DataCenterProperties.Credential credential = dataCenterProperties.credential("finance");
String url = credential.getUrl();
String token = credential.getToken();
List<JSONObject> rawDataList = new ArrayList<>();
String year = String.valueOf(DateUtil.thisYear());
String month = String.valueOf(DateUtil.thisMonth() + 1);
int pageNum = 1;
int pageSize = 1000;
int totalPages = 1;
int totalCount = 0;
do {
HttpRequest httpRequest = HttpUtil.createPost(url);
httpRequest.header(Header.CONTENT_TYPE, "application/json");
httpRequest.header("Accept-Encoding", "gzip, deflate, br");
httpRequest.header("X-H3C-TOKEN", token);
Map<String, Object> reqBody = Map.of(
"nf", year,
"yf", month,
"pageNum", pageNum,
"pageSize", pageSize
);
httpRequest.body(JSONUtil.toJsonStr(reqBody));
JSONObject resp = JSONUtil.parseObj(httpRequest.execute().body());
if (resp.getInt("code") != 0) {
throw new BaseException("获取财务数据失败,错误码: " + resp.getInt("code") + ";错误原因:" + resp.getStr("msg"));
}
JSONObject data = resp.getJSONObject("data");
if (pageNum == 1) {
totalCount = data.getInt("total", 0);
// totalPages = data.getInt("pages", 0);
totalPages = (int) Math.ceil((double) totalCount / pageSize);
}
JSONArray records = data.getJSONArray("records");
if (CollUtil.isNotEmpty(records)) {
rawDataList.addAll(records.stream().map(v -> (JSONObject) v).toList());
log.info("数据拉取进度: {}/{}", rawDataList.size(), totalCount);
}
pageNum++; // 只加页码
} while (pageNum <= totalPages);
// 接口数据输出
log.info("数据拉取结果: {}", rawDataList);
// 最后结果数据
Map<String, NutMap> result = new HashMap<>();
Map<String, String> api2db = Arrays.stream(Api2FinanceFiledMap.values())
.collect(Collectors.toMap(e -> e.apiField, e -> e.dbColumn));
for (JSONObject row : rawDataList) {
NutMap nutMap = DataCenterUtil.mapJsonToBean(row, NutMap.class, api2db);
result.put(nutMap.getString("loginname"), nutMap);
}
// 输出结果
log.info("财务数据拉取转换结果: {}", result);
log.info("数据拉取完成,共拉取 {} 条数据", result.size());
return result;
// 旧数据中心财务接口已停用,避免继续调用旧token/code模式接口。
throw new BaseException("旧数据中心财务拉取接口已停用");
}
}
@@ -309,9 +309,9 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
String decodePwd = Base64Decoder.decodeStr(passowrd);
String hashedPassword = PwdUtil.getPassword(decodePwd, user.getSalt());
if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) {
// if (Globals.sso) {
// throw new BaseException("用户名或者密码不正确");
// }
if (Globals.sso) {
throw new BaseException("用户名或者密码不正确");
}
}
user = this.fetchLinks(user, "unit");
if (Lang.isNotEmpty(user.getUnit()) && StrUtil.isNotBlank(user.getUnit().getUnionId())) {
@@ -169,16 +169,16 @@ public class ActivitySchoolApply extends BaseModel implements Serializable {
@ColDefine(type = ColType.VARCHAR, width = 50)
private String mobile;
// @Excel(name = "身份证号", width = 20)
@Excel(name = "身份证", width = 25)
private String idCard;
@Column
@Comment("职级")
@Excel(name = "职级", width = 20)
@ColDefine(type = ColType.VARCHAR, width = 50)
private String professionalLevel;
// @Excel(name = "身份证号", width = 20)
private String idCard;
@Column
@Comment("性别")
@Excel(name = "性别", width = 20)
@@ -10,6 +10,7 @@ import com.budwk.app.base.utils.DateUtil;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit;
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnion;
import com.budwk.app.zhgh.activity.culture.models.ActivityTissue;
import com.budwk.app.zhgh.activity.sports.models.ActivitySchool;
import com.budwk.app.zhgh.activity.sports.models.ActivitySchoolApply;
@@ -200,6 +201,7 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
app.activityUnionName unionname,
app.sex,
app.mobile,
u.idcard AS idCard,
app.professionalLevel,
u.userState,
ev.allName,
@@ -244,13 +246,25 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, ActivitySchoolApply.class, excels);
CommonDownloadUtil.download("报名表.xlsx", workbook, response);
CommonDownloadUtil.download(getUnionApplyExportFileName(unionId), workbook, response);
} catch (Exception e) {
e.printStackTrace();
}
}
private String getUnionApplyExportFileName(String unionId) {
String unionName = "分工会";
if (Strings.isNotBlank(unionId)) {
ActivityBasicUnion union = dao().fetch(ActivityBasicUnion.class, unionId);
if (union != null && Strings.isNotBlank(union.getName())) {
unionName = union.getName();
}
}
// 分工会名称可能已经包含“分工会”后缀,避免导出文件名重复拼接。
return unionName.endsWith("分工会") ? unionName + "报名表.xlsx" : unionName + "分工会报名表.xlsx";
}
private static class personType {
@@ -135,6 +135,7 @@ public class TrainSignUpApplyController {
tsuc.courseLocationCoordinates,
tsuc.courseReservedNumber,
tsuc.courseInstructor,
tsuc.courseInstructorMobile,
tsuc.campus,
tsuc.unionLimit,
tsuc.isMobileSign,
@@ -68,6 +68,11 @@ public class TrainSignUpCourse extends BaseModel implements Serializable {
@Comment("课程讲师")
private String courseInstructor;
@Column
@ColDefine(type = ColType.VARCHAR, width = 20)
@Comment("负责人手机号")
private String courseInstructorMobile;
@Column
@ColDefine(type = ColType.VARCHAR, width = 32)
@Comment("校区")
@@ -85,7 +85,7 @@ public class HonorBasicSettingsController {
} else {
dao.updateIgnoreNull(honorBasicSettings);
}
dao.update(Chain.make("hasChildren", true), Cnd.where("id", "=", honorBasicSettings.getParentId()));
dao.update(HonorBasicSettings.class, Chain.make("hasChildren", true), Cnd.where("id", "=", honorBasicSettings.getParentId()));
return Result.success();
} catch (Exception e) {
return Result.error();
@@ -103,7 +103,11 @@ public class HonorBatchController {
u.unionId,
u.unionName,
u.unitId,
u.unitName
u.unitName,
u.sex,
u.birthday,
u.userState,
u.political
FROM
`vw_user` u
""");
@@ -127,6 +131,10 @@ public class HonorBatchController {
user.ifPresent(sysUser -> v.setUnitId(sysUser.getString("unitId")));
user.ifPresent(sysUser -> v.setUnitName(sysUser.getString("unitName")));
user.ifPresent(sysUser -> v.setUserId(sysUser.getString("id")));
user.ifPresent(sysUser -> v.setUserSex(sysUser.getString("sex")));
user.ifPresent(sysUser -> v.setBirthday(sysUser.getString("birthday")));
user.ifPresent(sysUser -> v.setJobStatus(sysUser.getString("userState")));
user.ifPresent(sysUser -> v.setPolitical(sysUser.getString("political")));
} else {
v.setHonorType(getBasicIdByName("集体荣誉"));
//设置分工会
@@ -11,41 +11,41 @@ import java.math.BigDecimal;
import java.util.List;
/**
* 分工会季度额度分配服务。
* 分工会分配项目额度分配服务。
*
* <p>该服务统一处理季度额度分配、批量分配和重置回滚,
* 保证季度记录与年度预算表金额始终同步。</p>
* <p>该服务统一处理会费、评优奖励等分配项目的额度分配、批量分配和重置回滚,
* 保证分配项目记录与年度预算表金额始终同步。</p>
*
* @author zhf
*/
public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllocateUnion> {
/**
* 修改单个分工会的季度分配金额。
* 修改单个分工会的分配项目金额。
*
* @param id outlay_allocate_union 表主键,用于定位当前编辑的季度分配记录
* @param allocateMoney 本次要设置的季度分配金额,传入的是最终金额,不是增量金额
* @param id outlay_allocate_union 表主键,用于定位当前编辑的分配项目记录
* @param allocateMoney 本次要设置的分配项目金额,传入的是最终金额,不是增量金额
* @return Result 成功时返回 success;失败时返回错误信息,前端据此提示用户
*/
Result doEdit(String id, BigDecimal allocateMoney);
/**
* 批量设置某一季度所有分工会的分配金额。
* 批量设置某一分配项目所有分工会的分配金额。
*
* @param allocateMoney 本次批量设置的季度分配金额,所有命中的分工会都会写入该金额
* @param quarterly 要操作的季度,例如 1/2/3/4
* @param year 要操作的年份,用于筛选对应季度的有效分配记录
* @param allocateMoney 本次批量设置的分配项目金额,所有命中的分工会都会写入该金额
* @param quarterly 要操作的分配项目编码,复用 OUTLAY_QUARTERLY 字典
* @param year 要操作的年份,用于筛选对应分配项目的有效记录
* @return Result 成功时返回 success;失败时返回错误信息
*/
Result doBatchAllocate(BigDecimal allocateMoney, Integer quarterly, Integer year);
/**
* 判断某年某季度是否已经做过额度分配。
* 判断某年某分配项目是否已经做过额度分配。
*
* <p>只要当前季度记录中存在分配额度大于 0 的有效记录,
* 就认为该季度已经分配过额度,前端据此决定是否提示再次分配。</p>
* <p>只要当前分配项目记录中存在分配额度大于 0 的有效记录,
* 就认为该分配项目已经分配过额度,前端据此决定是否提示再次分配。</p>
*
* @param quarterly 要检查的季度,例如 1/2/3/4
* @param quarterly 要检查的分配项目编码,取值由 OUTLAY_QUARTERLY 字典维护
* @param year 要检查的年份
* @return true 已分配过;false 未分配
*/
@@ -60,15 +60,28 @@ public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllo
List<OutlayUnionAllocateImportVo> readImportExcel(TempFile file);
/**
* 根据导入数据按分工会逐条分配季度额度。
* 根据导入数据按分工会逐条分配项目额度。
*
* @param importList 导入预览数据
* @param quarterly 当前季度
* @param quarterly 当前分配项目编码
* @param year 当前年度
* @return 导入分配结果
*/
Result doImportAllocate(List<OutlayUnionAllocateImportVo> importList, Integer quarterly, Integer year);
/**
* 给指定分工会新增评优奖励分配记录。
*
* <p>评优奖励属于 OUTLAY_QUARTERLY 字典中的独立分配项目,只针对单个分工会新增;
* 新增后同步累加年度预算表总额度,分工会经费分配详情会按分配项目展示该记录。</p>
*
* @param year 当前预算年度
* @param unionId 要新增评优奖励的分工会 ID
* @param allocateMoney 本次新增的评优奖励金额
* @return Result 成功时返回 success;失败时返回校验原因
*/
Result doAddAwardAllocate(Integer year, String unionId, BigDecimal allocateMoney);
/**
* 导出分工会额度导入模板。
*
@@ -77,24 +90,24 @@ public interface OutlayManageUnionAllocateService extends BaseService<OutLayAllo
Workbook exportImportTemplate();
/**
* 重置指定年度季度的分配记录。
* 重置指定年度分配项目的分配记录。
*
* <p>页面支持切换年度和季度,所以重置动作必须严格使用前端当前选择值,
* 不能再按系统当前自然季度处理,否则会出现页面筛选季度和实际重置季度不一致的问题。</p>
* <p>页面支持切换年度和分配项目,所以重置动作必须严格使用前端当前选择值,
* 不能再按系统当前默认项目处理,否则会出现页面筛选项目和实际重置项目不一致的问题。</p>
*
* @param quarterly 要重置的季度,例如 1/2/3/4
* @param quarterly 要重置的分配项目编码
* @param year 要重置的年份
* @return Result 成功时返回 success;失败时返回错误信息
*/
Result deleteAllocateRecord(Integer quarterly, Integer year);
/**
* 按指定年度季度生成分工会预算记录。
* 按指定年度分配项目生成分工会预算记录。
*
* <p>生成前会先校验该年度季度是否已存在有效记录;
* <p>生成前会先校验该年度分配项目是否已存在有效记录;
* 若已存在,则直接提示前端需要先重置后再重新生成。</p>
*
* @param quarterly 要生成的季度,例如 1/2/3/4
* @param quarterly 要生成的分配项目编码
* @param year 要生成的年份
* @return Result 成功时返回 success;失败时返回错误信息
*/
@@ -33,13 +33,15 @@ import java.util.Map;
import java.util.Set;
/**
* 分工会季度额度分配实现。
* 分工会分配项目额度分配实现。
*
* @author zhf
*/
@IocBean(args = {"refer:dao"})
public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLayAllocateUnion> implements OutlayManageUnionAllocateService {
private static final int AWARD_PROJECT_CODE = 4;
public OutlayManageUnionAllocateServiceImpl(Dao dao) {
super(dao);
}
@@ -50,9 +52,9 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
if (Lang.isEmpty(allocateUnion)) {
return Result.error("分配记录不存在!");
}
int currentQuarter = getCurrentQuarter();
if (allocateUnion.getQuarterly() < currentQuarter) {
return Result.error("当前是第【" + currentQuarter + "季度】无法修改【第" + allocateUnion.getQuarterly() + "季度】的额度!");
int currentProject = getCurrentFeeProject();
if (allocateUnion.getQuarterly() < currentProject) {
return Result.error("当前仅允许修改当前会费项目额度!");
}
applyAllocateMoney(allocateUnion, allocateMoney);
return Result.success();
@@ -60,7 +62,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
@Override
public Result doBatchAllocate(BigDecimal allocateMoney, Integer quarterly, Integer year) {
Result validateResult = validateCurrentQuarterOperation(quarterly);
Result validateResult = validateCurrentPeriodOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
@@ -69,7 +71,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
return Result.error("当前季度没有分配记录!");
return Result.error("当前分配项目没有分配记录!");
}
for (OutLayAllocateUnion allocateUnion : allocateUnionList) {
applyAllocateMoney(allocateUnion, allocateMoney);
@@ -143,7 +145,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
@Override
public Result doImportAllocate(List<OutlayUnionAllocateImportVo> importList, Integer quarterly, Integer year) {
Result validateResult = validateCurrentQuarterOperation(quarterly);
Result validateResult = validateCurrentPeriodOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
@@ -155,7 +157,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
return Result.error("当前季度没有分配记录!");
return Result.error("当前分配项目没有分配记录!");
}
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW());
Map<String, Sys_union> unionMap = new HashMap<>();
@@ -190,7 +192,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
continue;
}
if (!allocateUnionMap.containsKey(union.getId())) {
errorList.add("" + item.getRowNum() + "行:当前季度未生成该分工会分配记录");
errorList.add("" + item.getRowNum() + "行:当前分配项目未生成该分工会分配记录");
}
}
if (!errorList.isEmpty()) {
@@ -199,20 +201,62 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
for (OutlayUnionAllocateImportVo item : importList) {
Sys_union union = unionMap.get(item.getUnionCode());
OutLayAllocateUnion allocateUnion = allocateUnionMap.get(union.getId());
// 导入分配与手工分配保持同一套金额同步规则,确保季度表和年度预算表数据一致。
// 导入分配与手工分配保持同一套金额同步规则,确保分配项目记录和年度预算表数据一致。
applyAllocateMoney(allocateUnion, item.getAllocateMoney());
}
return Result.success("导入分配成功");
}
@Override
public Result doAddAwardAllocate(Integer year, String unionId, BigDecimal allocateMoney) {
if (year == null || StrUtil.isBlank(unionId) || allocateMoney == null) {
return Result.error("参数错误!");
}
if (allocateMoney.compareTo(BigDecimal.ZERO) <= 0) {
return Result.error("评优奖励金额必须大于0");
}
Sys_union union = dao().fetch(Sys_union.class, unionId);
if (Lang.isEmpty(union)) {
return Result.error("分工会不存在!");
}
int count = dao().count(OutLayAllocateUnion.class,
Cnd.where(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getUnionId, "=", unionId)
.and(OutLayAllocateUnion::getQuarterly, "=", AWARD_PROJECT_CODE)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (count > 0) {
return Result.error("该分工会本年度已存在评优奖励记录,请直接编辑已有记录!");
}
OutLayAllocateUnion allocateUnion = new OutLayAllocateUnion();
allocateUnion.setYear(year);
allocateUnion.setUnionId(unionId);
allocateUnion.setQuarterly(AWARD_PROJECT_CODE);
allocateUnion.setAllocateHeadMoney(getCurrentYearSurplusMoney(year, unionId));
allocateUnion.setAllocateMoney(BigDecimal.ZERO);
insert(allocateUnion);
// 新增评优奖励后复用统一金额同步规则,确保分配项目记录和年度预算表 totalQuota 同步。
applyAllocateMoney(allocateUnion, allocateMoney);
return Result.success();
}
@Override
public Workbook exportImportTemplate() {
List<ExcelExportEntity> entityList = new ArrayList<>();
entityList.add(new ExcelExportEntity("工会名称", "unionName", 20));
entityList.add(new ExcelExportEntity("工会编码", "unionCode", 20));
entityList.add(new ExcelExportEntity("分配额度", "allocateMoney", 20));
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW().asc("unionCode"));
List<OutlayUnionAllocateImportVo> templateList = new ArrayList<>();
for (Sys_union union : unionList) {
OutlayUnionAllocateImportVo item = new OutlayUnionAllocateImportVo();
item.setUnionName(union.getName());
item.setUnionCode(union.getUnionCode());
templateList.add(item);
}
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
return ExcelExportUtil.exportExcel(exportParams, entityList, new ArrayList<>());
return ExcelExportUtil.exportExcel(exportParams, entityList, templateList);
}
@Override
@@ -220,7 +264,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
Result validateResult = validateCurrentQuarterOperation(quarterly);
Result validateResult = validateCurrentPeriodOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
@@ -229,7 +273,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (allocateUnionList == null || allocateUnionList.isEmpty()) {
return Result.error("当前季度还未分配,无法重置!");
return Result.error("当前分配项目还未分配,无法重置!");
}
for (OutLayAllocateUnion allocateUnion : allocateUnionList) {
@@ -248,7 +292,7 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
Result validateResult = validateCurrentQuarterOperation(quarterly);
Result validateResult = validateCurrentPeriodOperation(quarterly);
if (validateResult != null) {
return validateResult;
}
@@ -257,10 +301,10 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
.and(OutLayAllocateUnion::getYear, "=", year)
.and(OutLayAllocateUnion::getDelFlag, "=", false));
if (count > 0) {
return Result.error("当前季度已分配,如需重新分配请点击重置分配记录!");
return Result.error("当前分配项目已分配,如需重新分配请点击重置分配记录!");
}
// 第一季度需要承接上一年度剩余额度,其余季度承接当年预算额度,确保生成记录时的分配前额度准确。
// 第一个会费项目需要承接上一年度剩余额度,其余项目承接当年预算额度,确保生成记录时的分配前额度准确。
Integer sourceYear = quarterly == 1 ? year - 1 : year;
List<OutlayManageUnion> outlayManageUnionList = dao().query(OutlayManageUnion.class,
Cnd.where(OutlayManageUnion::getYear, "=", sourceYear));
@@ -270,10 +314,10 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
}
/**
* 按“先回退旧额度,再写入新额度”的方式同步季度记录和年度预算表。
* 按“先回退旧额度,再写入新额度”的方式同步分配项目记录和年度预算表。
*
* @param allocateUnion 当前季度分配记录,包含分工会、年份、旧分配额度等上下文
* @param newAllocateMoney 本次最终要保存的季度分配金额
* @param allocateUnion 当前分配项目记录,包含分工会、年份、旧分配额度等上下文
* @param newAllocateMoney 本次最终要保存的分配项目金额
*/
private void applyAllocateMoney(OutLayAllocateUnion allocateUnion, BigDecimal newAllocateMoney) {
BigDecimal oldAllocateMoney = defaultValue(allocateUnion.getAllocateMoney());
@@ -285,10 +329,14 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
manageUnion = buildManageUnion(allocateUnion, newAllocateMoney);
insert(manageUnion);
} else {
// 当前 totalQuota 里已经包含了旧季度额度,因此要先减旧值,再加新值,避免重复累加。
// 当前 totalQuota 里已经包含了旧项目额度,因此要先减旧值,再加新值,避免重复累加。
BigDecimal newTotalQuota = defaultValue(manageUnion.getTotalQuota())
.subtract(oldAllocateMoney)
.add(newAllocateMoney);
BigDecimal lastYearSurplusMoney = getFirstProjectMissingHeadMoney(allocateUnion, manageUnion);
if (lastYearSurplusMoney.compareTo(BigDecimal.ZERO) != 0) {
newTotalQuota = newTotalQuota.add(lastYearSurplusMoney);
}
dao().update(OutlayManageUnion.class, Chain.make("totalQuota", newTotalQuota),
Cnd.where(OutlayManageUnion::getId, "=", manageUnion.getId()));
}
@@ -298,9 +346,9 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
}
/**
* 回滚当前季度已分配到年度预算表中的金额。
* 回滚当前分配项目已分配到年度预算表中的金额。
*
* @param allocateUnion 当前季度分配记录,allocateMoney 表示本次需要从年度额度中扣回的金额
* @param allocateUnion 当前分配项目记录,allocateMoney 表示本次需要从年度额度中扣回的金额
*/
private void rollbackAllocateMoney(OutLayAllocateUnion allocateUnion) {
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class,
@@ -315,11 +363,43 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
Cnd.where(OutlayManageUnion::getId, "=", manageUnion.getId()));
}
/**
* 第一段会费分配记录的 allocateHeadMoney 保存上一年度剩余额度。
* 如果当前年度预算表已提前生成,导入/一键分配时 totalQuota 可能只包含各分配项目金额,
* 此时需要补入这笔期初结余;已补入过的年度预算再次导入时不重复累加。
*
* @param allocateUnion 当前分配项目记录
* @param manageUnion 当前年度分工会预算记录
* @return BigDecimal 本次需要补入的上一年度剩余额度;无需补入时返回 0
*/
private BigDecimal getFirstProjectMissingHeadMoney(OutLayAllocateUnion allocateUnion, OutlayManageUnion manageUnion) {
if (allocateUnion == null || manageUnion == null || !Integer.valueOf(1).equals(allocateUnion.getQuarterly())) {
return BigDecimal.ZERO;
}
BigDecimal headMoney = defaultValue(allocateUnion.getAllocateHeadMoney());
if (headMoney.compareTo(BigDecimal.ZERO) == 0) {
return BigDecimal.ZERO;
}
List<OutLayAllocateUnion> allocateUnionList = dao().query(OutLayAllocateUnion.class,
Cnd.where(OutLayAllocateUnion::getUnionId, "=", allocateUnion.getUnionId())
.and(OutLayAllocateUnion::getYear, "=", allocateUnion.getYear())
.and(OutLayAllocateUnion::getDelFlag, "=", false));
BigDecimal allocatedTotalMoney = allocateUnionList.stream()
.map(OutLayAllocateUnion::getAllocateMoney)
.map(this::defaultValue)
.reduce(BigDecimal.ZERO, BigDecimal::add);
BigDecimal nonAllocateMoney = defaultValue(manageUnion.getTotalQuota()).subtract(allocatedTotalMoney);
if (nonAllocateMoney.compareTo(BigDecimal.ZERO) == 0) {
return headMoney;
}
return BigDecimal.ZERO;
}
/**
* 当前年份预算表不存在时,按“分配前额度 + 本次分配额度”创建年度预算记录。
*
* @param allocateUnion 当前季度分配记录,allocateHeadMoney 表示生成记录时的剩余额度快照
* @param allocateMoney 本次要设置的季度分配额度
* @param allocateUnion 当前分配项目记录,allocateHeadMoney 表示生成记录时的剩余额度快照
* @param allocateMoney 本次要设置的分配项目额度
* @return OutlayManageUnion 新建的年度预算实体
*/
private OutlayManageUnion buildManageUnion(OutLayAllocateUnion allocateUnion, BigDecimal allocateMoney) {
@@ -347,38 +427,55 @@ public class OutlayManageUnionAllocateServiceImpl extends BaseServiceImpl<OutLay
}
/**
* 计算当前自然季度
* 计算当前年度指定分工会的可用余额,作为新增评优奖励前的额度快照
*
* @return int 当前季度,取值范围 1-4
* @param year 当前预算年度
* @param unionId 分工会 ID
* @return BigDecimal 当前年度总额度减已使用额度;没有年度预算记录时返回 0
*/
private int getCurrentQuarter() {
return DateUtil.month(DateUtil.date()) / 3 + 1;
private BigDecimal getCurrentYearSurplusMoney(Integer year, String unionId) {
OutlayManageUnion manageUnion = dao().fetch(OutlayManageUnion.class,
Cnd.where(OutlayManageUnion::getYear, "=", year)
.and(OutlayManageUnion::getUnionId, "=", unionId));
if (Lang.isEmpty(manageUnion)) {
return BigDecimal.ZERO;
}
return defaultValue(manageUnion.getTotalQuota()).subtract(defaultValue(manageUnion.getUsedQuota()));
}
/**
* 预算季度记录相关操作只能针对当前自然季度执行
* 计算当前会费项目
*
* @param quarterly 前端传入的目标季度
* @return int 当前会费项目,1 表示 1-4月会费,2 表示 5-8月会费,3 表示 9-12月会费
*/
private int getCurrentFeeProject() {
return DateUtil.month(DateUtil.date()) / 4 + 1;
}
/**
* 预算分配项目记录相关操作只能针对当前会费项目执行。
*
* @param quarterly 前端传入的目标分配项目编码,取值由 OUTLAY_QUARTERLY 字典维护
* @return Result 不允许操作时返回错误结果;允许操作时返回 null
*/
private Result validateCurrentQuarterOperation(Integer quarterly) {
private Result validateCurrentPeriodOperation(Integer quarterly) {
if (quarterly == null) {
return Result.error("参数错误!");
}
int currentQuarter = getCurrentQuarter();
if (!quarterly.equals(currentQuarter)) {
return Result.error("当前仅允许操作" + currentQuarter + "季度数据,请切换后再操作!");
int currentProject = getCurrentFeeProject();
if (!quarterly.equals(currentProject)) {
return Result.error("当前仅允许操作当前会费项目数据,请切换后再操作!");
}
return null;
}
/**
* 按目标年度季度初始化要生成的分工会分配记录。
* 按目标年度分配项目初始化要生成的分工会分配记录。
*
* @param outlayManageUnionList 用于计算“分配前额度”的年度预算数据
* @param quarterly 目标季度
* @param quarterly 目标分配项目编码
* @param year 目标年度
* @return List<OutLayAllocateUnion> 待插入的季度分配记录
* @return List<OutLayAllocateUnion> 待插入的分配项目记录
*/
private List<OutLayAllocateUnion> buildAllocateUnionList(List<OutlayManageUnion> outlayManageUnionList, Integer quarterly, Integer year) {
List<Sys_union> unionList = dao().query(Sys_union.class, Cnd.NEW());
@@ -38,13 +38,13 @@ import java.util.List;
/**
* @author zhf
* @date 2026/2/3 11:12
* @description 分工会经费分配
* @description 分工会经费分配项目管理
*/
@IocBean
@At("/platform/outlay/outlayManage/unionAllocate")
@Ok("json:full")
@Slf4j
@Api(tags = "分工会经费分配")
@Api(tags = "分工会经费分配项目管理")
public class OutlayManageUnionAllocateController {
@Inject
@@ -100,11 +100,13 @@ public class OutlayManageUnionAllocateController {
@At
@ApiOperation("一键批量分配所有工会额度")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "分工会预算-季度预算分配", msg = "一键批量分配所有工会额度")
@SLog(tag = "分工会预算-分配项目预算分配", msg = "一键批量分配所有工会额度")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result doBatchAllocate(@Param("allocateMoney") BigDecimal allocateMoney,
@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
// 参数说明:allocateMoney 为本次写入的分配额度;quarterly 承载 OUTLAY_QUARTERLY 字典编码,对应会费、评优奖励等分配项目;year 为预算年度。
// 返回 Result,成功时前端刷新列表,失败时 msg 字段用于页面提示。
if (allocateMoney == null || quarterly == null || year == null) {
return Result.error("参数错误!");
}
@@ -112,7 +114,7 @@ public class OutlayManageUnionAllocateController {
}
@At
@ApiOperation("校验当前季度是否已分配额度")
@ApiOperation("校验当前分配项目是否已分配额度")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result hasAllocated(@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
@@ -139,11 +141,13 @@ public class OutlayManageUnionAllocateController {
@At
@ApiOperation("导入分配分工会额度")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "分工会预算-季度预算分配", msg = "导入分配分工会额度")
@SLog(tag = "分工会预算-分配项目预算分配", msg = "导入分配分工会额度")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result doImportAllocate(String data,
@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
// 参数说明:data 为导入预览行 JSON;quarterly 为分配项目字典编码;year 为预算年度。
// 返回 Result,成功表示导入额度已同步到分配项目记录和年度预算表,失败时 msg 字段返回具体校验原因。
if (StrUtil.isBlank(data) || quarterly == null || year == null) {
return Result.error("参数错误!");
}
@@ -151,6 +155,22 @@ public class OutlayManageUnionAllocateController {
return outlayManageUnionAllocateService.doImportAllocate(importList, quarterly, year);
}
@At
@ApiOperation("新增单个分工会评优奖励")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "分工会预算-分配项目预算分配", msg = "新增单个分工会评优奖励")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result doAddAwardAllocate(@Param("year") Integer year,
@Param("unionId") String unionId,
@Param("allocateMoney") BigDecimal allocateMoney) {
// 参数说明:year 为预算年度;unionId 为分工会 IDallocateMoney 为本次新增的评优奖励金额。
// 返回 Result,成功后前端刷新分配列表;失败时 msg 字段返回参数或重复新增等校验原因。
if (year == null || StrUtil.isBlank(unionId) || allocateMoney == null) {
return Result.error("参数错误!");
}
return outlayManageUnionAllocateService.doAddAwardAllocate(year, unionId, allocateMoney);
}
@At
@Ok("void")
@ApiOperation("下载导入分配模板")
@@ -166,12 +186,13 @@ public class OutlayManageUnionAllocateController {
@At
@ApiOperation("重置预算季度记录")
@ApiOperation("重置预算分配记录")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "分工会预算-季度预算分配", msg = "重置预算季度记录")
@SLog(tag = "分工会预算-分配项目预算分配", msg = "重置预算分配记录")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result deleteAllocateRecord(@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
// 参数说明:quarterly 为当前要重置的分配项目编码,year 为预算年度;返回 Result 用于提示重置是否成功。
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
@@ -179,11 +200,13 @@ public class OutlayManageUnionAllocateController {
}
@At
@ApiOperation("预算季度记录生成")
@SLog(tag = "分工会预算-季度预算分配", msg = "生成了预算分配记录")
@ApiOperation("预算分配记录生成")
@Aop(TransAop.READ_COMMITTED)
@SLog(tag = "分工会预算-分配项目预算分配", msg = "生成了预算分配记录")
@SaCheckPermission("outlay.outlayManage.union.allocate")
public Result doAllocateRecord(@Param("quarterly") Integer quarterly,
@Param("year") Integer year) {
// 参数说明:quarterly 为本次生成记录的分配项目编码,year 为预算年度;返回 Result 用于前端提示生成结果。
if (quarterly == null || year == null) {
return Result.error("参数错误!");
}
@@ -0,0 +1,142 @@
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo.OutlayUnionIncomeExpenseVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Strings;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
* 二级分工会经费收支使用情况表。
*/
@IocBean
@At("/platform/outlay/outlayManage/unionIncomeExpense")
@Ok("json:full")
@Slf4j
@Api(tags = "二级分工会经费收支使用情况表")
public class OutlayManageUnionIncomeExpenseController {
@Inject
private BaseService baseService;
@At("")
@Ok("beetl:/platform/zhgh/dayofficework/outlay/outlayManage/union/incomeExpense/index.html")
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
public void index() {
}
@At
@ApiOperation("分页查询")
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
public Result pageData(PageForm pageForm, Integer year, String unionId) {
Sql sql = buildIncomeExpenseSql(year, unionId);
Pagination pagination = baseService.listPageVO(pageForm, sql, OutlayUnionIncomeExpenseVO.class);
return Result.success(pagination);
}
@At
@Ok("void")
@ApiOperation("导出")
@SaCheckPermission("outlay.outlayManage.union.incomeExpense")
public void doExport(Integer year, String unionId, HttpServletResponse response) {
Integer queryYear = getQueryYear(year);
Sql sql = buildIncomeExpenseSql(queryYear, unionId);
List<OutlayUnionIncomeExpenseVO> list = baseService.listVO(sql, OutlayUnionIncomeExpenseVO.class);
ArrayList<ExcelExportEntity> entities = new ArrayList<>();
entities.add(new ExcelExportEntity("单位", "unionName", 25));
entities.add(new ExcelExportEntity("年初数", "beginMoney", 20));
entities.add(new ExcelExportEntity("1-4月会费", "feeJanApr", 20));
entities.add(new ExcelExportEntity("5-8月会费", "feeMayAug", 20));
entities.add(new ExcelExportEntity("9-12月会费", "feeSepDec", 20));
entities.add(new ExcelExportEntity("评优奖励", "awardMoney", 20));
entities.add(new ExcelExportEntity("1-12月支出", "usedMoney", 20));
entities.add(new ExcelExportEntity("经费余额", "remainMoney", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entities, list);
CommonDownloadUtil.download(queryYear + "年二级分工会经费收支使用情况表.xlsx", workbook, response);
}
/**
* 统计参数说明:
* year 为统计年度,未传时默认当前年份;unionId 为二级分工会主键,管理员可为空查询全部。
* 返回 VO 中 beginMoney 是年初数,feeJanApr/feeMayAug/feeSepDec 是三个会费收入段,
* awardMoney 是评优奖励,usedMoney 是年度支出,remainMoney 是当前经费余额。
*/
private Sql buildIncomeExpenseSql(Integer year, String unionId) {
Sql sql = Sqls.create("""
SELECT
mu.year AS year,
mu.unionId AS unionId,
COALESCE(mu.unionName, su.name) AS unionName,
COALESCE(mu.unionCode, su.unionCode) AS unionCode,
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateHeadMoney ELSE 0 END), 0) AS beginMoney,
COALESCE(SUM(CASE WHEN au.quarterly = 1 THEN au.allocateMoney ELSE 0 END), 0) AS feeJanApr,
COALESCE(SUM(CASE WHEN au.quarterly = 2 THEN au.allocateMoney ELSE 0 END), 0) AS feeMayAug,
COALESCE(SUM(CASE WHEN au.quarterly = 3 THEN au.allocateMoney ELSE 0 END), 0) AS feeSepDec,
COALESCE(SUM(CASE WHEN au.quarterly = 4 THEN au.allocateMoney ELSE 0 END), 0) AS awardMoney,
COALESCE(mu.usedQuota, 0) AS usedMoney,
COALESCE(mu.totalQuota, 0) - COALESCE(mu.usedQuota, 0) AS remainMoney
FROM outlay_manage_union mu
LEFT JOIN sys_union su ON su.id = mu.unionId
LEFT JOIN outlay_allocate_union au ON au.year = mu.year
AND au.unionId = mu.unionId
AND au.delFlag = 0
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("mu.delFlag", "=", false);
cnd.and("mu.year", "=", getQueryYear(year));
cnd.and("mu.totalQuota", "IS NOT", null);
cnd.andEX("mu.unionId", "=", unionId);
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("mu.unionId", "=", SecurityUtil.getUnionId());
}
cnd.groupBy("mu.year");
cnd.groupBy("mu.unionId");
cnd.groupBy("mu.unionName");
cnd.groupBy("mu.unionCode");
cnd.groupBy("su.name");
cnd.groupBy("su.unionCode");
cnd.groupBy("mu.usedQuota");
cnd.groupBy("mu.totalQuota");
cnd.asc("mu.unionCode");
sql.setCondition(cnd);
return sql;
}
private Integer getQueryYear(Integer year) {
if (year != null) {
return year;
}
return DateUtil.thisYear();
}
}
@@ -116,7 +116,7 @@ public class OutlayManageUnionUseDetailController {
}
@At
@ApiOperation("查询分工会今年每个季度的分配情况")
@ApiOperation("查询分工会今年每个分配项目的分配情况")
@SaCheckPermission("outlay.outlayManage.union.useDetail")
public Result queryQuarterlyList(Integer year, String unionId){
Sql sql = Sqls.create("""
@@ -37,7 +37,7 @@ public class OutLayAllocateUnion extends BaseModel implements Serializable {
private String unionId;
@Column
@Comment("季度")
@Comment("分配项目")
@ColDefine(type = ColType.INT)
private Integer quarterly;
@@ -6,22 +6,20 @@ import lombok.Data;
import java.math.BigDecimal;
/**
* 分工会季度额度导入行数据。
* 分工会分配项目额度导入行数据。
*/
@Data
public class OutlayUnionAllocateImportVo {
@Excel(name = "工会名称")
private String unionName;
@Excel(name = "工会编码")
private String unionCode;
@Excel(name = "分配额度")
private BigDecimal allocateMoney;
/**
* 预览时展示匹配到的工会名称。
*/
private String unionName;
/**
* 预览时展示当前行错误信息。
*/
@@ -0,0 +1,34 @@
package com.budwk.app.zhgh.dayofficework.outlay.outlayManage.union.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
* 二级分工会经费收支使用情况表数据。
*/
@Data
public class OutlayUnionIncomeExpenseVO {
private Integer year;
private String unionId;
private String unionName;
private String unionCode;
private BigDecimal beginMoney;
private BigDecimal feeJanApr;
private BigDecimal feeMayAug;
private BigDecimal feeSepDec;
private BigDecimal awardMoney;
private BigDecimal usedMoney;
private BigDecimal remainMoney;
}
@@ -307,6 +307,9 @@ public class SiteCugApplyController {
if (item == null || StrUtil.hasBlank(item.getReserveStartTime(), item.getReserveEndTime())) {
continue;
}
if (isOccupiedByCurrentUser(item)) {
continue;
}
DateTime reserveStart = DateUtil.parseDateTime(item.getReserveStartTime());
DateTime reserveEnd = DateUtil.parseDateTime(item.getReserveEndTime());
if (!reserveEnd.isAfter(reserveStart)) {
@@ -389,6 +392,13 @@ public class SiteCugApplyController {
}
}
// 当前登录人占用了该预约时,该预约占用的时间块对当前登录人放开,对其他人仍保持锁定
private boolean isOccupiedByCurrentUser(SiteCugApply apply) {
return apply != null
&& StrUtil.isNotBlank(apply.getOccupyUserId())
&& StrUtil.equals(apply.getOccupyUserId(), SecurityUtil.getUserId());
}
private boolean intersectsAny(int start, int end, List<int[]> ranges) {
for (int[] range : ranges) {
if (range != null && start < range[1] && end > range[0]) {
@@ -693,11 +703,11 @@ public class SiteCugApplyController {
@SaCheckPermission(value = {"siteCug.apply", "h5.siteCug.apply"}, mode = SaMode.OR)
public Result timeLimitConfig(@Param("siteId") String siteId) {
if (StrUtil.isBlank(siteId)) {
return Result.success(NutMap.NEW().addv("filterHolidays", false).addv("holidayList", new ArrayList<>()).addv("notApplyTimeList", new ArrayList<>()));
return Result.success(NutMap.NEW().addv("filterHolidays", false).addv("holidayList", new ArrayList<>()).addv("notApplyTimeList", new ArrayList<>()).addv("termStartDate", "").addv("termEndDate", ""));
}
SiteCugInfo info = infoService.fetch(siteId);
if (info == null) {
return Result.success(NutMap.NEW().addv("filterHolidays", false).addv("holidayList", new ArrayList<>()).addv("notApplyTimeList", new ArrayList<>()));
return Result.success(NutMap.NEW().addv("filterHolidays", false).addv("holidayList", new ArrayList<>()).addv("notApplyTimeList", new ArrayList<>()).addv("termStartDate", "").addv("termEndDate", ""));
}
List<String> holidayList = new ArrayList<>();
if (Boolean.TRUE.equals(info.getFilterHolidays())) {
@@ -713,7 +723,9 @@ public class SiteCugApplyController {
return Result.success(NutMap.NEW()
.addv("filterHolidays", Boolean.TRUE.equals(info.getFilterHolidays()))
.addv("holidayList", holidayList)
.addv("notApplyTimeList", info.getNotApplyTimeList() == null ? new ArrayList<>() : info.getNotApplyTimeList()));
.addv("notApplyTimeList", info.getNotApplyTimeList() == null ? new ArrayList<>() : info.getNotApplyTimeList())
.addv("termStartDate", info.getTermStartDate() != null ? info.getTermStartDate() : "")
.addv("termEndDate", info.getTermEndDate() != null ? info.getTermEndDate() : ""));
}
private List<SiteCugApply> buildYearlyApplyList(SiteCugApply apply) {
@@ -819,5 +831,22 @@ public class SiteCugApplyController {
for (ProcessTask task : doingTaskList) {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
if (applyService.shouldDirectFinishOccupiedApply(apply)) {
directFinishOccupiedApply(instance, args);
}
}
// 占用人提交与占用时间交叉的预约时,复用已有流程引擎自动结束后续审核任务
private void directFinishOccupiedApply(ProcessInstance instance, Dict args) {
List<ProcessTask> doingTaskList = flowEngine.processTaskService().getDoingTaskList(instance.getId(), null);
if (doingTaskList.isEmpty()) {
return;
}
Dict directArgs = args.clone();
directArgs.set(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.AGREE.getCode());
directArgs.set(FlowConst.APPROVAL_COMMENT, "占用预约自动通过");
for (ProcessTask task : doingTaskList) {
flowEngine.executeAndJumpToEnd(task.getId(), FlowConst.AUTO_ID, directArgs);
}
}
}
@@ -105,6 +105,13 @@ public class SiteCugManageController {
if ((fullDayOpenHour == null || fullDayOpenHour.isEmpty()) && info.getReserveTimeType() == 2 && info.getOpenHours() != null && !info.getOpenHours().isEmpty()) {
fullDayOpenHour = info.getOpenHours().get(0);
}
// 场地预约次数限制作为后续提交校验的依据,保存场地时必须配置为正整数
if (info.getUnionYearReserveLimit() == null || info.getUnionYearReserveLimit() <= 0) {
return Result.error("分工会每年预约次数必须大于0");
}
if (info.getClubWeekReserveLimit() == null || info.getClubWeekReserveLimit() <= 0) {
return Result.error("社团每周预约次数必须大于0");
}
if (info.getReserveTimeType() == 1) {
if (segmentedOpenHours == null || segmentedOpenHours.isEmpty()) {
return Result.error("Please add at least one booking slot");
@@ -1,6 +1,7 @@
package com.budwk.app.zhgh.dayofficework.siteCug.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.engine.FlowEngine;
@@ -24,6 +25,7 @@ import org.nutz.mvc.annotation.Param;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
@IocBean
@Ok("json:full")
@@ -87,6 +89,28 @@ public class SiteCugRecordController {
return Result.success();
}
@At
@ApiOperation("占用预约记录")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("siteCug.record")
public Result occupy(@Param("id") String id, @Param("message") String message) {
Map<Boolean, String> result = applyService.occupyRecord(id, message, false);
return result.containsKey(false) ? Result.error(result.get(false)) : Result.success(result.get(true));
}
@At
@ApiOperation("批量占用预约记录")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission("siteCug.record")
public Result occupyBatch(@Param("ids") String ids, @Param("message") String message) {
if (StrUtil.isBlank(ids)) {
return Result.error("请选择需要占用的预约");
}
List<String> idList = StrUtil.split(ids, ",").stream().filter(StrUtil::isNotBlank).toList();
Map<Boolean, String> result = applyService.occupyRecords(idList, message, false);
return result.containsKey(false) ? Result.error(result.get(false)) : Result.success(result.get(true));
}
@At
@Ok("void")
@ApiOperation("导出预约记录")
@@ -110,5 +110,15 @@ public class SiteCugApply extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 200)
private String backOption;
@Column
@Comment("占用人ID")
@ColDefine(type = ColType.VARCHAR, width = 32)
private String occupyUserId;
@Column
@Comment("占用通知消息")
@ColDefine(type = ColType.VARCHAR, width = 1000)
private String occupyMessage;
private String yearlyReserveEndDate;
}
@@ -73,6 +73,28 @@ public class SiteCugInfo extends BaseModel {
@ColDefine(type = ColType.INT)
private Integer sexLimit;
@Column
@Comment("本学期开始时间")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String termStartDate;
@Column
@Comment("本学期结束时间")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String termEndDate;
@Column
@Comment("分工会每年预约次数")
@ColDefine(type = ColType.INT)
@Default("2")
private Integer unionYearReserveLimit;
@Column
@Comment("社团每周预约次数")
@ColDefine(type = ColType.INT)
@Default("2")
private Integer clubWeekReserveLimit;
@Column
@Comment("场地的禁用时间")
@ColDefine(type = ColType.MYSQL_JSON)
@@ -7,6 +7,7 @@ import org.nutz.dao.Cnd;
import org.nutz.dao.sql.Sql;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
public interface SiteCugApplyService extends BaseService<SiteCugApply> {
@@ -21,4 +22,13 @@ public interface SiteCugApplyService extends BaseService<SiteCugApply> {
// 场馆预约查询页的导出逻辑统一放在 service,controller 只负责接收请求
void exportRecord(SiteCugRecordPageForm pageForm, HttpServletResponse response);
// 占用单条预约记录,保存占用人和通知内容;真实发送消息代码当前保留为注释,便于测试流程
Map<Boolean, String> occupyRecord(String id, String message, boolean sendMsg);
// 批量占用预约记录,先统一校验再保存,避免出现部分记录已占用、部分记录失败的状态
Map<Boolean, String> occupyRecords(List<String> ids, String message, boolean sendMsg);
// 判断当前预约是否命中当前登录人的占用时间段,命中后提交预约可自动通过审核
boolean shouldDirectFinishOccupiedApply(SiteCugApply apply);
}
@@ -10,10 +10,10 @@ import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
import com.budwk.app.sys.models.SysHoliday;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.sys.services.SysMsgService;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.club.model.SysClub;
import com.budwk.app.zhgh.club.service.SysClubService;
@@ -46,6 +46,8 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
@Inject
private SysClubService sysClubService;
@Inject
private SysMsgService sysMsgService;
public SiteCugApplyServiceImpl(Dao dao) {
super(dao);
@@ -78,6 +80,10 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
if (!Boolean.TRUE.equals(siteInfo.getState())) {
return Map.of(false, "该场地未开启预约");
}
Map<Boolean, String> termDateRangeValidate = validateTermDateRange(apply, siteInfo);
if (termDateRangeValidate.containsKey(false)) {
return termDateRangeValidate;
}
if (apply.getJoinCount() == null || apply.getJoinCount() <= 0) {
return Map.of(false, "预约人数必须大于0");
}
@@ -96,6 +102,10 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
if (intersectsDisabledTime(siteInfo, apply.getReserveStartTime(), apply.getReserveEndTime())) {
return Map.of(false, "预约时间落在禁用时间内");
}
Map<Boolean, String> reserveLimitValidate = validateReserveLimit(apply, siteInfo);
if (reserveLimitValidate.containsKey(false)) {
return reserveLimitValidate;
}
Sql sql = Sqls.create("""
select
@@ -108,8 +118,7 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
Cnd cnd = Cnd.NEW();
cnd.and(SiteCugApply::getSiteId, "=", apply.getSiteId());
cnd.andEX("sa.id", "!=", apply.getId());
List<Integer> stateList = List.of(ProcessInstanceStateEnum.DOING.getCode(), ProcessInstanceStateEnum.FINISHED.getCode(), ProcessInstanceStateEnum.PENDING.getCode());
cnd.and(ProcessInstance::getState, "in", stateList);
cnd.and("ins.state", "in", buildEffectiveProcessStateList());
sql.setCondition(cnd);
List<SiteCugApply> applyList = listEntity(sql);
@@ -118,6 +127,9 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
boolean overlap = DateUtil.parseDateTime(item.getReserveStartTime()).isBefore(DateUtil.parseDateTime(apply.getReserveEndTime()))
&& DateUtil.parseDateTime(item.getReserveEndTime()).isAfter(DateUtil.parseDateTime(apply.getReserveStartTime()));
if (overlap) {
if (isOccupiedByCurrentUser(item)) {
continue;
}
if (StrUtil.isBlank(apply.getId()) && StrUtil.equals(item.getApplyUserId(), SecurityUtil.getUserId())) {
return Map.of(false, "该时间段您已存在预约");
}
@@ -127,6 +139,236 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
return Map.of(true, "");
}
// 分工会预约必须落在后台配置的本学期时间内,批量预约逐条复用该校验防止接口越权提交学期外日期
private Map<Boolean, String> validateTermDateRange(SiteCugApply apply, SiteCugInfo siteInfo) {
if (!StrUtil.equals(apply.getReserveType(), "union")
|| StrUtil.hasBlank(siteInfo.getTermStartDate(), siteInfo.getTermEndDate())) {
return Map.of(true, "");
}
try {
DateTime reserveStart = DateUtil.parseDateTime(apply.getReserveStartTime());
DateTime reserveEnd = DateUtil.parseDateTime(apply.getReserveEndTime());
Date termStart = DateUtil.beginOfDay(DateUtil.parseDate(siteInfo.getTermStartDate()));
Date termEnd = DateUtil.endOfDay(DateUtil.parseDate(siteInfo.getTermEndDate()));
if (reserveStart.isBefore(termStart) || reserveEnd.isAfter(termEnd)) {
return Map.of(false, "预约时间必须在本学期时间范围内");
}
return Map.of(true, "");
} catch (Exception e) {
return Map.of(false, "本学期时间配置有误,请联系管理员处理");
}
}
@Override
public Map<Boolean, String> occupyRecord(String id, String message, boolean sendMsg) {
if (StrUtil.isBlank(message)) {
return Map.of(false, "请填写通知消息");
}
SiteCugApply apply = fetch(id);
if (apply == null) {
return Map.of(false, "记录不存在");
}
Map<Boolean, String> validate = validateOccupyApply(apply);
if (validate.containsKey(false)) {
return validate;
}
saveOccupyApply(apply, message, sendMsg);
return Map.of(true, "占用成功");
}
// 已通过校验后统一保存占用信息;测试阶段真实发送消息代码保留注释
private void saveOccupyApply(SiteCugApply apply, String message, boolean sendMsg) {
// 保存占用人和通知内容,后续预约校验据此只放行当前占用人
apply.setOccupyUserId(SecurityUtil.getUserId());
apply.setOccupyMessage(message);
updateIgnoreNull(apply);
// 测试占用流程时先不真实发送消息,保留日志用于确认保存和跳转链路是否正常
log.info("场地预约占用测试消息,applyId={}receiverLoginName={}message={}", apply.getId(), apply.getApplyLoginName(), message);
if (sendMsg) {
// sysMsgService.sendMsgInSys(List.of(apply.getApplyLoginName()), "场地预约占用通知", message, SecurityUtil.getUserId());
}
}
@Override
public Map<Boolean, String> occupyRecords(List<String> ids, String message, boolean sendMsg) {
if (ids == null || ids.isEmpty()) {
return Map.of(false, "请选择需要占用的预约");
}
if (StrUtil.isBlank(message)) {
return Map.of(false, "请填写通知消息");
}
List<SiteCugApply> applyList = new ArrayList<>();
for (String id : ids) {
SiteCugApply apply = fetch(id);
if (apply == null) {
return Map.of(false, "记录不存在");
}
Map<Boolean, String> validate = validateOccupyApply(apply);
if (validate.containsKey(false)) {
return validate;
}
applyList.add(apply);
}
for (SiteCugApply apply : applyList) {
saveOccupyApply(apply, message, sendMsg);
}
return Map.of(true, "占用成功");
}
// 占用前统一校验预约状态,避免单条和批量接口出现不同判断
private Map<Boolean, String> validateOccupyApply(SiteCugApply apply) {
if (StrUtil.isBlank(apply.getApplyLoginName())) {
return Map.of(false, "预约人工号为空,无法发送消息");
}
if (StrUtil.isBlank(apply.getReserveStartTime()) || !DateUtil.parseDateTime(apply.getReserveStartTime()).isAfter(DateUtil.date())) {
return Map.of(false, "预约已开始,不能占用");
}
Integer state = queryInstanceState(apply.getId());
if (state == null || state != ProcessInstanceStateEnum.FINISHED.getCode()) {
return Map.of(false, "仅可占用已通过且未开始的预约记录");
}
if (StrUtil.isNotBlank(apply.getOccupyUserId()) && !StrUtil.equals(apply.getOccupyUserId(), SecurityUtil.getUserId())) {
return Map.of(false, "该预约已被其他人占用");
}
return Map.of(true, "");
}
private Integer queryInstanceState(String id) {
Sql sql = Sqls.create("""
SELECT
ins.state AS instanceState
FROM
site_cug_apply info
LEFT JOIN wf_process_instance ins ON ins.businessNo = info.id
WHERE info.id = @id
""");
sql.params().set("id", id);
sql.setCallback(Sqls.callback.maps());
dao().execute(sql);
List<NutMap> list = sql.getList(NutMap.class);
return list != null && !list.isEmpty() ? list.get(0).getInt("instanceState") : null;
}
// 当前登录人占用了该记录时,允许其再次提交与该记录有交叉的预约
private boolean isOccupiedByCurrentUser(SiteCugApply apply) {
return apply != null
&& StrUtil.isNotBlank(apply.getOccupyUserId())
&& StrUtil.equals(apply.getOccupyUserId(), SecurityUtil.getUserId());
}
@Override
public boolean shouldDirectFinishOccupiedApply(SiteCugApply apply) {
if (apply == null || StrUtil.hasBlank(apply.getSiteId(), apply.getReserveStartTime(), apply.getReserveEndTime())) {
return false;
}
Sql sql = Sqls.create("""
select
sa.*
from
site_cug_apply sa
left join wf_process_instance ins on ins.businessNo = sa.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("sa.siteId", "=", apply.getSiteId());
cnd.andEX("sa.id", "!=", apply.getId());
cnd.and("sa.occupyUserId", "=", SecurityUtil.getUserId());
cnd.and("ins.state", "=", ProcessInstanceStateEnum.FINISHED.getCode());
sql.setCondition(cnd);
List<SiteCugApply> applyList = listEntity(sql);
// 只要新预约时间和当前登录人占用的已通过预约有交叉,就允许本次预约免审通过
return applyList.stream().anyMatch(item ->
DateUtil.parseDateTime(item.getReserveStartTime()).isBefore(DateUtil.parseDateTime(apply.getReserveEndTime()))
&& DateUtil.parseDateTime(item.getReserveEndTime()).isAfter(DateUtil.parseDateTime(apply.getReserveStartTime()))
);
}
// 按预约主体统计有效预约次数,批量预约同一个批次号只计一次,避免一次批量提交占用多次额度
private Map<Boolean, String> validateReserveLimit(SiteCugApply apply, SiteCugInfo siteInfo) {
if (StrUtil.equals(apply.getReserveType(), "union")) {
if (siteInfo.getUnionYearReserveLimit() == null || siteInfo.getUnionYearReserveLimit() <= 0) {
return Map.of(false, "请先配置分工会每年预约次数");
}
String[] range = buildYearRange(apply.getReserveStartTime());
long count = countEffectiveReserveTimes(apply, "sa.applyUnionId", apply.getApplyUnionId(), range[0], range[1]);
if (count >= siteInfo.getUnionYearReserveLimit()) {
return Map.of(false, "该分工会本年度预约次数已达" + siteInfo.getUnionYearReserveLimit() + "次,不能继续预约");
}
}
if (StrUtil.equals(apply.getReserveType(), "club")) {
if (siteInfo.getClubWeekReserveLimit() == null || siteInfo.getClubWeekReserveLimit() <= 0) {
return Map.of(false, "请先配置社团每周预约次数");
}
String[] range = buildWeekRange(apply.getReserveStartTime());
long count = countEffectiveReserveTimes(apply, "sa.clubId", apply.getClubId(), range[0], range[1]);
if (count >= siteInfo.getClubWeekReserveLimit()) {
return Map.of(false, "该协会本周预约次数已达" + siteInfo.getClubWeekReserveLimit() + "次,不能继续预约");
}
}
return Map.of(true, "");
}
// 分工会每年次数按预约开始时间所在自然年统计
private String[] buildYearRange(String reserveStartTime) {
DateTime reserveStart = DateUtil.parseDateTime(reserveStartTime);
String year = String.valueOf(reserveStart.year());
return new String[]{year + "-01-01 00:00:00", year + "-12-31 23:59:59"};
}
// 协会每周次数按自然周统计,周一为开始、周日为结束
private String[] buildWeekRange(String reserveStartTime) {
DateTime reserveStart = DateUtil.parseDateTime(reserveStartTime);
int week = reserveStart.dayOfWeek() - 1;
int offsetToMonday = week == 0 ? -6 : 1 - week;
DateTime weekStart = DateUtil.offsetDay(reserveStart, offsetToMonday);
DateTime weekEnd = DateUtil.offsetDay(weekStart, 6);
return new String[]{DateUtil.formatDate(weekStart) + " 00:00:00", DateUtil.formatDate(weekEnd) + " 23:59:59"};
}
// 统计预约主体在指定时间范围内的有效预约次数,所有场地合计,不按场地过滤
private long countEffectiveReserveTimes(SiteCugApply apply, String targetField, String targetId, String rangeStart, String rangeEnd) {
if (StrUtil.isBlank(targetId)) {
return 0;
}
Sql sql = Sqls.create("""
select
sa.*
from
site_cug_apply sa
left join wf_process_instance ins on ins.businessNo = sa.id
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.andEX("sa.reserveType", "=", apply.getReserveType());
cnd.andEX(targetField, "=", targetId);
cnd.andEX("sa.reserveStartTime", ">=", rangeStart);
cnd.andEX("sa.reserveStartTime", "<=", rangeEnd);
if (StrUtil.isNotBlank(apply.getId())) {
cnd.andEX("sa.id", "!=", apply.getId());
}
cnd.and("ins.state", "in", buildEffectiveProcessStateList());
sql.setCondition(cnd);
List<SiteCugApply> applyList = listEntity(sql);
return applyList.stream()
.map(this::buildReserveCountKey)
.distinct()
.count();
}
// 只有待审核、办理中、已通过的流程占用预约次数,驳回记录不占额度
private List<Integer> buildEffectiveProcessStateList() {
return List.of(ProcessInstanceStateEnum.DOING.getCode(), ProcessInstanceStateEnum.FINISHED.getCode(), ProcessInstanceStateEnum.PENDING.getCode());
}
// 批量预约同一批次号只算一次,普通预约按单条申请计算
private String buildReserveCountKey(SiteCugApply apply) {
if (apply != null && StrUtil.isNotBlank(apply.getBackOption()) && apply.getBackOption().startsWith("YEARLY_BATCH:")) {
return apply.getBackOption();
}
return apply == null ? "" : apply.getId();
}
@Override
public Sql buildRecordSql() {
// 场馆预约查询页和导出页共用同一套返回字段,统一在 service 中维护,避免 controller 重复拼 SQL
@@ -135,6 +377,7 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
info.*,
si.name AS siteName,
ins.id AS instanceId,
ins.state AS instanceState,
ins.processDefineId instanceProcessDefineId,
CASE WHEN info.backOption LIKE 'YEARLY_BATCH:%' THEN 1 ELSE 0 END AS yearlyBatch,
CASE WHEN info.reserveType = 'club' THEN '协会预约' ELSE '分工会预约' END AS reserveTypeName,
@@ -315,7 +558,3 @@ public class SiteCugApplyServiceImpl extends BaseServiceImpl<SiteCugApply> imple
return Map.of(false, "预约类型不合法");
}
}
@@ -111,8 +111,6 @@ public class UnionReimburseCollectController {
cnd.and(seg);
}
cnd.and("info.stateId", "in", List.of(3, 2));
applyListSort(cnd, pageForm);
sql.setCondition(cnd);
Pagination<NutMap> pagination = unionReimburseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
@@ -185,29 +183,26 @@ public class UnionReimburseCollectController {
@Ok("void")
@SaCheckPermission(value = {"unionReimburse.collect", "h5.unionReimburse.collect"}, mode = SaMode.OR)
@ApiOperation("导出报销汇总表")
public void onExport(@Param(value = "year") Integer year,
public void onExport(PageForm pageForm,
@Param(value = "year") Integer year,
@Param(value = "unionId") String unionId,
@Param(value = "unitId") String unitId,
@Param(value = "reimburseProject") String reimburseProject,
@Param(value = "userName") String userName,
@Param(value = "searchKeyword") String searchKeyword,
HttpServletResponse response) {
//查询审核通过的数据
// 导出复用收集列表筛选口径,保证下载结果与页面当前查询条件一致。
Sql sql = Sqls.create("""
SELECT
t1.*,
ins.state instanceState
info.*
FROM
union_reimburse t1
LEFT JOIN `wf_process_instance` ins ON ins.businessNo = t1.id
union_reimburse info
$condition
""");
Cnd cnd = buildCondition(year, unionId, unitId, reimburseProject, userName, "t1.");
// 只查询流程实例状态为20的数据(已完成状态)
cnd.and("ins.state", "=", 20);
Cnd cnd = buildCondition(year, unionId, unitId, reimburseProject, searchKeyword, "info.");
if (!isAdmin()) {
cnd.andEX("t1.unionId", "=", SecurityUtil.getUnionId());
cnd.andEX("info.unionId", "=", SecurityUtil.getUnionId());
}
cnd.desc("t1.createTime");
applyListSort(cnd, pageForm);
sql.setCondition(cnd);
List<UnionReimburseCollectExcelVO> list = unionReimburseService.listVO(sql,UnionReimburseCollectExcelVO.class);
@@ -242,11 +237,13 @@ public class UnionReimburseCollectController {
item.setCreateTime(DateUtil.format(DateUtil.parse(item.getCreateTime()), "yyyy-MM-dd HH:mm:ss"));
}
// 拼接备注字段(仿照系统代码逻辑,使用activityName和condolenceName字段)
item.setStateName(formatStateName(item.getStateId()));
// 备注字段与页面表格保持一致:慰问显示被慰问人,其他项目显示活动名称。
if (cn.hutool.core.util.StrUtil.isNotBlank(item.getActivityName())) {
item.setRemark("活动名称:" + item.getActivityName());
} else if (cn.hutool.core.util.StrUtil.isNotBlank(item.getCondolenceName())) {
item.setRemark("慰问对象:" + item.getCondolenceName());
} else if (cn.hutool.core.util.StrUtil.isNotBlank(item.getCondolenceUserName())) {
item.setRemark("慰问:" + item.getCondolenceUserName());
}
});
@@ -263,12 +260,12 @@ public class UnionReimburseCollectController {
* @param unionId 工会ID
* @param unitId 单位ID
* @param reimburseProject 报销项目
* @param userName 经办人姓名
* @param searchKeyword 经办人姓名或工号
* @param prefix 表前缀
* @return 查询条件
*/
private Cnd buildCondition(Integer year, String unionId, String unitId,
String reimburseProject, String userName, String prefix) {
String reimburseProject, String searchKeyword, String prefix) {
Cnd cnd = Cnd.NEW();
// 年度查询条件
@@ -281,9 +278,12 @@ public class UnionReimburseCollectController {
// 报销项目查询条件
cnd.andEX(prefix + "reimburseProject", "=", reimburseProject);
// 经办人姓名查询条件
if (StrUtil.isNotBlank(userName)) {
cnd.and(prefix + "userName", "like", "%" + userName + "%");
// 经办人姓名或工号查询条件
if (StrUtil.isNotBlank(searchKeyword)) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike(prefix + "userName", searchKeyword);
seg.orLike(prefix + "loginName", searchKeyword);
cnd.and(seg);
}
return cnd;
@@ -318,4 +318,18 @@ public class UnionReimburseCollectController {
default -> null;
};
}
private String formatStateName(Integer stateId) {
if (stateId == null) {
return "";
}
return switch (stateId) {
case 1 -> "待提交";
case 2 -> "待审核确认";
case 3 -> "报销成功";
case 4 -> "拒绝";
case 5 -> "退回";
default -> String.valueOf(stateId);
};
}
}
@@ -175,6 +175,11 @@ public class UnionReimburse extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 100)
private String bankOfDeposit;
@Column
@Comment("支付明细")
@ColDefine(type = ColType.MYSQL_JSON)
private List<JSONObject> paymentDetails;
/**
* 慰问
*/
@@ -369,13 +369,15 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl<UnionReimburse> i
if (Integer.valueOf(3).equals(dbRecord.getStateId())) {
return Result.success();
}
Result validateResult = validateFundSourceBeforeSubmit(dbRecord);
if (validateResult != null) {
return validateResult;
}
Result deductResult = deductBudgetAndSaveUseDetail(dbRecord);
if (deductResult != null && deductResult.getCode() != 0) {
return deductResult;
if (!skipBudgetDeduct(dbRecord)) {
Result validateResult = validateFundSourceBeforeSubmit(dbRecord);
if (validateResult != null) {
return validateResult;
}
Result deductResult = deductBudgetAndSaveUseDetail(dbRecord);
if (deductResult != null && deductResult.getCode() != 0) {
return deductResult;
}
}
}
dbRecord.setReviewTime(new Date());
@@ -422,7 +424,7 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl<UnionReimburse> i
if (dbRecord == null) {
return Result.error("未找到对应的报销记录");
}
if (Integer.valueOf(3).equals(dbRecord.getStateId())) {
if (Integer.valueOf(3).equals(dbRecord.getStateId()) && !skipBudgetDeduct(dbRecord)) {
OutlayUseDetail oldDetail = dao().fetch(OutlayUseDetail.class, Cnd.where("outlayReimburseId", "=", dbRecord.getId()));
BigDecimal oldMoney = oldDetail != null && oldDetail.getAdjustMoney() != null
? oldDetail.getAdjustMoney()
@@ -652,6 +654,16 @@ public class UnionReimburseServiceImpl extends BaseServiceImpl<UnionReimburse> i
return Result.error("不支持的经费来源");
}
/**
* 慰问和专项活动费用不占用经费预算,审核通过及后续调整实际金额时都不写预算台账。
*/
private boolean skipBudgetDeduct(UnionReimburse unionReimburse) {
return unionReimburse != null && Set.of(
"UNION_REIMBURSE_PROJECT_1",
"UNION_REIMBURSE_PROJECT_4"
).contains(unionReimburse.getReimburseProject());
}
/**
* 已通过报销单修改实际金额时,用差额同步预算主表和使用明细,避免重复全量扣减。
*/
@@ -22,23 +22,30 @@ public class UnionReimburseCollectExcelVO implements Serializable {
@Excel(name = "所属单位", width = 20)
private String unitName;
@Excel(name = "申请时间", width = 30)
private String createTime;
@Excel(name = "报销项目", width = 20)
private String reimburseProject;
@Excel(name = "备注", width = 20)
private String remark;
@Excel(name = "金额", width = 20)
@Excel(name = "申请状态", width = 20)
private String stateName;
private Double money;
@Excel(name = "申请时间", width = 30)
private String createTime;
private Integer stateId;
private String reimburseFundSource;
//活动名称
private String activityName;
//被慰问人姓名
private String condolenceUserName;
//被慰问人
private String condolenceName;
@@ -63,6 +63,11 @@ public class AidFundMemberHistory extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 20)
private String personType;
@Column
@Comment("人员属性")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String userAttribute;
@Column
@Comment("在职状态")
@ColDefine(type = ColType.VARCHAR, width = 10)
@@ -64,4 +64,9 @@ public class AidFundMemberPay extends BaseModel {
@ColDefine(type = ColType.VARCHAR, width = 10)
private String userState;
@Column
@Comment("人员属性")
@ColDefine(type = ColType.VARCHAR, width = 20)
private String userAttribute;
}
+37 -10
View File
@@ -21,7 +21,7 @@ jetty:
#结合ftp使用,或用nginx代理ftp路径
#staticPath: /Users/wizzer/temp/files
#开发模式静态资源
staticPathLocal: D:/project/zhgh_cug_v4/src/main/resources/static
staticPathLocal: E:/projects/zhgh_cug_v4/src/main/resources/static
security:
tokenName: saToken
@@ -71,7 +71,7 @@ redis:
#nodes=192.168.6.31:6377,192.168.6.31:6378,192.168.6.28:6377,192.168.6.28:6378,192.168.6.34:6377,192.168.6.34:6378
jdbc:
url: jdbc:mysql://127.0.0.1:3306/zhgh_cug_v4?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
url: jdbc:mysql://192.168.21.215:3306/zhgh_cug_v4?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
username: root
password: root
validationQuery: select 1
@@ -87,7 +87,7 @@ xsssql:
beetl:
RESOURCE:
#本地路径,开发时设置本地路径,便于调试
rootLocal: D:/project/zhgh_cug_v4/src/main/resources/views/
rootLocal: E:/projects/zhgh_cug_v4/src/main/resources/views/
root: views/
DELIMITER_STATEMENT_START: "<!--#"
DELIMITER_STATEMENT_END: "#-->"
@@ -162,16 +162,43 @@ quartz:
minio:
accessKey: minioadmin
secretKey: minioadmin
endPoint: http://127.0.0.1:9000
bucket: jshvc
endPoint: http://192.168.21.214:9000
bucket: njupt
data-center:
grant_type: password
scope: read
username:
password:
token-url:
username: 3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD
password: 3848A3C738EFBB2C2E76E0D59B419DACA16A80F3AB0354CD
token-url: https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/oauth/token
urls:
teacher:
unit:
teacher: https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/get/JZGJCSJZLB
unit: https://bd.whcp.edu.cn/sjjkfwpt/api/bd-api/get/YXSDWJBSJZLB
msg:
platform:
enabled: false
# 地大通讯平台基础地址,默认对接正式地址
base-url: https://msg.cug.edu.cn
# 授权系统名称,对应文档中的 tp_name
tp-name : nwszl.cug.edu.cn
# 便捷发送方法默认发送人工号,controller 只传接收人和内容时会读取这里
default-send-user-id: 790036
# 便捷发送方法默认发送人姓名,controller 只传接收人和内容时会读取这里
default-send-user-name: 周斐霏
# 便捷发送方法默认发送机构ID,可不填
default-send-unit-id: 421
# 便捷发送方法默认发送机构名称,可不填
default-send-unit-name: 工会
# 便捷发送方法默认签名,可不填
default-send-user-sign:
#短信中如果不包含链接和电话,可以使用公共模板ID:
default-template-id: 1978744168869937153
# 原始密钥,未提前加密时可直接填这里,程序会按 Base64 后 SHA 自动计算 secret_key
raw-secret-key: Z21kbDlwYWJ4c2Vtbnk4NjlxeQ==
# 如果对方已经提供了可直接使用的 secret_key,也可以直接配置该值,优先级高于 raw-secret-key
encrypted-secret-key:
# HTTP连接超时时间,单位毫秒
connect-timeout: 5000
# HTTP读取超时时间,单位毫秒
read-timeout: 10000
@@ -1,8 +0,0 @@
ALTER TABLE `asset`
MODIFY COLUMN `assetUnitPrice` DECIMAL(18, 2) NULL COMMENT '单价';
ALTER TABLE `asset_depreciation_record`
MODIFY COLUMN `assetAllMoney` DECIMAL(18, 2) NULL COMMENT '资产全部的价值',
MODIFY COLUMN `assetSurplusMoney` DECIMAL(18, 2) NULL COMMENT '剩余价值',
MODIFY COLUMN `assetDepreciationMoney` DECIMAL(18, 2) NULL COMMENT '累计折旧多少钱',
MODIFY COLUMN `assetAverageMonthMoney` DECIMAL(18, 2) NULL COMMENT '平均一个月多少钱';
@@ -1,3 +0,0 @@
ALTER TABLE `build_home_little_house`
ADD COLUMN `mapX` DECIMAL(8,4) NULL COMMENT '地图X坐标百分比' AFTER `mediaFiles`,
ADD COLUMN `mapY` DECIMAL(8,4) NULL COMMENT '地图Y坐标百分比' AFTER `mapX`;
@@ -1,3 +0,0 @@
ALTER TABLE `build_home_little_house`
ADD COLUMN `unitId` VARCHAR(32) NULL COMMENT '单位ID' AFTER `unitName`,
ADD COLUMN `mediaFiles` JSON NULL COMMENT '图片视频资料' AFTER `openTime`;
@@ -1,2 +0,0 @@
ALTER TABLE `honor`
ADD COLUMN `photoFiles` JSON NULL COMMENT '荣誉照片' AFTER `files`;
@@ -1,72 +0,0 @@
CREATE TABLE IF NOT EXISTS learning_course_outline (
id VARCHAR(32) NOT NULL COMMENT 'ID',
courseId VARCHAR(32) NULL COMMENT '所属课程ID',
courseName VARCHAR(100) NULL COMMENT '所属课程名称',
parentId VARCHAR(32) NULL COMMENT '父节点ID',
nodeType VARCHAR(20) NULL COMMENT '节点类型',
title VARCHAR(100) NULL COMMENT '章/节标题',
subtitle VARCHAR(200) NULL COMMENT '副标题',
description LONGTEXT NULL COMMENT '简介',
sortOrder INT NULL COMMENT '排序值',
required TINYINT(1) NULL COMMENT '是否必学',
status VARCHAR(20) NULL COMMENT '状态',
createdBy VARCHAR(32) NULL COMMENT '创建人',
createdAt BIGINT NULL COMMENT '创建时间',
updatedBy VARCHAR(32) NULL COMMENT '修改人',
updatedAt BIGINT NULL COMMENT '修改时间',
delFlag TINYINT(1) NULL COMMENT '删除标记',
PRIMARY KEY (id),
INDEX idx_learning_outline_course (courseId),
INDEX idx_learning_outline_parent (parentId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习教育课程大纲';
CREATE TABLE IF NOT EXISTS learning_outline_resource (
id VARCHAR(32) NOT NULL COMMENT 'ID',
courseId VARCHAR(32) NULL COMMENT '所属课程ID',
outlineId VARCHAR(32) NULL COMMENT '所属章/节ID',
resourceTitle VARCHAR(100) NULL COMMENT '资料标题',
resourceType VARCHAR(20) NULL COMMENT '资料类型',
fileExt VARCHAR(20) NULL COMMENT '文件扩展名',
fileData LONGTEXT NULL COMMENT '附件',
durationSeconds INT NULL COMMENT '视频/音频时长',
sortOrder INT NULL COMMENT '排序值',
required TINYINT(1) NULL COMMENT '是否必学',
allowPreview TINYINT(1) NULL COMMENT '是否允许预览',
allowDownload TINYINT(1) NULL COMMENT '是否允许下载',
status VARCHAR(20) NULL COMMENT '状态',
createdBy VARCHAR(32) NULL COMMENT '创建人',
createdAt BIGINT NULL COMMENT '创建时间',
updatedBy VARCHAR(32) NULL COMMENT '修改人',
updatedAt BIGINT NULL COMMENT '修改时间',
delFlag TINYINT(1) NULL COMMENT '删除标记',
PRIMARY KEY (id),
INDEX idx_learning_resource_course (courseId),
INDEX idx_learning_resource_outline (outlineId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习教育大纲资料';
CREATE TABLE IF NOT EXISTS learning_study_rule (
id VARCHAR(32) NOT NULL COMMENT 'ID',
courseId VARCHAR(32) NULL COMMENT '所属课程ID',
targetType VARCHAR(20) NULL COMMENT '规则对象类型',
targetId VARCHAR(32) NULL COMMENT '规则对象ID',
required TINYINT(1) NULL COMMENT '是否必学',
studyMode VARCHAR(20) NULL COMMENT '学习方式',
completionRule VARCHAR(50) NULL COMMENT '完成规则',
completePercent INT NULL COMMENT '完成比例',
minStudySeconds INT NULL COMMENT '最少学习时长',
unlockRule VARCHAR(20) NULL COMMENT '解锁规则',
allowSkip TINYINT(1) NULL COMMENT '是否允许跳过',
allowDrag TINYINT(1) NULL COMMENT '是否允许拖动',
pauseCountTime TINYINT(1) NULL COMMENT '暂停是否计时',
hiddenCountTime TINYINT(1) NULL COMMENT '页面隐藏是否计时',
inactiveCountTime TINYINT(1) NULL COMMENT '长时间无操作是否计时',
status VARCHAR(20) NULL COMMENT '状态',
createdBy VARCHAR(32) NULL COMMENT '创建人',
createdAt BIGINT NULL COMMENT '创建时间',
updatedBy VARCHAR(32) NULL COMMENT '修改人',
updatedAt BIGINT NULL COMMENT '修改时间',
delFlag TINYINT(1) NULL COMMENT '删除标记',
PRIMARY KEY (id),
INDEX idx_learning_rule_target (targetType, targetId),
INDEX idx_learning_rule_course (courseId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习教育学习规则';
@@ -1,27 +0,0 @@
CREATE TABLE IF NOT EXISTS learning_course (
id VARCHAR(32) NOT NULL COMMENT 'ID',
courseName VARCHAR(100) NULL COMMENT '课程名称',
courseTypeId VARCHAR(32) NULL COMMENT '课程类型',
lecturerName VARCHAR(100) NULL COMMENT '授课讲师',
lecturerInfo VARCHAR(500) NULL COMMENT '讲师基本信息',
courseIntro LONGTEXT NULL COMMENT '课程简介',
suitablePeople VARCHAR(500) NULL COMMENT '适合人群',
learningGoal VARCHAR(500) NULL COMMENT '学习目标',
coursePeriod VARCHAR(50) NULL COMMENT '课程周期',
openType VARCHAR(20) NULL COMMENT '开课类型',
startTime DATETIME NULL COMMENT '开始时间',
endTime DATETIME NULL COMMENT '结束时间',
status VARCHAR(20) NULL COMMENT '课程状态',
recommendFlags VARCHAR(500) NULL COMMENT '推荐标识',
courseTags VARCHAR(500) NULL COMMENT '课程标签',
targetType VARCHAR(20) NULL COMMENT '学习对象',
targetOrgText VARCHAR(500) NULL COMMENT '指定组织',
sortNum INT NULL COMMENT '排序编码',
cover VARCHAR(500) NULL COMMENT '课程封面',
createdBy VARCHAR(32) NULL COMMENT '创建人',
createdAt BIGINT NULL COMMENT '创建时间',
updatedBy VARCHAR(32) NULL COMMENT '修改人',
updatedAt BIGINT NULL COMMENT '修改时间',
delFlag TINYINT(1) NULL COMMENT '删除标记',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习教育课程';
@@ -1,2 +0,0 @@
ALTER TABLE learning_course_type
ADD COLUMN remark VARCHAR(500) NULL COMMENT '备注';
@@ -1,2 +0,0 @@
ALTER TABLE learning_study_record
ADD COLUMN lastPositionSeconds INT NULL COMMENT '最近播放位置(秒)' AFTER studySeconds;
@@ -1,52 +0,0 @@
CREATE TABLE IF NOT EXISTS learning_study_record (
id VARCHAR(32) NOT NULL COMMENT 'ID',
userId VARCHAR(32) NULL COMMENT '学习人ID',
loginName VARCHAR(120) NULL COMMENT '工号',
userName VARCHAR(100) NULL COMMENT '姓名',
unionId VARCHAR(32) NULL COMMENT '所属分工会ID',
unionName VARCHAR(100) NULL COMMENT '所属分工会',
courseId VARCHAR(32) NULL COMMENT '课程ID',
courseName VARCHAR(100) NULL COMMENT '课程名称',
outlineId VARCHAR(32) NULL COMMENT '章节ID',
outlineName VARCHAR(100) NULL COMMENT '章节名称',
firstStudyTime DATETIME NULL COMMENT '第一次进入时间',
latestStudyTime DATETIME NULL COMMENT '最近学习时间',
studySeconds INT NULL COMMENT '累计有效学习时长(秒)',
lastPositionSeconds INT NULL COMMENT '最近播放位置(秒)',
requiredSeconds INT NULL COMMENT '要求学习时长(秒)',
progressPercent INT NULL COMMENT '学习进度',
completeStatus VARCHAR(20) NULL COMMENT '完成状态',
completedAt DATETIME NULL COMMENT '完成时间',
createdBy VARCHAR(32) NULL COMMENT '创建人',
createdAt BIGINT NULL COMMENT '创建时间',
updatedBy VARCHAR(32) NULL COMMENT '修改人',
updatedAt BIGINT NULL COMMENT '修改时间',
delFlag TINYINT(1) NULL COMMENT '删除标记',
PRIMARY KEY (id),
UNIQUE KEY idx_learning_record_user_course_outline (userId, courseId, outlineId),
INDEX idx_learning_record_union (unionId),
INDEX idx_learning_record_course (courseId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习教育学习记录';
CREATE TABLE IF NOT EXISTS learning_study_segment (
id VARCHAR(32) NOT NULL COMMENT 'ID',
recordId VARCHAR(32) NULL COMMENT '学习记录ID',
userId VARCHAR(32) NULL COMMENT '学习人ID',
courseId VARCHAR(32) NULL COMMENT '课程ID',
outlineId VARCHAR(32) NULL COMMENT '章节ID',
resourceId VARCHAR(32) NULL COMMENT '资源ID',
resourceName VARCHAR(100) NULL COMMENT '资源名称',
startTime DATETIME NULL COMMENT '开始时间',
endTime DATETIME NULL COMMENT '结束时间',
lastHeartbeatTime DATETIME NULL COMMENT '最近心跳时间',
activeSeconds INT NULL COMMENT '本时段有效学习时长(秒)',
state VARCHAR(20) NULL COMMENT '状态',
createdBy VARCHAR(32) NULL COMMENT '创建人',
createdAt BIGINT NULL COMMENT '创建时间',
updatedBy VARCHAR(32) NULL COMMENT '修改人',
updatedAt BIGINT NULL COMMENT '修改时间',
delFlag TINYINT(1) NULL COMMENT '删除标记',
PRIMARY KEY (id),
INDEX idx_learning_segment_record (recordId),
INDEX idx_learning_segment_user_state (userId, state)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学习教育学习时段';
@@ -1,50 +0,0 @@
/* cms_menu_01 */
update sys_menu set location=10 where path='0001'
/* cms_menu_02 */
update sys_menu set location=8 where path='0002'
/* cms_menu_03 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('02e86a61e99746bea34236ea73dd52a5','','0003','CMS','CMS','menu','','','ti-world','1','0','cms',NULL,'9','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468895671','0')
/* cms_menu_04 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('077cb6be4c7c41cc8955ee045a4f0286','68cdbf694f71445c8587a20234d6fe31','0003000300020001','添加链接','Add','data','','','','0','0','cms.link.link.add',NULL,'47','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897043','0')
/* cms_menu_05 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('17500ef3a9e44b4fabb240162a164fcb','6075fc0cf0ef441b9d93cc3cab3445bf','0003000200020003','删除文章','Delete','data','','','','0','0','cms.content.article.delete',NULL,'40','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896170','0')
/* cms_menu_06 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('31ed2243077c44448cce26abfd5ae574','9822bafbe3454dfd8e8b974ebc304d03','0003000300010002','修改分类','Edit','data','','','','0','0','cms.link.class.edit',NULL,'44','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896957','0')
/* cms_menu_07 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('33aed9298643424783116e0cf0f7fcbe','6075fc0cf0ef441b9d93cc3cab3445bf','0003000200020001','添加文章','Add','data','','','','0','0','cms.content.article.add',NULL,'38','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896151','0')
/* cms_menu_08 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('36e0faf5062b4f6b95d4167cbb1f8fea','68cdbf694f71445c8587a20234d6fe31','0003000300020002','修改链接','Edit','data','','','','0','0','cms.link.link.edit',NULL,'48','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897051','0')
/* cms_menu_09 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('3c24111091ad4a70ad2d9cc361311d2f','68cdbf694f71445c8587a20234d6fe31','0003000300020003','删除链接','Delete','data','','','','0','0','cms.link.link.delete',NULL,'49','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897060','0')
/* cms_menu_10 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('3f330d729ca34dc9825c46122be1bfae','02e86a61e99746bea34236ea73dd52a5','00030003','广告链接','AD','menu','','','ti-link','1','0','cms.link',NULL,'41','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468896230','0')
/* cms_menu_11 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('4781372b00bb4d52b429b58e72b80c68','b2631bbdbf824cc4b74d819c87962c0d','0003000200010001','添加栏目','Add','data','','','','0','0','cms.content.channel.add',NULL,'33','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896049','0')
/* cms_menu_12 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('50ba60ee650e4c739e6abc3ab71e4960','b2631bbdbf824cc4b74d819c87962c0d','0003000200010004','栏目排序','Sort','data','','','','0','0','cms.content.channel.sort',NULL,'36','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896092','0')
/* cms_menu_13 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('6075fc0cf0ef441b9d93cc3cab3445bf','6b6de8c720c645a1808e1c3e9ccbfc90','000300020002','文章管理','Article','menu','/platform/cms/article','data-pjax','','1','0','cms.content.article',NULL,'37','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896141','0')
/* cms_menu_14 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('68cdbf694f71445c8587a20234d6fe31','3f330d729ca34dc9825c46122be1bfae','000300030002','链接管理','Link','menu','/platform/cms/link/link','data-pjax','','1','0','cms.link.link',NULL,'46','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468897031','0')
/* cms_menu_15 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('6b6de8c720c645a1808e1c3e9ccbfc90','02e86a61e99746bea34236ea73dd52a5','00030002','内容管理','Content','menu','','','ti-pencil-alt','1','0','cms.content',NULL,'31','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468895990','0')
/* cms_menu_16 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('7125a72beee34b21ab3df9bf01b7bce6','9822bafbe3454dfd8e8b974ebc304d03','0003000300010003','删除分类','Delete','data','','','','0','0','cms.link.class.delete',NULL,'45','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896968','0')
/* cms_menu_17 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('73a29d3f99224426b5a87c92da122275','d1e991ad38a8424daf9f7eb000ee27f4','0003000100010001','保存配置','Save','data','','','','0','0','cms.site.settings.save',NULL,'30','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468895899','0')
/* cms_menu_18 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('7db6207d0dab4d6e95a7eee4f2efe875','9822bafbe3454dfd8e8b974ebc304d03','0003000300010001','添加分类','Add','data','','','','0','0','cms.link.class.add',NULL,'43','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896947','0')
/* cms_menu_19 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('9822bafbe3454dfd8e8b974ebc304d03','3f330d729ca34dc9825c46122be1bfae','000300030001','链接分类','Class','menu','/platform/cms/link/class','data-pjax','','1','0','cms.link.class',NULL,'42','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896932','0')
/* cms_menu_20 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('b2631bbdbf824cc4b74d819c87962c0d','6b6de8c720c645a1808e1c3e9ccbfc90','000300020001','栏目管理','Channel','menu','/platform/cms/channel','data-pjax','','1','0','cms.content.channel',NULL,'32','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896018','0')
/* cms_menu_21 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('d1e991ad38a8424daf9f7eb000ee27f4','d920314e925c451da6d881e7a29743b7','000300010001','网站配置','Settings','menu','/platform/cms/site','data-pjax','','1','0','cms.site.settings',NULL,'29','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468895881','0')
/* cms_menu_22 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('d920314e925c451da6d881e7a29743b7','02e86a61e99746bea34236ea73dd52a5','00030001','站点管理','Site','menu','','','ti-world','1','0','cms.site',NULL,'28','1','1a19ef09b12344b4a797d6e6dfe7fb29','1468895821','0')
/* cms_menu_23 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('e461c62a1d5441619cd35612f3b40691','b2631bbdbf824cc4b74d819c87962c0d','0003000200010002','修改栏目','Edit','data','','','','0','0','cms.content.channel.edit',NULL,'34','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896060','0')
/* cms_menu_24 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('ef9f436c61654ec09efbfa79a40061cf','6075fc0cf0ef441b9d93cc3cab3445bf','0003000200020002','修改文章','Edit','data','','','','0','0','cms.content.article.edit',NULL,'39','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896159','0')
/* cms_menu_25 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('f6fba69c3b704d79834b8bd2cc753729','b2631bbdbf824cc4b74d819c87962c0d','0003000200010003','删除栏目','Delete','data','','','','0','0','cms.content.channel.delete',NULL,'35','0','1a19ef09b12344b4a797d6e6dfe7fb29','1468896072','0')
@@ -1,103 +0,0 @@
/* wx_menu_01 */
update sys_menu set location=10 where path='0001'
/* wx_menu_02 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('b0edc6861a494b79b97990dc05f0a524','','0002','微信','Wechat','menu','','','fa fa-weixin','1','0','wx',NULL,'8','1','','1467471229','0')
/* wx_menu_03 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('e4256d7b0ffc4a02906cf900322b6213','b0edc6861a494b79b97990dc05f0a524','00020001','微信会员','Member','menu','','','fa fa-user','1','0','wx.user',NULL,'1','1','','1467471292','0')
/* wx_menu_04 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('b19b23b0459a4754bf1fb8cb234450f2','e4256d7b0ffc4a02906cf900322b6213','000200010001','会员列表','List','menu','/platform/wx/user/index','data-pjax','','1','0','wx.user.list',NULL,'2','0','','1467471357','0')
/* wx_menu_05 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('4dc997fef71e4862b9db22de8e99a618','b19b23b0459a4754bf1fb8cb234450f2','0002000100010001','同步会员信息','Sync','data','','','','0','0','wx.user.list.sync',NULL,'0','0','','1467473044','0')
/* wx_menu_06 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('9f20a757a6bc40ddbb650c70debbf660','b0edc6861a494b79b97990dc05f0a524','00020002','消息管理','Message','menu','','','ti-pencil-alt','1','0','wx.msg',NULL,'3','1','','1467471415','0')
/* wx_menu_07 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('f426468abf714b1599729f8c36ebbb0d','9f20a757a6bc40ddbb650c70debbf660','000200020001','会员消息','Msg','menu','/platform/wx/msg/user','data-pjax','','1','0','wx.msg.user',NULL,'4','1','','1467471478','0')
/* wx_menu_08 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('1734e586e96941268a4c5248b593cef9','f426468abf714b1599729f8c36ebbb0d','0002000200010001','回复消息','Reply','data','','','','0','0','wx.msg.user.reply',NULL,'0','0','','1467473127','0')
/* wx_menu_09 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('6bb17a41f6394ed0a8a6faf5ff781354','9f20a757a6bc40ddbb650c70debbf660','000200020002','群发消息','Mass','menu','/platform/wx/msg/mass','data-pjax','','1','0','wx.msg.mass',NULL,'5','0','','1467471561','0')
/* wx_menu_10 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('56d0658c5a8848818ac05e8ffa5c0570','6bb17a41f6394ed0a8a6faf5ff781354','0002000200020001','添加图文','Add','data','','','','0','0','wx.msg.mass.addNews',NULL,'0','0','','1467473338','0')
/* wx_menu_11 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('ce709456e867425297955b3c40406d7e','6bb17a41f6394ed0a8a6faf5ff781354','0002000200020002','删除图文','Delete','data','','','','0','0','wx.msg.mass.delNews',NULL,'0','0','','1467473363','0')
/* wx_menu_12 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('3099f497480c4b1987bce3f3a26c3fb4','6bb17a41f6394ed0a8a6faf5ff781354','0002000200020003','群发消息','Push','data','','','','0','0','wx.msg.mass.pushNews',NULL,'0','0','','1467473400','0')
/* wx_menu_13 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('4cd8e4e9519e4cff95465194fdcc8d88','b0edc6861a494b79b97990dc05f0a524','00020003','自动回复','AutoReply','menu','','','ti-back-left','1','0','wx.reply',NULL,'6','1','','1467471610','0')
/* wx_menu_14 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('234f8ec3c2bc42bf9f6202aecae36fd6','4cd8e4e9519e4cff95465194fdcc8d88','000200030001','文本内容','Txt','menu','/platform/wx/reply/txt','data-pjax','','1','0','wx.reply.txt',NULL,'7','0','','1467471884','0')
/* wx_menu_15 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('c3a44b478d3241b899b9c3f4611bc2b6','234f8ec3c2bc42bf9f6202aecae36fd6','0002000300010001','添加文本','Add','data','','','','0','0','wx.reply.txt.add',NULL,'0','0','','1467473460','0')
/* wx_menu_16 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('fd63a8e389e04ff3a86c3cea53a3b9d5','234f8ec3c2bc42bf9f6202aecae36fd6','0002000300010002','修改文本','Edit','data','','','','0','0','wx.reply.txt.edit',NULL,'0','0','','1467473519','0')
/* wx_menu_17 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('7c040dfd8db347e5956a3bc1764653dc','234f8ec3c2bc42bf9f6202aecae36fd6','0002000300010003','删除文本','Delete','data','','','','0','0','wx.reply.txt.delete',NULL,'0','0','','1467473540','0')
/* wx_menu_18 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('234f8ec3c2bc42bf9f6202aecae36f99','4cd8e4e9519e4cff95465194fdcc8d88','000200030005','图片内容','Img','menu','/platform/wx/reply/img','data-pjax','','1','0','wx.reply.img',NULL,'8','0','','1467471884','0')
/* wx_menu_19 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('c3a44b478d3241b899b9c3f4611bc216','234f8ec3c2bc42bf9f6202aecae36f99','0002000300050001','添加图片','Add','data','','','','0','0','wx.reply.img.add',NULL,'0','0','','1467473460','0')
/* wx_menu_20 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('fd63a8e389e04ff3a86c3cea53a3b925','234f8ec3c2bc42bf9f6202aecae36f99','0002000300050002','修改图片','Edit','data','','','','0','0','wx.reply.img.edit',NULL,'0','0','','1467473519','0')
/* wx_menu_21 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('7c040dfd8db347e5956a3bc17646533c','234f8ec3c2bc42bf9f6202aecae36f99','0002000300050003','删除图片','Delete','data','','','','0','0','wx.reply.img.delete',NULL,'0','0','','1467473540','0')
/* wx_menu_22 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('17e1ee23ca1443f1bc886c2f5eb7c24b','4cd8e4e9519e4cff95465194fdcc8d88','000200030002','图文内容','News','menu','/platform/wx/reply/news','data-pjax','','1','0','wx.reply.news',NULL,'9','0','','1467471926','0')
/* wx_menu_23 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('2275cb125710414e91b617dd7c62f12c','17e1ee23ca1443f1bc886c2f5eb7c24b','0002000300020001','添加图文','add','data','','','','0','0','wx.reply.news.add',NULL,'0','0','','1467473585','0')
/* wx_menu_24 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('0a972ce655cb4c84809d58668b655900','17e1ee23ca1443f1bc886c2f5eb7c24b','0002000300020002','修改图文','Edit','data','','','','0','0','wx.reply.news.edit',NULL,'0','0','','1467473596','0')
/* wx_menu_25 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('fc52d5284b8f4522802383c1ef732242','17e1ee23ca1443f1bc886c2f5eb7c24b','0002000300020003','删除图文','Delete','data','','','','0','0','wx.reply.news.delete',NULL,'0','0','','1467473606','0')
/* wx_menu_26 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('2cb327ad59b140828fd26eb2a46cb948','4cd8e4e9519e4cff95465194fdcc8d88','000200030003','关注自动回复','Follow','menu','/platform/wx/reply/conf/follow','data-pjax','','1','0','wx.reply.follow',NULL,'10','0','','1467472280','0')
/* wx_menu_27 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('dd965b2c1dfd493fb5efc7e4bcac99d4','2cb327ad59b140828fd26eb2a46cb948','0002000300030001','添加绑定','Add','data','','','','0','0','wx.reply.follow.add',NULL,'0','0','','1467474026','0')
/* wx_menu_28 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('30a5e70a1456447ebf90b5546e9bc321','2cb327ad59b140828fd26eb2a46cb948','0002000300030002','修改绑定','Edit','data','','','','0','0','wx.reply.follow.edit',NULL,'0','0','','1467474056','0')
/* wx_menu_29 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('2a63040409094f1e9dc535dd78ce15b7','2cb327ad59b140828fd26eb2a46cb948','0002000300030003','删除绑定','Delete','data','','','','0','0','wx.reply.follow.delete',NULL,'0','0','','1467474080','0')
/* wx_menu_30 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('0706112ff5dc46e388064a99bcdb0561','4cd8e4e9519e4cff95465194fdcc8d88','000200030004','关键词回复','Keyword','menu','/platform/wx/reply/conf/keyword','data-pjax','','1','0','wx.reply.keyword',NULL,'11','0','','1467472362','0')
/* wx_menu_31 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('e864c78aba63448892cbcb6a3a7f4da7','0706112ff5dc46e388064a99bcdb0561','0002000300040001','添加绑定','Add','data','','','','0','0','wx.reply.keyword.add',NULL,'0','0','','1467474113','0')
/* wx_menu_32 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('ff6cd243a77c4ae98dacf6149c816c75','0706112ff5dc46e388064a99bcdb0561','0002000300040002','修改绑定','Edit','data','','','','0','0','wx.reply.keyword.edit',NULL,'0','0','','1467474125','0')
/* wx_menu_33 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('733d3f35d49f45af99ca9220048583ba','0706112ff5dc46e388064a99bcdb0561','0002000300040003','删除绑定','Delete','data','','','','0','0','wx.reply.keyword.delete',NULL,'0','0','','1467474136','0')
/* wx_menu_34 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('bcf64d623fdd4519ae345b7a08c071a1','b0edc6861a494b79b97990dc05f0a524','00020004','微信配置','Config','menu','','','fa fa-weixin','1','0','wx.conf',NULL,'12','1','','1467472498','0')
/* wx_menu_35 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('66cc21d7ce104dd6877cbce114c59fb3','bcf64d623fdd4519ae345b7a08c071a1','000200040001','帐号配置','Account','menu','/platform/wx/conf/account','data-pjax','','1','0','wx.conf.account',NULL,'13','0','','1467472624','0')
/* wx_menu_36 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('309dc29ad3c34408a68df8f867a5c9ff','66cc21d7ce104dd6877cbce114c59fb3','0002000400010001','添加帐号','Add','data','','','','0','0','wx.conf.account.add',NULL,'0','0','','1467474187','0')
/* wx_menu_37 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('96554b09a2dd4f82bab7546fa59acd35','66cc21d7ce104dd6877cbce114c59fb3','0002000400010002','修改帐号','Edit','data','','','','0','0','wx.conf.account.edit',NULL,'0','0','','1467474197','0')
/* wx_menu_38 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('d568f4c2b687404e8aec7b9edcae5767','66cc21d7ce104dd6877cbce114c59fb3','0002000400010003','删除帐号','Delete','data','','','','0','0','wx.conf.account.delete',NULL,'0','0','','1467474209','0')
/* wx_menu_39 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('2fab774f8b6d40cb9d7e187babab2d91','bcf64d623fdd4519ae345b7a08c071a1','000200040002','菜单配置','Menu','menu','/platform/wx/conf/menu','data-pjax','','1','0','wx.conf.menu',NULL,'14','0','','1467472649','0')
/* wx_menu_40 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('45d958ca78304f25b51f6c71cf66f6d8','2fab774f8b6d40cb9d7e187babab2d91','0002000400020001','添加菜单','Add','data','','','','0','0','wx.conf.menu.add',NULL,'0','0','','1467474283','0')
/* wx_menu_41 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('44da90bc76a5419a841f4924333f7a66','2fab774f8b6d40cb9d7e187babab2d91','0002000400020002','修改菜单','Edit','data','','','','0','0','wx.conf.menu.edit',NULL,'0','0','','1467474294','0')
/* wx_menu_42 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('9a9557177d334c209cf73c3817fe3b63','2fab774f8b6d40cb9d7e187babab2d91','0002000400020003','删除菜单','Delete','data','','','','0','0','wx.conf.menu.delete',NULL,'0','0','','1467474304','0')
/* wx_menu_43 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('0a43d291e0c94ad88c8b690009279e34','2fab774f8b6d40cb9d7e187babab2d91','0002000400020004','保存排序','Save','data','','','','0','0','wx.conf.menu.sort',NULL,'0','0','','1467474314','0')
/* wx_menu_44 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('5244f5c38eb24b918e9ad64d456daa38','2fab774f8b6d40cb9d7e187babab2d91','0002000400020005','推送到微信','Push','data','','','','0','0','wx.conf.menu.push',NULL,'0','0','','1467474330','0')
/* wx_menu_45 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('6afc5075913d4df4b44a6476080e35a0','b0edc6861a494b79b97990dc05f0a524','00020005','模板消息','Template','menu','','','ti-notepad','1','0','wx.tpl',NULL,'50','1','','1470406797','0')
/* wx_menu_46 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('1385ae887e5c4b8aa33fbf228be7f907','6afc5075913d4df4b44a6476080e35a0','000200050001','模板编号','Id','menu','/platform/wx/tpl/id','data-pjax','','1','0','wx.tpl.id',NULL,'51','0','','1470406854','0')
/* wx_menu_47 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('e6b6224617b04090a76e46a4b048fb96','1385ae887e5c4b8aa33fbf228be7f907','0002000500010001','添加编号','Add','data','','','','0','0','wx.tpl.id.add',NULL,'54','0','','1470407055','0')
/* wx_menu_48 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('3888f05aa4064f788ba7ec51c495ce7c','1385ae887e5c4b8aa33fbf228be7f907','0002000500010002','删除编号','Delete','data','','','','0','0','wx.tpl.id.delete',NULL,'55','0','','1470407068','0')
/* wx_menu_49 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('cabbe834a7474675b899e8442b5c2604','6afc5075913d4df4b44a6476080e35a0','000200050002','模板列表','List','menu','/platform/wx/tpl/list','data-pjax','','1','0','wx.tpl.list',NULL,'52','0','','1470406883','0')
/* wx_menu_50 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('a11163584dfe456cbfd6fb2d4b74391b','cabbe834a7474675b899e8442b5c2604','0002000500020001','获取列表','Get','data','','','','0','0','wx.tpl.list.get',NULL,'56','0','','1470407390','0')
/* wx_menu_51 */
insert into sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, delFlag) values('c76a84f871d047db955dd1465c845ac1','6afc5075913d4df4b44a6476080e35a0','000200050003','发送记录','Log','menu','/platform/wx/tpl/log','data-pjax','','1','0','wx.tpl.log',NULL,'53','0','','1470406926','0')
@@ -1,91 +0,0 @@
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT
'a0f47f6a6d734c8b9c6ce5c0dfd80001',
'',
LPAD(IFNULL(MAX(CAST(path AS UNSIGNED)), 0) + 1, 4, '0'),
'学习教育平台',
'Learning',
'menu',
'',
'',
'ti-book',
1,
0,
'learning',
NULL,
990,
1,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
'PC',
NULL,
NULL,
'x',
0,
0
FROM sys_menu
WHERE (parentId = '' OR parentId IS NULL)
AND CHAR_LENGTH(path) = 4
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'a0f47f6a6d734c8b9c6ce5c0dfd80002', p.id, CONCAT(p.path, '0001'), '课程类型设置', 'Course Type', 'menu', '/platform/learning/course/type', 'data-pjax', '', 1, 0, 'learning.course.type', NULL, 1, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'k', 0, 0
FROM sys_menu p
WHERE p.permission = 'learning'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning.course.type') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'a0f47f6a6d734c8b9c6ce5c0dfd80003', p.id, CONCAT(p.path, '0002'), '课程管理', 'Course Manage', 'menu', '/platform/learning/course/manage', 'data-pjax', '', 1, 0, 'learning.course.manage', NULL, 2, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'k', 0, 0
FROM sys_menu p
WHERE p.permission = 'learning'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning.course.manage') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'a0f47f6a6d734c8b9c6ce5c0dfd80004', p.id, CONCAT(p.path, '0003'), '章节内容管理', 'Chapter Content', 'menu', '/platform/learning/chapter/content', 'data-pjax', '', 1, 0, 'learning.chapter.content', NULL, 3, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'z', 0, 0
FROM sys_menu p
WHERE p.permission = 'learning'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning.chapter.content') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'a0f47f6a6d734c8b9c6ce5c0dfd80005', p.id, CONCAT(p.path, '0004'), '课程展示', 'Course Display', 'menu', '/platform/learning/course/display', 'data-pjax', '', 1, 0, 'learning.course.display', NULL, 4, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'k', 0, 0
FROM sys_menu p
WHERE p.permission = 'learning'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning.course.display') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'a0f47f6a6d734c8b9c6ce5c0dfd80006', p.id, CONCAT(p.path, '0005'), '学习活动管理', 'Activity Manage', 'menu', '/platform/learning/activity/manage', 'data-pjax', '', 1, 0, 'learning.activity.manage', NULL, 5, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'learning'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning.activity.manage') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'a0f47f6a6d734c8b9c6ce5c0dfd80007', p.id, CONCAT(p.path, '0006'), '学习统计', 'Learning Statistics', 'menu', '/platform/learning/statistics', 'data-pjax', '', 1, 0, 'learning.statistics', NULL, 6, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'learning'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning.statistics') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'a0f47f6a6d734c8b9c6ce5c0dfd80008', p.id, CONCAT(p.path, '0007'), '我的学习记录', 'My Learning Record', 'menu', '/platform/learning/my/record', 'data-pjax', '', 1, 0, 'learning.my.record', NULL, 7, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'w', 0, 0
FROM sys_menu p
WHERE p.permission = 'learning'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'learning.my.record') t);
INSERT INTO sys_role_menu (roleId, menuId)
SELECT r.id, m.id
FROM sys_role r
JOIN sys_menu m ON m.permission IN (
'learning',
'learning.course.type',
'learning.course.manage',
'learning.chapter.content',
'learning.course.display',
'learning.activity.manage',
'learning.statistics',
'learning.my.record'
)
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
WHERE r.code = 'SYSADMIN'
AND rm.roleId IS NULL;
@@ -1,160 +0,0 @@
-- 问卷服务菜单初始化
-- 使用 permission 做幂等判断,避免同一环境重复执行时插入重复菜单。
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT
'f6c0c37d2d7a4a22b5c7b1a1qsv0001',
'',
LPAD(IFNULL(MAX(CAST(path AS UNSIGNED)), 0) + 1, 4, '0'),
'日常办公',
'Day Office Work',
'menu',
'',
'',
'ti-briefcase',
1,
0,
'dayofficework',
NULL,
600,
1,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
'PC',
NULL,
NULL,
'r',
0,
0
FROM sys_menu
WHERE (parentId = '' OR parentId IS NULL)
AND CHAR_LENGTH(path) = 4
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'dayofficework') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT
'f6c0c37d2d7a4a22b5c7b1a1qsv0002',
p.id,
CONCAT(p.path, LPAD(IFNULL(MAX(CAST(SUBSTRING(c.path, CHAR_LENGTH(p.path) + 1, 4) AS UNSIGNED)), 0) + 1, 4, '0')),
'问卷服务',
'Questionnaire Service',
'menu',
'',
'',
'fa fa-list-alt',
1,
0,
'qsv',
NULL,
1,
1,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
'PC',
p.moduleId,
NULL,
'w',
0,
0
FROM sys_menu p
LEFT JOIN sys_menu c ON c.parentId = p.id AND CHAR_LENGTH(c.path) = CHAR_LENGTH(p.path) + 4
WHERE p.permission = 'dayofficework'
GROUP BY p.id, p.path, p.moduleId
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'qsv') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'f6c0c37d2d7a4a22b5c7b1a1qsv0003', p.id, CONCAT(p.path, LPAD(IFNULL(MAX(CAST(SUBSTRING(c.path, CHAR_LENGTH(p.path) + 1, 4) AS UNSIGNED)), 0) + 1, 4, '0')), '问卷管理', 'Questionnaire Manage', 'menu', '/platform/qsv/activity', 'data-pjax', '', 1, 0, 'qsv.activity', NULL, 1, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', p.moduleId, NULL, 'w', 0, 0
FROM sys_menu p
LEFT JOIN sys_menu c ON c.parentId = p.id AND CHAR_LENGTH(c.path) = CHAR_LENGTH(p.path) + 4
WHERE p.permission = 'qsv'
GROUP BY p.id, p.path, p.moduleId
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'qsv.activity') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'f6c0c37d2d7a4a22b5c7b1a1qsv0004', p.id, CONCAT(p.path, LPAD(IFNULL(MAX(CAST(SUBSTRING(c.path, CHAR_LENGTH(p.path) + 1, 4) AS UNSIGNED)), 0) + 1, 4, '0')), '题库管理', 'Question Bank', 'menu', '/platform/qsv/bank', 'data-pjax', '', 1, 0, 'qsv.bank', NULL, 2, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', p.moduleId, NULL, 't', 0, 0
FROM sys_menu p
LEFT JOIN sys_menu c ON c.parentId = p.id AND CHAR_LENGTH(c.path) = CHAR_LENGTH(p.path) + 4
WHERE p.permission = 'qsv'
GROUP BY p.id, p.path, p.moduleId
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'qsv.bank') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'f6c0c37d2d7a4a22b5c7b1a1qsv0005', p.id, CONCAT(p.path, LPAD(IFNULL(MAX(CAST(SUBSTRING(c.path, CHAR_LENGTH(p.path) + 1, 4) AS UNSIGNED)), 0) + 1, 4, '0')), '调查统计', 'Survey Statistics', 'menu', '/platform/qsv/survey', 'data-pjax', '', 1, 0, 'qsv.survey', NULL, 3, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', p.moduleId, NULL, 'd', 0, 0
FROM sys_menu p
LEFT JOIN sys_menu c ON c.parentId = p.id AND CHAR_LENGTH(c.path) = CHAR_LENGTH(p.path) + 4
WHERE p.permission = 'qsv'
GROUP BY p.id, p.path, p.moduleId
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'qsv.survey') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'f6c0c37d2d7a4a22b5c7b1a1qsv0006', p.id, CONCAT(p.path, LPAD(IFNULL(MAX(CAST(SUBSTRING(c.path, CHAR_LENGTH(p.path) + 1, 4) AS UNSIGNED)), 0) + 1, 4, '0')), '答题排行', 'Quiz Rank', 'menu', '/platform/qsv/quizRank', 'data-pjax', '', 1, 0, 'qsv.quiz.rank', NULL, 4, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', p.moduleId, NULL, 'd', 0, 0
FROM sys_menu p
LEFT JOIN sys_menu c ON c.parentId = p.id AND CHAR_LENGTH(c.path) = CHAR_LENGTH(p.path) + 4
WHERE p.permission = 'qsv'
GROUP BY p.id, p.path, p.moduleId
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'qsv.quiz.rank') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'f6c0c37d2d7a4a22b5c7b1a1qsv0007', p.id, CONCAT(p.path, LPAD(IFNULL(MAX(CAST(SUBSTRING(c.path, CHAR_LENGTH(p.path) + 1, 4) AS UNSIGNED)), 0) + 1, 4, '0')), '在线答题', 'Online Quiz', 'menu', '/platform/qsv/online', 'data-pjax', '', 1, 0, 'qsv.online', NULL, 5, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', p.moduleId, NULL, 'z', 0, 0
FROM sys_menu p
LEFT JOIN sys_menu c ON c.parentId = p.id AND CHAR_LENGTH(c.path) = CHAR_LENGTH(p.path) + 4
WHERE p.permission = 'qsv'
GROUP BY p.id, p.path, p.moduleId
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'qsv.online') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT
'f6c0c37d2d7a4a22b5c7b1a1qsv0008',
'',
LPAD(IFNULL(MAX(CAST(path AS UNSIGNED)), 0) + 1, 4, '0'),
'问卷服务',
'Questionnaire Service',
'menu',
'/platform/h5/qsv',
'data-pjax',
'',
1,
0,
'h5.qsv',
NULL,
601,
0,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
'H5',
NULL,
'/assets/mobile/svg/qsv/icon.svg',
'w',
1,
1
FROM sys_menu
WHERE (parentId = '' OR parentId IS NULL)
AND CHAR_LENGTH(path) = 4
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'h5.qsv') t);
-- 给系统管理员默认授权,其他角色可在角色管理中按需分配。
INSERT INTO sys_role_menu (roleId, menuId)
SELECT r.id, m.id
FROM sys_role r
JOIN sys_menu m ON m.permission IN (
'dayofficework',
'qsv',
'qsv.activity',
'qsv.bank',
'qsv.survey',
'qsv.quiz.rank',
'qsv.online',
'h5.qsv'
)
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
WHERE r.code = 'SYSADMIN'
AND rm.roleId IS NULL;
@@ -1,64 +0,0 @@
-- Home work template menu. Prefer a sibling of sys.homeActivity, then sys.manager, then sys.
INSERT INTO sys_menu (
id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt,
delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService
)
SELECT
'e6ed122326a8492fa7f415f97eaf4f01',
parent.id,
CONCAT(parent.path, LPAD(IFNULL(child.maxNo, 0) + 1, 4, '0')),
'Work Template',
'Work Template',
'menu',
'/platform/sys/worktemplate',
'data-pjax',
'',
1,
0,
'sys.worktemplate',
NULL,
IFNULL(child.maxLocation, 0) + 1,
0,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
'PC',
NULL,
NULL,
'g',
0,
0
FROM (
SELECT p.*
FROM sys_menu p
WHERE p.id = (SELECT h.parentId FROM sys_menu h WHERE h.permission = 'sys.homeActivity' LIMIT 1)
OR p.permission IN ('sys.manager', 'sys')
ORDER BY
CASE
WHEN p.id = (SELECT h.parentId FROM sys_menu h WHERE h.permission = 'sys.homeActivity' LIMIT 1) THEN 0
WHEN p.permission = 'sys.manager' THEN 1
ELSE 2
END
LIMIT 1
) parent
LEFT JOIN (
SELECT parentId,
MAX(CAST(RIGHT(path, 4) AS UNSIGNED)) AS maxNo,
MAX(location) AS maxLocation
FROM sys_menu
GROUP BY parentId
) child ON child.parentId = parent.id
WHERE NOT EXISTS (
SELECT 1 FROM sys_menu WHERE permission = 'sys.worktemplate'
);
INSERT INTO sys_role_menu (roleId, menuId)
SELECT r.id, m.id
FROM sys_role r
JOIN sys_menu m ON m.permission = 'sys.worktemplate'
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
WHERE r.code = 'SYSADMIN'
AND rm.roleId IS NULL;
@@ -1,122 +0,0 @@
-- 普惠疗休养平台电脑端菜单。
-- 使用 permission 做幂等判断,避免同一环境重复执行时插入重复菜单。
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT
'b7c63f0c73a44a9a8c4f3d3bb1a10001',
'',
LPAD(IFNULL(MAX(CAST(path AS UNSIGNED)), 0) + 1, 4, '0'),
'普惠疗休养',
'Tour',
'menu',
'',
'',
'ti-map-alt',
1,
0,
'tour',
NULL,
991,
1,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
'',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
'PC',
NULL,
NULL,
'p',
0,
0
FROM sys_menu
WHERE (parentId = '' OR parentId IS NULL)
AND CHAR_LENGTH(path) = 4
HAVING NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10002', p.id, CONCAT(p.path, '0001'), '疗休养设置', 'Tour Setting', 'menu', '/platform/tour/setting', 'data-pjax', '', 1, 0, 'tour.setting', NULL, 1, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.setting') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10003', p.id, CONCAT(p.path, '0002'), '旅行社管理', 'Travel Agency', 'menu', '/platform/tour/travelAgency', 'data-pjax', '', 1, 0, 'tour.travelAgency', NULL, 2, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.travelAgency') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10004', p.id, CONCAT(p.path, '0003'), '线路管理', 'Route Manage', 'menu', '/platform/tour/route', 'data-pjax', '', 1, 0, 'tour.route', NULL, 3, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.route') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10005', p.id, CONCAT(p.path, '0004'), '疗休养事项', 'Tour Matter', 'menu', '/platform/tour/matter', 'data-pjax', '', 1, 0, 'tour.matter', NULL, 4, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.matter') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10006', p.id, CONCAT(p.path, '0005'), '疗休养报名', 'Tour Signup', 'menu', '/platform/tour/signup', 'data-pjax', '', 1, 0, 'tour.signup', NULL, 5, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.signup') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10008', p.id, CONCAT(p.path, '0006'), '我的报名', 'My Signup', 'menu', '/platform/tour/mysignup', 'data-pjax', '', 1, 0, 'tour.mysignup', NULL, 6, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'w', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.mysignup') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10009', p.id, CONCAT(p.path, '0007'), '分工会查询', 'Union Ledger', 'menu', '/platform/tour/unionledger', 'data-pjax', '', 1, 0, 'tour.unionledger', NULL, 7, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'f', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.unionledger') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10011', p.id, CONCAT(p.path, '0010'), '分工会审核', 'Union Approval', 'menu', '/platform/tour/unionApproval', 'data-pjax', '', 1, 0, 'tour.unionApproval', NULL, 8, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'f', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.unionApproval') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10012', p.id, CONCAT(p.path, '0011'), '校工会审核', 'School Union Approval', 'menu', '/platform/tour/schoolUnionApproval', 'data-pjax', '', 1, 0, 'tour.schoolUnionApproval', NULL, 9, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.schoolUnionApproval') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10007', p.id, CONCAT(p.path, '0008'), '疗休养台账', 'Tour Ledger', 'menu', '/platform/tour/ledger', 'data-pjax', '', 1, 0, 'tour.ledger', NULL, 10, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'l', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.ledger') t);
INSERT INTO sys_menu (id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled, permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt, delFlag, platform, moduleId, picIcon, initialPinyinName, isRecommendApp, isRecommendService)
SELECT 'b7c63f0c73a44a9a8c4f3d3bb1a10010', p.id, CONCAT(p.path, '0009'), '线路成团', 'Tour Group', 'menu', '/platform/tour/group', 'data-pjax', '', 1, 0, 'tour.group', NULL, 11, 0, '', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0, 'PC', NULL, NULL, 'x', 0, 0
FROM sys_menu p
WHERE p.permission = 'tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM sys_menu WHERE permission = 'tour.group') t);
-- 给系统管理员默认授权,其他角色可在角色管理中按需分配。
INSERT INTO sys_role_menu (roleId, menuId)
SELECT r.id, m.id
FROM sys_role r
JOIN sys_menu m ON m.permission IN (
'tour',
'tour.setting',
'tour.travelAgency',
'tour.route',
'tour.matter',
'tour.signup',
'tour.group',
'tour.mysignup',
'tour.unionledger',
'tour.unionApproval',
'tour.schoolUnionApproval',
'tour.ledger'
)
LEFT JOIN sys_role_menu rm ON rm.roleId = r.id AND rm.menuId = m.id
WHERE r.code = 'SYSADMIN'
AND rm.roleId IS NULL;
@@ -1,49 +0,0 @@
INSERT INTO sys_menu (
id, parentId, path, name, aliasName, type, href, target, icon, showit, disabled,
permission, note, location, hasChildren, createdBy, createdAt, updatedBy, updatedAt,
delFlag, processKey, platform, moduleId, isQuickEntry, picIcon, initialPinyinName,
isRecommendApp, isRecommendService
)
SELECT
'2a46a3fd5e284b0ea508264bd7f6ab31',
'5ba858277fa44aaf958b32055468f52a',
'000100040004',
'高级工具',
NULL,
'menu',
'/platform/sys/data/tool',
'data-pjax',
NULL,
1,
0,
'sys.data.advanced.tool',
NULL,
588,
0,
'29847d7826aa415a92d03b9576d01d3f',
UNIX_TIMESTAMP(NOW()) * 1000,
'29847d7826aa415a92d03b9576d01d3f',
UNIX_TIMESTAMP(NOW()) * 1000,
0,
NULL,
'PC',
NULL,
0,
NULL,
'g',
0,
0
FROM DUAL
WHERE NOT EXISTS (
SELECT 1 FROM sys_menu WHERE permission = 'sys.data.advanced.tool'
);
INSERT INTO sys_role_menu (roleId, menuId)
SELECT
oldMap.roleId,
newMenu.id
FROM sys_role_menu oldMap
JOIN sys_menu oldMenu ON oldMenu.id = oldMap.menuId AND oldMenu.permission = 'sys.data.user.pull'
JOIN sys_menu newMenu ON newMenu.permission = 'sys.data.advanced.tool'
LEFT JOIN sys_role_menu existsMap ON existsMap.roleId = oldMap.roleId AND existsMap.menuId = newMenu.id
WHERE existsMap.roleId IS NULL;
@@ -1,3 +0,0 @@
ALTER TABLE qsv_subject
ADD COLUMN option_layout VARCHAR(20) DEFAULT 'VERTICAL' COMMENT '投票选项排列方式',
ADD COLUMN option_columns INT DEFAULT 1 COMMENT '投票选项横向列数';
-62
View File
@@ -1,62 +0,0 @@
/*QUARTZ_23*/
CREATE TABLE sys_qrtz_job_details(SCHED_NAME VARCHAR2(120) NOT NULL,JOB_NAME VARCHAR2(200) NOT NULL,JOB_GROUP VARCHAR2(200) NOT NULL,DESCRIPTION VARCHAR2(250) NULL,JOB_CLASS_NAME VARCHAR2(250) NOT NULL, IS_DURABLE VARCHAR2(1) NOT NULL,IS_NONCONCURRENT VARCHAR2(1) NOT NULL,IS_UPDATE_DATA VARCHAR2(1) NOT NULL,REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,JOB_DATA BLOB NULL,CONSTRAINT JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
/*QUARTZ_24*/
CREATE TABLE sys_qrtz_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,JOB_NAME VARCHAR2(200) NOT NULL, JOB_GROUP VARCHAR2(200) NOT NULL,DESCRIPTION VARCHAR2(250) NULL,NEXT_FIRE_TIME NUMBER(13) NULL,PREV_FIRE_TIME NUMBER(13) NULL,PRIORITY NUMBER(13) NULL,TRIGGER_STATE VARCHAR2(16) NOT NULL,TRIGGER_TYPE VARCHAR2(8) NOT NULL,START_TIME NUMBER(13) NOT NULL,END_TIME NUMBER(13) NULL,CALENDAR_NAME VARCHAR2(200) NULL,MISFIRE_INSTR NUMBER(2) NULL,JOB_DATA BLOB NULL,CONSTRAINT TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) REFERENCES sys_qrtz_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
/*QUARTZ_25*/
CREATE TABLE sys_qrtz_simple_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL, REPEAT_COUNT NUMBER(7) NOT NULL,REPEAT_INTERVAL NUMBER(12) NOT NULL,TIMES_TRIGGERED NUMBER(10) NOT NULL,CONSTRAINT SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), CONSTRAINT SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_26*/
CREATE TABLE sys_qrtz_cron_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL, CRON_EXPRESSION VARCHAR2(120) NOT NULL, TIME_ZONE_ID VARCHAR2(80),CONSTRAINT CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_27*/
CREATE TABLE sys_qrtz_simprop_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,STR_PROP_1 VARCHAR2(512) NULL,STR_PROP_2 VARCHAR2(512) NULL,STR_PROP_3 VARCHAR2(512) NULL,INT_PROP_1 NUMBER(10) NULL,INT_PROP_2 NUMBER(10) NULL,LONG_PROP_1 NUMBER(13) NULL,LONG_PROP_2 NUMBER(13) NULL,DEC_PROP_1 NUMERIC(13,4) NULL,DEC_PROP_2 NUMERIC(13,4) NULL,BOOL_PROP_1 VARCHAR2(1) NULL,BOOL_PROP_2 VARCHAR2(1) NULL,CONSTRAINT SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_28*/
CREATE TABLE sys_qrtz_blob_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,BLOB_DATA BLOB NULL,CONSTRAINT BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_29*/
CREATE TABLE sys_qrtz_calendars(SCHED_NAME VARCHAR2(120) NOT NULL,CALENDAR_NAME VARCHAR2(200) NOT NULL,CALENDAR BLOB NOT NULL,CONSTRAINT CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
/*QUARTZ_30*/
CREATE TABLE sys_qrtz_paused_trigger_grps(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,CONSTRAINT PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
/*QUARTZ_31*/
CREATE TABLE sys_qrtz_fired_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,ENTRY_ID VARCHAR2(95) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,INSTANCE_NAME VARCHAR2(200) NOT NULL,FIRED_TIME NUMBER(13) NOT NULL,SCHED_TIME NUMBER(13) NOT NULL,PRIORITY NUMBER(13) NOT NULL,STATE VARCHAR2(16) NOT NULL,JOB_NAME VARCHAR2(200) NULL,JOB_GROUP VARCHAR2(200) NULL,IS_NONCONCURRENT VARCHAR2(1) NULL,REQUESTS_RECOVERY VARCHAR2(1) NULL,CONSTRAINT FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID))
/*QUARTZ_32*/
CREATE TABLE sys_qrtz_scheduler_state (SCHED_NAME VARCHAR2(120) NOT NULL,INSTANCE_NAME VARCHAR2(200) NOT NULL,LAST_CHECKIN_TIME NUMBER(13) NOT NULL,CHECKIN_INTERVAL NUMBER(13) NOT NULL,CONSTRAINT SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
/*QUARTZ_33*/
CREATE TABLE sys_qrtz_locks(SCHED_NAME VARCHAR2(120) NOT NULL,LOCK_NAME VARCHAR2(40) NOT NULL, CONSTRAINT LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME))
/*QUARTZ_34*/
create index qz_j_req_recovery on sys_qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY)
/*QUARTZ_35*/
create index qz_j_grp on sys_qrtz_job_details(SCHED_NAME,JOB_GROUP)
/*QUARTZ_36*/
create index qz_t_j on sys_qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP)
/*QUARTZ_37*/
create index qz_t_jg on sys_qrtz_triggers(SCHED_NAME,JOB_GROUP)
/*QUARTZ_38*/
create index qz_t_c on sys_qrtz_triggers(SCHED_NAME,CALENDAR_NAME)
/*QUARTZ_39*/
create index qz_t_g on sys_qrtz_triggers(SCHED_NAME,TRIGGER_GROUP)
/*QUARTZ_40*/
create index qz_t_state on sys_qrtz_triggers(SCHED_NAME,TRIGGER_STATE)
/*QUARTZ_41*/
create index qz_t_n_state on sys_qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE)
/*QUARTZ_42*/
create index qz_t_n_g_state on sys_qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE)
/*QUARTZ_43*/
create index qz_t_next_fire_time on sys_qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME)
/*QUARTZ_44*/
create index qz_t_nft_st on sys_qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME)
/*QUARTZ_45*/
create index qz_t_nft_misfire on sys_qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME)
/*QUARTZ_46*/
create index qz_t_nft_st_misfire on sys_qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE)
/*QUARTZ_47*/
create index qz_t_nft_st_misfire_grp on sys_qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE)
/*QUARTZ_48*/
create index qz_ft_trig_inst_name on sys_qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME)
/*QUARTZ_49*/
create index qz_ft_inst_job_req_rcvry on sys_qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY)
/*QUARTZ_50*/
create index qz_ft_j_g on sys_qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP)
/*QUARTZ_51*/
create index qz_ft_jg on sys_qrtz_fired_triggers(SCHED_NAME,JOB_GROUP)
/*QUARTZ_52*/
create index qz_ft_t_g on sys_qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
/*QUARTZ_53*/
create index qz_ft_tg on sys_qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP)
-84
View File
@@ -1,84 +0,0 @@
/*QUARTZ_01*/
DROP TABLE IF EXISTS SYS_QRTZ_FIRED_TRIGGERS;
/*QUARTZ_02*/
DROP TABLE IF EXISTS SYS_QRTZ_PAUSED_TRIGGER_GRPS;
/*QUARTZ_03*/
DROP TABLE IF EXISTS SYS_QRTZ_SCHEDULER_STATE;
/*QUARTZ_04*/
DROP TABLE IF EXISTS SYS_QRTZ_LOCKS;
/*QUARTZ_05*/
DROP TABLE IF EXISTS SYS_QRTZ_SIMPLE_TRIGGERS;
/*QUARTZ_06*/
DROP TABLE IF EXISTS SYS_QRTZ_SIMPROP_TRIGGERS;
/*QUARTZ_07*/
DROP TABLE IF EXISTS SYS_QRTZ_CRON_TRIGGERS;
/*QUARTZ_08*/
DROP TABLE IF EXISTS SYS_QRTZ_BLOB_TRIGGERS;
/*QUARTZ_09*/
DROP TABLE IF EXISTS SYS_QRTZ_TRIGGERS;
/*QUARTZ_10*/
DROP TABLE IF EXISTS SYS_QRTZ_JOB_DETAILS;
/*QUARTZ_11*/
DROP TABLE IF EXISTS SYS_QRTZ_CALENDARS;
/*QUARTZ_12*/
CREATE TABLE SYS_QRTZ_JOB_DETAILS(SCHED_NAME VARCHAR(120) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,JOB_CLASS_NAME VARCHAR(250) NOT NULL,IS_DURABLE VARCHAR(1) NOT NULL,IS_NONCONCURRENT VARCHAR(1) NOT NULL,IS_UPDATE_DATA VARCHAR(1) NOT NULL,REQUESTS_RECOVERY VARCHAR(1) NOT NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))ENGINE=InnoDB;
/*QUARTZ_13*/
CREATE TABLE SYS_QRTZ_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,JOB_NAME VARCHAR(200) NOT NULL,JOB_GROUP VARCHAR(200) NOT NULL,DESCRIPTION VARCHAR(250) NULL,NEXT_FIRE_TIME BIGINT(13) NULL,PREV_FIRE_TIME BIGINT(13) NULL,PRIORITY INTEGER NULL,TRIGGER_STATE VARCHAR(16) NOT NULL,TRIGGER_TYPE VARCHAR(8) NOT NULL,START_TIME BIGINT(13) NOT NULL,END_TIME BIGINT(13) NULL,CALENDAR_NAME VARCHAR(200) NULL,MISFIRE_INSTR SMALLINT(2) NULL,JOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)REFERENCES SYS_QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))ENGINE=InnoDB;
/*QUARTZ_14*/
CREATE TABLE SYS_QRTZ_SIMPLE_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,REPEAT_COUNT BIGINT(7) NOT NULL,REPEAT_INTERVAL BIGINT(12) NOT NULL,TIMES_TRIGGERED BIGINT(10) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;
/*QUARTZ_15*/
CREATE TABLE SYS_QRTZ_CRON_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,CRON_EXPRESSION VARCHAR(120) NOT NULL,TIME_ZONE_ID VARCHAR(80),PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;
/*QUARTZ_16*/
CREATE TABLE SYS_QRTZ_SIMPROP_TRIGGERS(SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,STR_PROP_1 VARCHAR(512) NULL,STR_PROP_2 VARCHAR(512) NULL,STR_PROP_3 VARCHAR(512) NULL,INT_PROP_1 INT NULL,INT_PROP_2 INT NULL,LONG_PROP_1 BIGINT NULL,LONG_PROP_2 BIGINT NULL,DEC_PROP_1 NUMERIC(13,4) NULL,DEC_PROP_2 NUMERIC(13,4) NULL,BOOL_PROP_1 VARCHAR(1) NULL,BOOL_PROP_2 VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;
/*QUARTZ_17*/
CREATE TABLE SYS_QRTZ_BLOB_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,BLOB_DATA BLOB NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))ENGINE=InnoDB;
/*QUARTZ_18*/
CREATE TABLE SYS_QRTZ_CALENDARS (SCHED_NAME VARCHAR(120) NOT NULL,CALENDAR_NAME VARCHAR(200) NOT NULL,CALENDAR BLOB NOT NULL,PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))ENGINE=InnoDB;
/*QUARTZ_19*/
CREATE TABLE SYS_QRTZ_PAUSED_TRIGGER_GRPS (SCHED_NAME VARCHAR(120) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))ENGINE=InnoDB;
/*QUARTZ_20*/
CREATE TABLE SYS_QRTZ_FIRED_TRIGGERS (SCHED_NAME VARCHAR(120) NOT NULL,ENTRY_ID VARCHAR(95) NOT NULL,TRIGGER_NAME VARCHAR(200) NOT NULL,TRIGGER_GROUP VARCHAR(200) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,FIRED_TIME BIGINT(13) NOT NULL,SCHED_TIME BIGINT(13) NOT NULL,PRIORITY INTEGER NOT NULL,STATE VARCHAR(16) NOT NULL,JOB_NAME VARCHAR(200) NULL,JOB_GROUP VARCHAR(200) NULL,IS_NONCONCURRENT VARCHAR(1) NULL,REQUESTS_RECOVERY VARCHAR(1) NULL,PRIMARY KEY (SCHED_NAME,ENTRY_ID))ENGINE=InnoDB;
/*QUARTZ_21*/
CREATE TABLE SYS_QRTZ_SCHEDULER_STATE (SCHED_NAME VARCHAR(120) NOT NULL,INSTANCE_NAME VARCHAR(200) NOT NULL,LAST_CHECKIN_TIME BIGINT(13) NOT NULL,CHECKIN_INTERVAL BIGINT(13) NOT NULL,PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))ENGINE=InnoDB;
/*QUARTZ_22*/
CREATE TABLE SYS_QRTZ_LOCKS (SCHED_NAME VARCHAR(120) NOT NULL,LOCK_NAME VARCHAR(40) NOT NULL,PRIMARY KEY (SCHED_NAME,LOCK_NAME))ENGINE=InnoDB;
/*QUARTZ_23*/
CREATE INDEX IDX_SYS_QRTZ_01 ON SYS_QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
/*QUARTZ_24*/
CREATE INDEX IDX_SYS_QRTZ_02 ON SYS_QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);
/*QUARTZ_25*/
CREATE INDEX IDX_SYS_QRTZ_03 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
/*QUARTZ_26*/
CREATE INDEX IDX_SYS_QRTZ_04 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
/*QUARTZ_27*/
CREATE INDEX IDX_SYS_QRTZ_05 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
/*QUARTZ_28*/
CREATE INDEX IDX_SYS_QRTZ_06 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
/*QUARTZ_29*/
CREATE INDEX IDX_SYS_QRTZ_07 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
/*QUARTZ_30*/
CREATE INDEX IDX_SYS_QRTZ_08 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
/*QUARTZ_31*/
CREATE INDEX IDX_SYS_QRTZ_09 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
/*QUARTZ_32*/
CREATE INDEX IDX_SYS_QRTZ_10 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
/*QUARTZ_33*/
CREATE INDEX IDX_SYS_QRTZ_11 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
/*QUARTZ_34*/
CREATE INDEX IDX_SYS_QRTZ_12 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
/*QUARTZ_35*/
CREATE INDEX IDX_SYS_QRTZ_13 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
/*QUARTZ_36*/
CREATE INDEX IDX_SYS_QRTZ_14 ON SYS_QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);
/*QUARTZ_37*/
CREATE INDEX IDX_SYS_QRTZ_15 ON SYS_QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
/*QUARTZ_38*/
CREATE INDEX IDX_SYS_QRTZ_16 ON SYS_QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
/*QUARTZ_39*/
CREATE INDEX IDX_SYS_QRTZ_17 ON SYS_QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
/*QUARTZ_40*/
CREATE INDEX IDX_SYS_QRTZ_18 ON SYS_QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
/*QUARTZ_41*/
CREATE INDEX IDX_SYS_QRTZ_19 ON SYS_QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
/*QUARTZ_42*/
CREATE INDEX IDX_SYS_QRTZ_20 ON SYS_QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
-62
View File
@@ -1,62 +0,0 @@
/*QUARTZ_23*/
CREATE TABLE sys_qrtz_job_details(SCHED_NAME VARCHAR2(120) NOT NULL,JOB_NAME VARCHAR2(200) NOT NULL,JOB_GROUP VARCHAR2(200) NOT NULL,DESCRIPTION VARCHAR2(250) NULL,JOB_CLASS_NAME VARCHAR2(250) NOT NULL, IS_DURABLE VARCHAR2(1) NOT NULL,IS_NONCONCURRENT VARCHAR2(1) NOT NULL,IS_UPDATE_DATA VARCHAR2(1) NOT NULL,REQUESTS_RECOVERY VARCHAR2(1) NOT NULL,JOB_DATA BLOB NULL,CONSTRAINT JOB_DETAILS_PK PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
/*QUARTZ_24*/
CREATE TABLE sys_qrtz_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,JOB_NAME VARCHAR2(200) NOT NULL, JOB_GROUP VARCHAR2(200) NOT NULL,DESCRIPTION VARCHAR2(250) NULL,NEXT_FIRE_TIME NUMBER(13) NULL,PREV_FIRE_TIME NUMBER(13) NULL,PRIORITY NUMBER(13) NULL,TRIGGER_STATE VARCHAR2(16) NOT NULL,TRIGGER_TYPE VARCHAR2(8) NOT NULL,START_TIME NUMBER(13) NOT NULL,END_TIME NUMBER(13) NULL,CALENDAR_NAME VARCHAR2(200) NULL,MISFIRE_INSTR NUMBER(2) NULL,JOB_DATA BLOB NULL,CONSTRAINT TRIGGERS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT TRIGGER_TO_JOBS_FK FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP) REFERENCES sys_qrtz_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
/*QUARTZ_25*/
CREATE TABLE sys_qrtz_simple_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL, REPEAT_COUNT NUMBER(7) NOT NULL,REPEAT_INTERVAL NUMBER(12) NOT NULL,TIMES_TRIGGERED NUMBER(10) NOT NULL,CONSTRAINT SIMPLE_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP), CONSTRAINT SIMPLE_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_26*/
CREATE TABLE sys_qrtz_cron_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL, CRON_EXPRESSION VARCHAR2(120) NOT NULL, TIME_ZONE_ID VARCHAR2(80),CONSTRAINT CRON_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT CRON_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_27*/
CREATE TABLE sys_qrtz_simprop_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,STR_PROP_1 VARCHAR2(512) NULL,STR_PROP_2 VARCHAR2(512) NULL,STR_PROP_3 VARCHAR2(512) NULL,INT_PROP_1 NUMBER(10) NULL,INT_PROP_2 NUMBER(10) NULL,LONG_PROP_1 NUMBER(13) NULL,LONG_PROP_2 NUMBER(13) NULL,DEC_PROP_1 NUMERIC(13,4) NULL,DEC_PROP_2 NUMERIC(13,4) NULL,BOOL_PROP_1 VARCHAR2(1) NULL,BOOL_PROP_2 VARCHAR2(1) NULL,CONSTRAINT SIMPROP_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT SIMPROP_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_28*/
CREATE TABLE sys_qrtz_blob_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,BLOB_DATA BLOB NULL,CONSTRAINT BLOB_TRIG_PK PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),CONSTRAINT BLOB_TRIG_TO_TRIG_FK FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)REFERENCES sys_qrtz_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
/*QUARTZ_29*/
CREATE TABLE sys_qrtz_calendars(SCHED_NAME VARCHAR2(120) NOT NULL,CALENDAR_NAME VARCHAR2(200) NOT NULL,CALENDAR BLOB NOT NULL,CONSTRAINT CALENDARS_PK PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
/*QUARTZ_30*/
CREATE TABLE sys_qrtz_paused_trigger_grps(SCHED_NAME VARCHAR2(120) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,CONSTRAINT PAUSED_TRIG_GRPS_PK PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
/*QUARTZ_31*/
CREATE TABLE sys_qrtz_fired_triggers(SCHED_NAME VARCHAR2(120) NOT NULL,ENTRY_ID VARCHAR2(95) NOT NULL,TRIGGER_NAME VARCHAR2(200) NOT NULL,TRIGGER_GROUP VARCHAR2(200) NOT NULL,INSTANCE_NAME VARCHAR2(200) NOT NULL,FIRED_TIME NUMBER(13) NOT NULL,SCHED_TIME NUMBER(13) NOT NULL,PRIORITY NUMBER(13) NOT NULL,STATE VARCHAR2(16) NOT NULL,JOB_NAME VARCHAR2(200) NULL,JOB_GROUP VARCHAR2(200) NULL,IS_NONCONCURRENT VARCHAR2(1) NULL,REQUESTS_RECOVERY VARCHAR2(1) NULL,CONSTRAINT FIRED_TRIGGER_PK PRIMARY KEY (SCHED_NAME,ENTRY_ID))
/*QUARTZ_32*/
CREATE TABLE sys_qrtz_scheduler_state (SCHED_NAME VARCHAR2(120) NOT NULL,INSTANCE_NAME VARCHAR2(200) NOT NULL,LAST_CHECKIN_TIME NUMBER(13) NOT NULL,CHECKIN_INTERVAL NUMBER(13) NOT NULL,CONSTRAINT SCHEDULER_STATE_PK PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
/*QUARTZ_33*/
CREATE TABLE sys_qrtz_locks(SCHED_NAME VARCHAR2(120) NOT NULL,LOCK_NAME VARCHAR2(40) NOT NULL, CONSTRAINT LOCKS_PK PRIMARY KEY (SCHED_NAME,LOCK_NAME))
/*QUARTZ_34*/
create index qz_j_req_recovery on sys_qrtz_job_details(SCHED_NAME,REQUESTS_RECOVERY)
/*QUARTZ_35*/
create index qz_j_grp on sys_qrtz_job_details(SCHED_NAME,JOB_GROUP)
/*QUARTZ_36*/
create index qz_t_j on sys_qrtz_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP)
/*QUARTZ_37*/
create index qz_t_jg on sys_qrtz_triggers(SCHED_NAME,JOB_GROUP)
/*QUARTZ_38*/
create index qz_t_c on sys_qrtz_triggers(SCHED_NAME,CALENDAR_NAME)
/*QUARTZ_39*/
create index qz_t_g on sys_qrtz_triggers(SCHED_NAME,TRIGGER_GROUP)
/*QUARTZ_40*/
create index qz_t_state on sys_qrtz_triggers(SCHED_NAME,TRIGGER_STATE)
/*QUARTZ_41*/
create index qz_t_n_state on sys_qrtz_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE)
/*QUARTZ_42*/
create index qz_t_n_g_state on sys_qrtz_triggers(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE)
/*QUARTZ_43*/
create index qz_t_next_fire_time on sys_qrtz_triggers(SCHED_NAME,NEXT_FIRE_TIME)
/*QUARTZ_44*/
create index qz_t_nft_st on sys_qrtz_triggers(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME)
/*QUARTZ_45*/
create index qz_t_nft_misfire on sys_qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME)
/*QUARTZ_46*/
create index qz_t_nft_st_misfire on sys_qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE)
/*QUARTZ_47*/
create index qz_t_nft_st_misfire_grp on sys_qrtz_triggers(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE)
/*QUARTZ_48*/
create index qz_ft_trig_inst_name on sys_qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME)
/*QUARTZ_49*/
create index qz_ft_inst_job_req_rcvry on sys_qrtz_fired_triggers(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY)
/*QUARTZ_50*/
create index qz_ft_j_g on sys_qrtz_fired_triggers(SCHED_NAME,JOB_NAME,JOB_GROUP)
/*QUARTZ_51*/
create index qz_ft_jg on sys_qrtz_fired_triggers(SCHED_NAME,JOB_GROUP)
/*QUARTZ_52*/
create index qz_ft_t_g on sys_qrtz_fired_triggers(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
/*QUARTZ_53*/
create index qz_ft_tg on sys_qrtz_fired_triggers(SCHED_NAME,TRIGGER_GROUP)
-281
View File
@@ -1,281 +0,0 @@
/*QUARTZ_01*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_SYS_QRTZ_TRIGGERS_SYS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[SYS_QRTZ_TRIGGERS] DROP CONSTRAINT FK_SYS_QRTZ_TRIGGERS_SYS_QRTZ_JOB_DETAILS
/*QUARTZ_02*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_SYS_QRTZ_CRON_TRIGGERS_SYS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[SYS_QRTZ_CRON_TRIGGERS] DROP CONSTRAINT FK_SYS_QRTZ_CRON_TRIGGERS_SYS_QRTZ_TRIGGERS
/*QUARTZ_03*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_SYS_QRTZ_SIMPLE_TRIGGERS_SYS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[SYS_QRTZ_SIMPLE_TRIGGERS] DROP CONSTRAINT FK_SYS_QRTZ_SIMPLE_TRIGGERS_SYS_QRTZ_TRIGGERS
/*QUARTZ_04*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[FK_SYS_QRTZ_SIMPROP_TRIGGERS_SYS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISFOREIGNKEY') = 1)
ALTER TABLE [dbo].[SYS_QRTZ_SIMPROP_TRIGGERS] DROP CONSTRAINT FK_SYS_QRTZ_SIMPROP_TRIGGERS_SYS_QRTZ_TRIGGERS
/*QUARTZ_05*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_CALENDARS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_CALENDARS]
/*QUARTZ_06*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_CRON_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_CRON_TRIGGERS]
/*QUARTZ_07*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_BLOB_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_BLOB_TRIGGERS]
/*QUARTZ_08*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_FIRED_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_FIRED_TRIGGERS]
/*QUARTZ_09*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_PAUSED_TRIGGER_GRPS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_PAUSED_TRIGGER_GRPS]
/*QUARTZ_10*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_SCHEDULER_STATE]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_SCHEDULER_STATE]
/*QUARTZ_11*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_LOCKS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_LOCKS]
/*QUARTZ_12*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_JOB_DETAILS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_JOB_DETAILS]
/*QUARTZ_13*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_SIMPLE_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_SIMPLE_TRIGGERS]
/*QUARTZ_14*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_SIMPROP_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_SIMPROP_TRIGGERS]
/*QUARTZ_15*/
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[dbo].[SYS_QRTZ_TRIGGERS]') AND OBJECTPROPERTY(id, N'ISUSERTABLE') = 1)
DROP TABLE [dbo].[SYS_QRTZ_TRIGGERS]
/*QUARTZ_16*/
CREATE TABLE [dbo].[SYS_QRTZ_CALENDARS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[CALENDAR_NAME] [VARCHAR] (200) NOT NULL ,
[CALENDAR] [IMAGE] NOT NULL
) ON [PRIMARY]
/*QUARTZ_17*/
CREATE TABLE [dbo].[SYS_QRTZ_CRON_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[CRON_EXPRESSION] [VARCHAR] (120) NOT NULL ,
[TIME_ZONE_ID] [VARCHAR] (80)
) ON [PRIMARY]
/*QUARTZ_18*/
CREATE TABLE [dbo].[SYS_QRTZ_FIRED_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[ENTRY_ID] [VARCHAR] (95) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[INSTANCE_NAME] [VARCHAR] (200) NOT NULL ,
[FIRED_TIME] [BIGINT] NOT NULL ,
[SCHED_TIME] [BIGINT] NOT NULL ,
[PRIORITY] [INTEGER] NOT NULL ,
[STATE] [VARCHAR] (16) NOT NULL,
[JOB_NAME] [VARCHAR] (200) NULL ,
[JOB_GROUP] [VARCHAR] (200) NULL ,
[IS_NONCONCURRENT] [VARCHAR] (1) NULL ,
[REQUESTS_RECOVERY] [VARCHAR] (1) NULL
) ON [PRIMARY]
/*QUARTZ_19*/
CREATE TABLE [dbo].[SYS_QRTZ_PAUSED_TRIGGER_GRPS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL
) ON [PRIMARY]
/*QUARTZ_20*/
CREATE TABLE [dbo].[SYS_QRTZ_SCHEDULER_STATE] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[INSTANCE_NAME] [VARCHAR] (200) NOT NULL ,
[LAST_CHECKIN_TIME] [BIGINT] NOT NULL ,
[CHECKIN_INTERVAL] [BIGINT] NOT NULL
) ON [PRIMARY]
/*QUARTZ_21*/
CREATE TABLE [dbo].[SYS_QRTZ_LOCKS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[LOCK_NAME] [VARCHAR] (40) NOT NULL
) ON [PRIMARY]
/*QUARTZ_22*/
CREATE TABLE [dbo].[SYS_QRTZ_JOB_DETAILS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[JOB_NAME] [VARCHAR] (200) NOT NULL ,
[JOB_GROUP] [VARCHAR] (200) NOT NULL ,
[DESCRIPTION] [VARCHAR] (250) NULL ,
[JOB_CLASS_NAME] [VARCHAR] (250) NOT NULL ,
[IS_DURABLE] [VARCHAR] (1) NOT NULL ,
[IS_NONCONCURRENT] [VARCHAR] (1) NOT NULL ,
[IS_UPDATE_DATA] [VARCHAR] (1) NOT NULL ,
[REQUESTS_RECOVERY] [VARCHAR] (1) NOT NULL ,
[JOB_DATA] [IMAGE] NULL
) ON [PRIMARY]
/*QUARTZ_23*/
CREATE TABLE [dbo].[SYS_QRTZ_SIMPLE_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[REPEAT_COUNT] [BIGINT] NOT NULL ,
[REPEAT_INTERVAL] [BIGINT] NOT NULL ,
[TIMES_TRIGGERED] [BIGINT] NOT NULL
) ON [PRIMARY]
/*QUARTZ_24*/
CREATE TABLE [dbo].[SYS_QRTZ_SIMPROP_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[STR_PROP_1] [VARCHAR] (512) NULL,
[STR_PROP_2] [VARCHAR] (512) NULL,
[STR_PROP_3] [VARCHAR] (512) NULL,
[INT_PROP_1] [INT] NULL,
[INT_PROP_2] [INT] NULL,
[LONG_PROP_1] [BIGINT] NULL,
[LONG_PROP_2] [BIGINT] NULL,
[DEC_PROP_1] [NUMERIC] (13,4) NULL,
[DEC_PROP_2] [NUMERIC] (13,4) NULL,
[BOOL_PROP_1] [VARCHAR] (1) NULL,
[BOOL_PROP_2] [VARCHAR] (1) NULL,
) ON [PRIMARY]
/*QUARTZ_25*/
CREATE TABLE [dbo].[SYS_QRTZ_BLOB_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[BLOB_DATA] [IMAGE] NULL
) ON [PRIMARY]
/*QUARTZ_26*/
CREATE TABLE [dbo].[SYS_QRTZ_TRIGGERS] (
[SCHED_NAME] [VARCHAR] (120) NOT NULL ,
[TRIGGER_NAME] [VARCHAR] (200) NOT NULL ,
[TRIGGER_GROUP] [VARCHAR] (200) NOT NULL ,
[JOB_NAME] [VARCHAR] (200) NOT NULL ,
[JOB_GROUP] [VARCHAR] (200) NOT NULL ,
[DESCRIPTION] [VARCHAR] (250) NULL ,
[NEXT_FIRE_TIME] [BIGINT] NULL ,
[PREV_FIRE_TIME] [BIGINT] NULL ,
[PRIORITY] [INTEGER] NULL ,
[TRIGGER_STATE] [VARCHAR] (16) NOT NULL ,
[TRIGGER_TYPE] [VARCHAR] (8) NOT NULL ,
[START_TIME] [BIGINT] NOT NULL ,
[END_TIME] [BIGINT] NULL ,
[CALENDAR_NAME] [VARCHAR] (200) NULL ,
[MISFIRE_INSTR] [SMALLINT] NULL ,
[JOB_DATA] [IMAGE] NULL
) ON [PRIMARY]
/*QUARTZ_27*/
ALTER TABLE [dbo].[SYS_QRTZ_CALENDARS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_CALENDARS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[CALENDAR_NAME]
) ON [PRIMARY]
/*QUARTZ_28*/
ALTER TABLE [dbo].[SYS_QRTZ_CRON_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_CRON_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
/*QUARTZ_29*/
ALTER TABLE [dbo].[SYS_QRTZ_FIRED_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_FIRED_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[ENTRY_ID]
) ON [PRIMARY]
/*QUARTZ_30*/
ALTER TABLE [dbo].[SYS_QRTZ_PAUSED_TRIGGER_GRPS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_PAUSED_TRIGGER_GRPS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
/*QUARTZ_31*/
ALTER TABLE [dbo].[SYS_QRTZ_SCHEDULER_STATE] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_SCHEDULER_STATE] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[INSTANCE_NAME]
) ON [PRIMARY]
/*QUARTZ_32*/
ALTER TABLE [dbo].[SYS_QRTZ_LOCKS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_LOCKS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[LOCK_NAME]
) ON [PRIMARY]
/*QUARTZ_33*/
ALTER TABLE [dbo].[SYS_QRTZ_JOB_DETAILS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_JOB_DETAILS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
) ON [PRIMARY]
/*QUARTZ_34*/
ALTER TABLE [dbo].[SYS_QRTZ_SIMPLE_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_SIMPLE_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
/*QUARTZ_35*/
ALTER TABLE [dbo].[SYS_QRTZ_SIMPROP_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_SIMPROP_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
/*QUARTZ_36*/
ALTER TABLE [dbo].[SYS_QRTZ_TRIGGERS] WITH NOCHECK ADD
CONSTRAINT [PK_SYS_QRTZ_TRIGGERS] PRIMARY KEY CLUSTERED
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON [PRIMARY]
/*QUARTZ_37*/
ALTER TABLE [dbo].[SYS_QRTZ_CRON_TRIGGERS] ADD
CONSTRAINT [FK_SYS_QRTZ_CRON_TRIGGERS_SYS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [dbo].[SYS_QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
/*QUARTZ_38*/
ALTER TABLE [dbo].[SYS_QRTZ_SIMPLE_TRIGGERS] ADD
CONSTRAINT [FK_SYS_QRTZ_SIMPLE_TRIGGERS_SYS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [dbo].[SYS_QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
/*QUARTZ_39*/
ALTER TABLE [dbo].[SYS_QRTZ_SIMPROP_TRIGGERS] ADD
CONSTRAINT [FK_SYS_QRTZ_SIMPROP_TRIGGERS_SYS_QRTZ_TRIGGERS] FOREIGN KEY
(
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) REFERENCES [dbo].[SYS_QRTZ_TRIGGERS] (
[SCHED_NAME],
[TRIGGER_NAME],
[TRIGGER_GROUP]
) ON DELETE CASCADE
/*QUARTZ_40*/
ALTER TABLE [dbo].[SYS_QRTZ_TRIGGERS] ADD
CONSTRAINT [FK_SYS_QRTZ_TRIGGERS_SYS_QRTZ_JOB_DETAILS] FOREIGN KEY
(
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
) REFERENCES [dbo].[SYS_QRTZ_JOB_DETAILS] (
[SCHED_NAME],
[JOB_NAME],
[JOB_GROUP]
)
@@ -1,3 +0,0 @@
ALTER TABLE `site_cug_info`
ADD COLUMN `segmented_open_hours` JSON NULL COMMENT '分段预约场次信息' AFTER `open_hours`,
ADD COLUMN `full_day_open_hour` JSON NULL COMMENT '全天候预约时间段' AFTER `segmented_open_hours`;
@@ -1,3 +0,0 @@
ALTER TABLE `site_cug_info`
ADD COLUMN `reserve_time_type` INT NULL DEFAULT 1 COMMENT '预约时间段类型(1分段预约,2全天候预约)' AFTER `not_apply_time_list`,
ADD COLUMN `open_hours` JSON NULL COMMENT '场次信息' AFTER `reserve_time_type`;
@@ -1,2 +0,0 @@
ALTER TABLE `site_cug_info`
ADD COLUMN `site_photo` VARCHAR(255) NULL COMMENT '场地照片' AFTER `introduce`;
@@ -1,2 +0,0 @@
ALTER TABLE `sys_config`
MODIFY COLUMN `configValue` TEXT;
@@ -1,2 +0,0 @@
ALTER TABLE `sys_home_template`
ADD COLUMN `templateFile` varchar(1000) DEFAULT NULL COMMENT 'template file' AFTER `templateIcon`;
@@ -1,2 +0,0 @@
ALTER TABLE `sys_home_template`
ADD COLUMN `templateIcon` varchar(255) DEFAULT NULL COMMENT 'template icon' AFTER `templateName`;
@@ -1,6 +0,0 @@
ALTER TABLE `sys_home_template`
ADD COLUMN `templateName` varchar(50) DEFAULT NULL COMMENT 'display template name' AFTER `name`;
UPDATE `sys_home_template`
SET `templateName` = `name`
WHERE (`templateName` IS NULL OR `templateName` = '');
@@ -1,26 +0,0 @@
CREATE TABLE IF NOT EXISTS `sys_home_template` (
`id` varchar(32) NOT NULL COMMENT 'business id',
`name` varchar(50) DEFAULT NULL COMMENT 'template name',
`templateName` varchar(50) DEFAULT NULL COMMENT 'display template name',
`templateIcon` varchar(255) DEFAULT NULL COMMENT 'template icon',
`templateFile` varchar(1000) DEFAULT NULL COMMENT 'template file',
`cover` varchar(255) DEFAULT NULL COMMENT 'template cover',
`content` text COMMENT 'template content',
`url` varchar(1000) DEFAULT NULL COMMENT 'pc url',
`h5Url` varchar(1000) DEFAULT NULL COMMENT 'h5 url',
`allowUserGroupId` int DEFAULT NULL COMMENT 'allowed user group id',
`allowUserSql` varchar(1000) DEFAULT NULL COMMENT 'allowed user sql',
`enable` tinyint(1) DEFAULT 0 COMMENT 'enabled',
`classPath` varchar(500) DEFAULT NULL COMMENT 'source class path',
`top` tinyint(1) DEFAULT 0 COMMENT 'top flag',
`push` tinyint(1) DEFAULT 0 COMMENT 'push flag',
`sortNo` int DEFAULT 0 COMMENT 'sort number',
`startDate` datetime DEFAULT NULL COMMENT 'start date',
`endDate` datetime DEFAULT NULL COMMENT 'end date',
`createdBy` varchar(32) DEFAULT NULL,
`createdAt` bigint DEFAULT NULL,
`updatedBy` varchar(32) DEFAULT NULL,
`updatedAt` bigint DEFAULT NULL,
`delFlag` tinyint(1) DEFAULT 0,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='home work template';
-253
View File
@@ -1,253 +0,0 @@
-- 普惠疗休养系统字典初始化。
-- 执行后可在 /platform/sys/dict 页面看到:疗休养(Tour) -> 组织形式/疗休养类型/线路类型/床型。
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict001', '', '9500', '疗休养', '普惠疗休养平台字典', 'Tour', 0, 9500, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
WHERE NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'Tour') t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict002', p.id, CONCAT(p.path, '0001'), '组织形式', '疗休养组织形式', 'organizationType', 0, 1, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'Tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'organizationType' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict003', p.id, CONCAT(p.path, '0001'), '校工会组织', '疗休养组织形式', 'schoolUnion', 0, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'organizationType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'schoolUnion' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict004', p.id, CONCAT(p.path, '0002'), '分工会组织', '疗休养组织形式', 'branchUnion', 0, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'organizationType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'branchUnion' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict005', p.id, CONCAT(p.path, '0003'), '个人组织', '疗休养组织形式', 'personal', 0, 3, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'organizationType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'personal' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict006', p.id, CONCAT(p.path, '0002'), '疗休养类型', '疗休养类型', 'tourType', 0, 2, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'Tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'tourType' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict007', p.id, CONCAT(p.path, '0001'), '普惠性疗休养', '疗休养类型', 'inclusiveTour', 0, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'tourType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'inclusiveTour' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict008', p.id, CONCAT(p.path, '0002'), '优秀职工疗休养', '疗休养类型', 'excellentWorkerTour', 0, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'tourType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'excellentWorkerTour' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict009', p.id, CONCAT(p.path, '0003'), '线路类型', '线路类型', 'lineType', 0, 3, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'Tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'lineType' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict010', p.id, CONCAT(p.path, '0001'), '省内线路', '线路类型', 'inProvinceLine', 0, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'lineType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'inProvinceLine' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict011', p.id, CONCAT(p.path, '0002'), '省外线路', '线路类型', 'outProvinceLine', 0, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'lineType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'outProvinceLine' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict020', p.id, CONCAT(p.path, '0004'), '床型', '床型', 'bedType', 0, 4, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'Tour'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'bedType' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict021', p.id, CONCAT(p.path, '0001'), '双人床', '床型', 'doubleBed', 0, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'bedType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'doubleBed' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict022', p.id, CONCAT(p.path, '0002'), '单人床', '床型', 'singleBed', 0, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'bedType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'singleBed' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict023', p.id, CONCAT(p.path, '0003'), '大床', '床型', 'kingBed', 0, 3, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'bedType'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'kingBed' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict012', '', '9600', '亲属关系', '亲属关系', 'familyRelationship', 0, 9600, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
WHERE NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'familyRelationship') t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict013', p.id, CONCAT(p.path, '0001'), '直系亲属', '亲属关系', 'directRelative', 0, 1, 1,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'familyRelationship'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'directRelative' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict014', p.id, CONCAT(p.path, '0001'), '父亲', '直系亲属', 'father', 0, 1, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'directRelative'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'father' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict015', p.id, CONCAT(p.path, '0002'), '母亲', '直系亲属', 'mother', 0, 2, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'directRelative'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'mother' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict016', p.id, CONCAT(p.path, '0003'), '丈夫', '直系亲属', 'husband', 0, 3, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'directRelative'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'husband' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict017', p.id, CONCAT(p.path, '0004'), '妻子', '直系亲属', 'wife', 0, 4, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'directRelative'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'wife' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict018', p.id, CONCAT(p.path, '0005'), '儿子', '直系亲属', 'son', 0, 5, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'directRelative'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'son' AND `parentId` = p.id) t);
INSERT INTO `sys_dict` (
`id`, `parentId`, `path`, `name`, `remark`, `code`, `disabled`, `location`, `hasChildren`,
`createdBy`, `createdAt`, `updatedBy`, `updatedAt`, `delFlag`
)
SELECT
'b7c63f0c73a44a9a8c4f3d3bdict019', p.id, CONCAT(p.path, '0006'), '女儿', '直系亲属', 'daughter', 0, 6, 0,
'', UNIX_TIMESTAMP(NOW()) * 1000, '', UNIX_TIMESTAMP(NOW()) * 1000, 0
FROM `sys_dict` p
WHERE p.`code` = 'directRelative'
AND NOT EXISTS (SELECT 1 FROM (SELECT id FROM `sys_dict` WHERE `code` = 'daughter' AND `parentId` = p.id) t);
UPDATE `sys_dict` SET `hasChildren` = 1 WHERE `code` IN ('Tour', 'organizationType', 'tourType', 'lineType', 'bedType', 'familyRelationship', 'directRelative');
@@ -1,7 +0,0 @@
-- Add matter reference so signup records are unique per travel period/matter.
ALTER TABLE `tour_ledger`
ADD COLUMN `matterId` varchar(32) DEFAULT NULL COMMENT '报名事项ID' AFTER `signupTime`;
ALTER TABLE `tour_ledger`
ADD KEY `idx_tour_ledger_matter` (`matterId`),
ADD KEY `idx_tour_ledger_matter_job` (`matterId`, `jobNo`);
@@ -1,2 +0,0 @@
ALTER TABLE `tour_ledger`
ADD COLUMN `overCostReimbursed` tinyint(1) DEFAULT 0 COMMENT '报销超出费用' AFTER `reimbursed`;
@@ -1,9 +0,0 @@
-- 疗休养台账查询加速索引。
ALTER TABLE `tour_ledger`
ADD KEY `idx_tour_ledger_year_signup` (`year`, `delFlag`, `signupTime`),
ADD KEY `idx_tour_ledger_year_line` (`year`, `lineId`, `delFlag`),
ADD KEY `idx_tour_ledger_year_union_type` (`year`, `unionId`, `lineType`, `delFlag`),
ADD KEY `idx_tour_ledger_year_job` (`year`, `jobNo`, `delFlag`);
ALTER TABLE `wf_process_instance`
ADD KEY `idx_wf_process_instance_business_state` (`businessNo`, `state`);
@@ -1,21 +0,0 @@
-- 直系亲属线路报名信息表,独立于普通携带亲属信息表。
CREATE TABLE IF NOT EXISTS `tour_ledger_direct_relative` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`ledgerId` varchar(32) DEFAULT NULL COMMENT '台账ID',
`relativeName` varchar(100) DEFAULT NULL COMMENT '亲属姓名',
`unitName` varchar(100) DEFAULT NULL COMMENT '所在单位',
`relationshipCode` varchar(50) DEFAULT NULL COMMENT '亲属关系编码',
`relationshipName` varchar(50) DEFAULT NULL COMMENT '亲属关系',
`lineId` varchar(32) DEFAULT NULL COMMENT '线路ID',
`lineName` varchar(100) DEFAULT NULL COMMENT '线路名称',
`travelStartTime` varchar(20) DEFAULT NULL COMMENT '出行开始日期',
`travelEndTime` varchar(20) DEFAULT NULL COMMENT '出行结束日期',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_ledger_direct_relative_ledger` (`ledgerId`),
KEY `idx_tour_ledger_direct_relative_line` (`lineId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养直系亲属线路报名信息';
@@ -1,10 +0,0 @@
-- 线路管理增加创建人和所在单位业务字段。
ALTER TABLE `tour_line`
ADD COLUMN `creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID' AFTER `travelAgencyId`,
ADD COLUMN `creatorName` varchar(100) DEFAULT NULL COMMENT '创建人' AFTER `creatorUserId`,
ADD COLUMN `unitId` varchar(32) DEFAULT NULL COMMENT '所在单位ID' AFTER `creatorName`,
ADD COLUMN `unitName` varchar(100) DEFAULT NULL COMMENT '所在单位' AFTER `unitId`;
ALTER TABLE `tour_line`
ADD KEY `idx_tour_line_creator` (`creatorUserId`),
ADD KEY `idx_tour_line_unit` (`unitId`);
@@ -1,3 +0,0 @@
-- 线路管理增加是否直系亲属线路字段,默认否。
ALTER TABLE `tour_line`
ADD COLUMN `directFamilyUnitLine` tinyint(1) DEFAULT 0 COMMENT '是否直系亲属线路' AFTER `openFlag`;
@@ -1,3 +0,0 @@
-- 线路管理增加是否对外开放字段,默认是。
ALTER TABLE `tour_line`
ADD COLUMN `openFlag` tinyint(1) DEFAULT 1 COMMENT '是否对外开放' AFTER `mobileThumb`;
@@ -1,7 +0,0 @@
-- 疗休养事项增加创建人字段。
ALTER TABLE `tour_matter`
ADD COLUMN `creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID' AFTER `settingId`,
ADD COLUMN `creatorName` varchar(100) DEFAULT NULL COMMENT '创建人' AFTER `creatorUserId`;
ALTER TABLE `tour_matter`
ADD KEY `idx_tour_matter_creator` (`creatorUserId`);
@@ -1,26 +0,0 @@
-- 疗休养事项批次表。
CREATE TABLE IF NOT EXISTS `tour_matter_batch` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`matterId` varchar(32) DEFAULT NULL COMMENT '事项ID',
`lineId` varchar(32) DEFAULT NULL COMMENT '线路ID',
`batchName` varchar(100) DEFAULT NULL COMMENT '批次名称',
`signupStartTime` varchar(20) DEFAULT NULL COMMENT '报名开始时间',
`signupEndTime` varchar(20) DEFAULT NULL COMMENT '报名结束时间',
`travelStartTime` varchar(20) DEFAULT NULL COMMENT '出行开始时间',
`travelEndTime` varchar(20) DEFAULT NULL COMMENT '出行结束时间',
`changeDeadline` varchar(20) DEFAULT NULL COMMENT '变更截止时间',
`contactName` varchar(30) DEFAULT NULL COMMENT '联系人',
`contactPhone` varchar(30) DEFAULT NULL COMMENT '联系方式',
`minGroupPeople` int DEFAULT NULL COMMENT '最少成团人数',
`maxGroupPeople` int DEFAULT NULL COMMENT '最多成团人数',
`estimatedCost` decimal(10,2) DEFAULT NULL COMMENT '预计费用',
`enabled` tinyint(1) DEFAULT 1 COMMENT '状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_matter_batch_matter` (`matterId`),
KEY `idx_tour_matter_batch_line` (`lineId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养事项批次';
@@ -1,25 +0,0 @@
-- 疗休养事项表。
CREATE TABLE IF NOT EXISTS `tour_matter` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '年度',
`matterName` varchar(100) DEFAULT NULL COMMENT '事项名称',
`settingId` varchar(32) DEFAULT NULL COMMENT '疗休养配置ID',
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
`unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID',
`organizationType` varchar(100) DEFAULT NULL COMMENT '组织形式',
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
`enabled` tinyint(1) DEFAULT 1 COMMENT '事项状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_matter_year_name` (`year`, `matterName`),
KEY `idx_tour_matter_year` (`year`),
KEY `idx_tour_matter_creator` (`creatorUserId`),
KEY `idx_tour_matter_setting` (`settingId`),
KEY `idx_tour_matter_union` (`unionId`),
KEY `idx_tour_matter_org_type` (`organizationType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养事项';
@@ -1,6 +0,0 @@
-- Add activity user scope reference for tour settings.
ALTER TABLE `tour_setting`
ADD COLUMN `activityGroupId` varchar(32) DEFAULT NULL COMMENT '可参加人员范围ID' AFTER `tourType`;
ALTER TABLE `tour_setting`
ADD KEY `idx_tour_setting_activity_group` (`activityGroupId`);
@@ -1,3 +0,0 @@
-- 疗休养配置增加周期允许次数字段。
ALTER TABLE `tour_setting`
ADD COLUMN `cycleAllowedTimes` int DEFAULT NULL COMMENT '周期允许次数' AFTER `cycleTotalCost`;
@@ -1,2 +0,0 @@
ALTER TABLE `tour_setting`
ADD COLUMN `cycleTotalCost` int DEFAULT NULL COMMENT '周期内总费用' AFTER `cycleEndYear`;
@@ -1,4 +0,0 @@
-- Add optional cycle year range for tour settings.
ALTER TABLE `tour_setting`
ADD COLUMN `cycleStartYear` int DEFAULT NULL COMMENT '周期开始年度' AFTER `outProvinceRatio`,
ADD COLUMN `cycleEndYear` int DEFAULT NULL COMMENT '周期结束年度' AFTER `cycleStartYear`;
@@ -1,3 +0,0 @@
-- 疗休养配置增加是否填报床位信息字段,默认开启以兼容历史配置。
ALTER TABLE `tour_setting`
ADD COLUMN `fillBedInfo` tinyint(1) DEFAULT 1 COMMENT '是否填报床位信息' AFTER `allowFamily`;
@@ -1,3 +0,0 @@
ALTER TABLE `tour_setting`
ADD COLUMN `outProvinceRatioType` varchar(50) DEFAULT '当年报名人数' COMMENT '省外人数占比类型' AFTER `outProvinceRatio`,
ADD COLUMN `outProvinceFixedPeople` int DEFAULT 0 COMMENT '省外固定人数' AFTER `outProvinceRatioType`;
@@ -1,183 +0,0 @@
-- 普惠疗休养基础配置表。
-- 若生产环境未开启 Nutz 自动建表,请先执行本脚本再使用“疗休养设置”菜单。
CREATE TABLE IF NOT EXISTS `tour_setting` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '年度',
`configName` varchar(100) DEFAULT NULL COMMENT '疗休养配置名称',
`tourType` varchar(50) DEFAULT NULL COMMENT '疗休养类型',
`activityGroupId` varchar(32) DEFAULT NULL COMMENT '可参加人员范围ID',
`sortNo` int DEFAULT NULL COMMENT '排序编号',
`minGroupPeople` int DEFAULT NULL COMMENT '最少成团人数',
`maxGroupPeople` int DEFAULT NULL COMMENT '最多成团人数',
`outProvinceYears` int DEFAULT NULL COMMENT '省外几年去一次',
`outProvinceRatio` decimal(10,2) DEFAULT NULL COMMENT '省外人数占比',
`outProvinceRatioType` varchar(50) DEFAULT '当年报名人数' COMMENT '省外人数占比类型',
`outProvinceFixedPeople` int DEFAULT 0 COMMENT '省外固定人数',
`cycleStartYear` int DEFAULT NULL COMMENT '周期开始年度',
`cycleEndYear` int DEFAULT NULL COMMENT '周期结束年度',
`cycleTotalCost` int DEFAULT NULL COMMENT '周期内总费用',
`cycleAllowedTimes` int DEFAULT NULL COMMENT '周期允许次数',
`allowFamily` tinyint(1) DEFAULT 0 COMMENT '是否允许携带家属',
`fillBedInfo` tinyint(1) DEFAULT 1 COMMENT '是否填报床位信息',
`enabled` tinyint(1) DEFAULT 1 COMMENT '是否启用',
`serviceNotice` text COMMENT '服务须知',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_setting_year` (`year`),
KEY `idx_tour_setting_activity_group` (`activityGroupId`),
KEY `idx_tour_setting_sort` (`sortNo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养配置';
-- 疗休养配置标段表。
-- 标段先挂在配置上维护,后续线路、旅行社、报名等模块可继续通过 lotId 做业务关联。
CREATE TABLE IF NOT EXISTS `tour_setting_lot` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`settingId` varchar(32) DEFAULT NULL COMMENT '所属配置ID',
`lotName` varchar(50) DEFAULT NULL COMMENT '标段名称',
`lotValue` varchar(50) DEFAULT NULL COMMENT '标段值',
`activityCost` int DEFAULT NULL COMMENT '标段费用',
`allowOverReimbursement` tinyint(1) DEFAULT 0 COMMENT '允许超出报销',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_setting_lot_setting` (`settingId`),
KEY `idx_tour_setting_lot_value` (`lotValue`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养配置标段';
-- 旅行社管理表。
CREATE TABLE IF NOT EXISTS `tour_travel_agency` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '年度',
`agencyCode` varchar(50) DEFAULT NULL COMMENT '旅行社编号',
`agencyName` varchar(100) DEFAULT NULL COMMENT '旅行社名称',
`contactName` varchar(30) DEFAULT NULL COMMENT '联系人',
`contactPhone` varchar(30) DEFAULT NULL COMMENT '联系人手机',
`email` varchar(100) DEFAULT NULL COMMENT '邮箱',
`remark` text COMMENT '备注',
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
`enabled` tinyint(1) DEFAULT 1 COMMENT '激活状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_travel_agency_year_code` (`year`, `agencyCode`),
KEY `idx_tour_travel_agency_name` (`agencyName`),
KEY `idx_tour_travel_agency_contact` (`contactName`, `contactPhone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养旅行社';
-- 线路管理表。
CREATE TABLE IF NOT EXISTS `tour_line` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '创建年度',
`lineCode` varchar(50) DEFAULT NULL COMMENT '线路编号',
`lineName` varchar(100) DEFAULT NULL COMMENT '线路名称',
`travelAgencyId` varchar(32) DEFAULT NULL COMMENT '旅行社ID',
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
`unitId` varchar(32) DEFAULT NULL COMMENT '所在单位ID',
`unitName` varchar(100) DEFAULT NULL COMMENT '所在单位',
`lineType` varchar(50) DEFAULT NULL COMMENT '线路类型',
`lotId` varchar(32) DEFAULT NULL COMMENT '时间标段ID',
`lineContent` text COMMENT '线路内容',
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
`openFlag` tinyint(1) DEFAULT 1 COMMENT '是否对外开放',
`directFamilyUnitLine` tinyint(1) DEFAULT 0 COMMENT '是否直系亲属线路',
`enabled` tinyint(1) DEFAULT 1 COMMENT '激活状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_line_year_code` (`year`, `lineCode`),
KEY `idx_tour_line_year` (`year`),
KEY `idx_tour_line_name` (`lineName`),
KEY `idx_tour_line_agency` (`travelAgencyId`),
KEY `idx_tour_line_creator` (`creatorUserId`),
KEY `idx_tour_line_unit` (`unitId`),
KEY `idx_tour_line_lot` (`lotId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养线路';
-- 疗休养事项表。
CREATE TABLE IF NOT EXISTS `tour_matter` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`year` int DEFAULT NULL COMMENT '年度',
`matterName` varchar(100) DEFAULT NULL COMMENT '事项名称',
`settingId` varchar(32) DEFAULT NULL COMMENT '疗休养配置ID',
`creatorUserId` varchar(32) DEFAULT NULL COMMENT '创建人ID',
`creatorName` varchar(100) DEFAULT NULL COMMENT '创建人',
`unionId` varchar(32) DEFAULT NULL COMMENT '所属工会ID',
`organizationType` varchar(100) DEFAULT NULL COMMENT '组织形式',
`mobileThumb` varchar(500) DEFAULT NULL COMMENT '移动端缩略图',
`enabled` tinyint(1) DEFAULT 1 COMMENT '事项状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tour_matter_year_name` (`year`, `matterName`),
KEY `idx_tour_matter_year` (`year`),
KEY `idx_tour_matter_creator` (`creatorUserId`),
KEY `idx_tour_matter_setting` (`settingId`),
KEY `idx_tour_matter_union` (`unionId`),
KEY `idx_tour_matter_org_type` (`organizationType`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养事项';
-- 疗休养事项批次表。
CREATE TABLE IF NOT EXISTS `tour_matter_batch` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`matterId` varchar(32) DEFAULT NULL COMMENT '事项ID',
`lineId` varchar(32) DEFAULT NULL COMMENT '线路ID',
`batchName` varchar(100) DEFAULT NULL COMMENT '批次名称',
`signupStartTime` varchar(20) DEFAULT NULL COMMENT '报名开始时间',
`signupEndTime` varchar(20) DEFAULT NULL COMMENT '报名结束时间',
`travelStartTime` varchar(20) DEFAULT NULL COMMENT '出行开始时间',
`travelEndTime` varchar(20) DEFAULT NULL COMMENT '出行结束时间',
`changeDeadline` varchar(20) DEFAULT NULL COMMENT '变更截止时间',
`contactName` varchar(30) DEFAULT NULL COMMENT '联系人',
`contactPhone` varchar(30) DEFAULT NULL COMMENT '联系方式',
`minGroupPeople` int DEFAULT NULL COMMENT '最少成团人数',
`maxGroupPeople` int DEFAULT NULL COMMENT '最多成团人数',
`estimatedCost` decimal(10,2) DEFAULT NULL COMMENT '预计费用',
`enabled` tinyint(1) DEFAULT 1 COMMENT '状态',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_matter_batch_matter` (`matterId`),
KEY `idx_tour_matter_batch_line` (`lineId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养事项批次';
-- 直系亲属线路报名信息表。
CREATE TABLE IF NOT EXISTS `tour_ledger_direct_relative` (
`id` varchar(32) NOT NULL COMMENT 'ID',
`ledgerId` varchar(32) DEFAULT NULL COMMENT '台账ID',
`relativeName` varchar(100) DEFAULT NULL COMMENT '亲属姓名',
`unitName` varchar(100) DEFAULT NULL COMMENT '所在单位',
`relationshipCode` varchar(50) DEFAULT NULL COMMENT '亲属关系编码',
`relationshipName` varchar(50) DEFAULT NULL COMMENT '亲属关系',
`lineId` varchar(32) DEFAULT NULL COMMENT '线路ID',
`lineName` varchar(100) DEFAULT NULL COMMENT '线路名称',
`travelStartTime` varchar(20) DEFAULT NULL COMMENT '出行开始日期',
`travelEndTime` varchar(20) DEFAULT NULL COMMENT '出行结束日期',
`createdBy` varchar(32) DEFAULT NULL COMMENT '创建人',
`createdAt` bigint DEFAULT NULL COMMENT '创建时间',
`updatedBy` varchar(32) DEFAULT NULL COMMENT '修改人',
`updatedAt` bigint DEFAULT NULL COMMENT '修改时间',
`delFlag` tinyint(1) DEFAULT 0 COMMENT '删除标记',
PRIMARY KEY (`id`),
KEY `idx_tour_ledger_direct_relative_ledger` (`ledgerId`),
KEY `idx_tour_ledger_direct_relative_line` (`lineId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='普惠疗休养直系亲属线路报名信息';
@@ -1,2 +0,0 @@
ALTER TABLE `tour_setting_lot`
ADD COLUMN `allowOverReimbursement` tinyint(1) DEFAULT 0 COMMENT '允许超出报销' AFTER `activityCost`;
@@ -78,10 +78,10 @@ layout("/layouts/platform.html"){
<el-table-column prop="userState" label="在职状态" sortable width="120"></el-table-column>
<el-table-column prop="arrivalAtSchoolDate" label="来校时间" sortable width="120"></el-table-column>
<el-table-column prop="personType" label="人员类型" sortable width="120"></el-table-column>
<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
<!-- <el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
<el-table-column prop="position" label="干部职务" sortable width="120" show-overflow-tooltip></el-table-column>
<el-table-column prop="education" label="学历" show-overflow-tooltip sortable width="120"></el-table-column>
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>-->
<el-table-column prop="unitName" label="单位" show-overflow-tooltip sortable width="120"></el-table-column>
<el-table-column prop="unitId" label="单位编码" sortable width="120"></el-table-column>
<el-table-column prop="political" label="政治面貌" sortable></el-table-column>
@@ -71,10 +71,10 @@ layout("/layouts/platform.html"){
<el-table-column prop="userState" label="在职状态" sortable width="120"></el-table-column>
<el-table-column prop="personType" label="人员类型" sortable width="120"></el-table-column>
<el-table-column prop="arrivalAtSchoolDate" label="来校年月" sortable width="120"></el-table-column>
<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
<!--<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
<el-table-column prop="position" label="职务" sortable width="120" show-overflow-tooltip></el-table-column>
<el-table-column prop="education" label="学历" show-overflow-tooltip sortable width="120"></el-table-column>
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>
<el-table-column prop="academicDegree" label="学位" show-overflow-tooltip sortable width="120"></el-table-column>-->
<el-table-column prop="unitName" label="单位" show-overflow-tooltip sortable width="120"></el-table-column>
<el-table-column prop="unitId" label="单位编码" sortable width="120"></el-table-column>
<el-table-column prop="political" label="政治面貌" sortable></el-table-column>
@@ -120,9 +120,9 @@ layout("/layouts/platform.html"){
</div>
</el-timeline-item>
</el-timeline>
<span slot="footer" class="dialog-footer" v-loading="updateLoading">
<span slot="footer" class="dialog-footer">
<el-button @click="updateDialog = false" :disabled="updateLoading">取 消</el-button>
<el-button type="primary" @click="execUpdate" :disabled="updateLoading">确 定</el-button>
<el-button type="primary" @click="execUpdate" :disabled="updateLoading" :loading="updateLoading">确 定</el-button>
</span>
</el-dialog>
</div>
@@ -239,6 +239,12 @@ const basicForm = {
</template>
</el-table-column>
<el-table-column label="手机号" prop="courseInstructorMobile">
<template v-slot="{row}">
<el-input size="small" v-model="row.courseInstructorMobile" placeholder="请输入手机号"></el-input>
</template>
</el-table-column>
<el-table-column label="分类标识" prop="assort">
<template v-slot="{row}">
<el-input size="small" v-model="row.assort" placeholder="请输入分类标识"></el-input>
@@ -328,7 +334,7 @@ const basicForm = {
formData: {
notice: false,
courseList: [
{ orderNum: 1, courseName: "", courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false },
{ orderNum: 1, courseName: "", courseInstructorMobile: "", courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false },
],
conditionStructure: {
method: "AND",
@@ -462,7 +468,7 @@ const basicForm = {
this.formData.courseList = this.formData.courseList.sort((a, b) => a.orderNum - b.orderNum)
},
addCourse() {
this.formData.courseList.push({ courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false })
this.formData.courseList.push({ courseInstructorMobile: "", courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false })
},
async historicalActChange(val) {
const resp = await this.$axios.post("/platform/trainSignUp/manage/findOne", {id: val})
@@ -572,6 +578,10 @@ const basicForm = {
this.$message.warning("第" + (i + 1) + "行信息填写有误,请核查")
return true
}
if (v.courseInstructorMobile && !/^1[3-9]\d{9}$/.test(v.courseInstructorMobile)) {
this.$message.warning("第" + (i + 1) + "行手机号格式填写有误,请核查")
return true
}
if (v.isMobileSign === true && v.signType === 3 && (v.courseLocationCoordinates === undefined || v.courseLocationCoordinates.length < 2)) {
this.$message.warning("第" + (i + 1) + "行地点坐标填写有误,请核查")
return true
@@ -61,7 +61,7 @@ layout("/layouts/platform.html"){
</el-table-column>
<el-table-column label="操作" width="150px">
<template v-slot="{row}">
<el-button @click="handleUser(row.userId)" size="mini" type="danger" v-if="!row.isDisabled">拉黑</el-button>
<el-button @click="handleUser(row.userId)" size="mini" type="danger" v-if="!row.isDisabled">冻结</el-button>
<el-button @click="handleUser(row.userId)" size="mini" type="success" v-if="row.isDisabled">解封</el-button>
</template>
</el-table-column>
@@ -18,9 +18,9 @@ layout("/layouts/platform.html"){
value-format="yyyy">
</el-date-picker>
</search-item>
<search-item label="所属季度">
<search-item label="分配项目">
<dict-select clearable code="OUTLAY_QUARTERLY"
placeholder="请选择所属季度"
placeholder="请选择分配项目"
v-model="pageForm.quarterly"></dict-select>
</search-item>
<search-item label="所属工会">
@@ -42,10 +42,13 @@ layout("/layouts/platform.html"){
<table-tool label="预算分配">
<el-button @click="showBatchAllocateDialog" size="small" type="primary" :loading="formLoading">一键分配
</el-button>
<el-button @click="doAllocateRecord" size="small" type="primary" :loading="formLoading">季度记录生成
<el-button @click="showAwardAllocateDialog" size="small" type="primary" :loading="formLoading">
新增评优奖励
</el-button>
<el-button @click="doAllocateRecord" size="small" type="primary" :loading="formLoading">分配记录生成
</el-button>
<el-button @click="deleteAllocateRecord" size="small" type="danger" :loading="formLoading">重置季度记录
<el-button @click="deleteAllocateRecord" size="small" type="danger" :loading="formLoading">重置分配记录
</el-button>
</table-tool>
<el-table :data="tableData" style="width: 100%" row-key="id"
@@ -118,17 +121,15 @@ layout("/layouts/platform.html"){
</el-form-item>
<el-form-item label="上传文件">
<el-upload
name="file"
class="upload-demo"
ref="importUploadRef"
:limit="1"
action="/platform/outlay/outlayManage/unionAllocate/readImportExcel"
:on-success="onImportSuccess"
:on-remove="onImportRemove"
:before-upload="beforeImportUpload"
:file-list="importFileList"
drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将Excel文件拖到此处,或<em>点击上传</em></div>
:file-list="importFileList">
<el-button size="small" type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item label="导入预览" v-if="batchAllocateForm.importPreviewList.length > 0">
@@ -152,6 +153,41 @@ layout("/layouts/platform.html"){
<el-button type="primary" @click="doBatchAllocate" :loading="formLoading">确 定</el-button>
</span>
</el-dialog>
<el-dialog title="新增评优奖励" :visible.sync="awardAllocateDialogVisible" width="520px">
<el-form :model="awardAllocateForm" label-width="120px">
<el-form-item label="年度">
<el-date-picker
placeholder="选择年度"
style="width: 100%"
type="year"
v-model="awardAllocateForm.year"
:clearable="false"
value-format="yyyy">
</el-date-picker>
</el-form-item>
<el-form-item label="所属工会">
<el-select placeholder="请选择所属工会" v-model="awardAllocateForm.unionId"
style="width: 100%;"
clearable
filterable>
<el-option v-for="item in unionList"
:label="item.name"
:key="item.id"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="评优奖励金额">
<el-input-number v-model="awardAllocateForm.allocateMoney" :min="0" :precision="2"
style="width: 100%" placeholder="请输入评优奖励金额">
</el-input-number>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeAwardAllocateDialog">取 消</el-button>
<el-button type="primary" @click="doAddAwardAllocate" :loading="formLoading">确 定</el-button>
</span>
</el-dialog>
</template>
</guava>
</div>
@@ -170,48 +206,62 @@ layout("/layouts/platform.html"){
unionList: [],
tableColumns: [
{prop: 'year', label: '年度'},
{prop: 'quarterly', label: '季度'},
{prop: 'quarterly', label: '分配项目'},
{prop: 'unionName', label: '工会名称'},
{prop: 'allocateHeadMoney', label: '分配前额度'},
{prop: 'allocateMoney', label: '分配额度'},
],
quarterlyList: [],
periodList: [],
batchAllocateDialogVisible: false,
batchAllocateForm: {
allocateMode: "uniform",
allocateMoney: 0,
importPreviewList: []
},
importFileList: []
importFileList: [],
awardAllocateDialogVisible: false,
awardAllocateForm: {
year: this.$moment().format("YYYY"),
unionId: "",
allocateMoney: 0
}
}
},
methods: {
/**
* 确认提示文案优先展示页面当前筛选季度
* 未选择季度时再回退到系统当前自然季度,避免提示文案与用户当前查看条件不一致。
* 确认提示文案优先展示页面当前筛选的分配项目名称
* 未选择分配项目时再回退到当前会费项目,避免提示文案与用户当前查看条件不一致。
*/
getPromptQuarter() {
return this.pageForm.quarterly || this.$moment().quarter()
getPromptProjectName() {
return this.getProjectName(this.pageForm.quarterly || this.getCurrentFeeProject())
},
/**
* 季度记录生成、重置记录都要按页面当前筛选的年度和季度执行。
* 这里统一封装请求参数,避免前后端再次出现“提示季度”和“实际执行季度”不一致的问题
* 分配记录生成、重置记录都要按页面当前筛选的年度和分配项目执行。
* quarterly 参数承载 OUTLAY_QUARTERLY 字典编码,例如 1-4月会费、5-8月会费、9-12月会费、评优奖励
*/
getCurrentQuarterParams() {
getCurrentProjectParams() {
return {
quarterly: this.pageForm.quarterly || this.$moment().quarter(),
quarterly: this.pageForm.quarterly || this.getCurrentFeeProject(),
year: this.pageForm.year
}
},
/**
* 生成、重置、一键分配都只允许操作当前自然季度
* 这里统一做前端入口校验,避免同类判断分散在多个按钮方法里难维护
* 生成、重置、一键分配都只允许操作当前会费项目
* 当前会费项目按月份划分:1-4月会费、5-8月会费、9-12月会费
*/
validateCurrentQuarterAction(actionName) {
const currentQuarter = this.$moment().quarter()
const selectedQuarter = Number(this.getCurrentQuarterParams().quarterly)
if (selectedQuarter !== currentQuarter) {
this.$message.warning('当前仅允许操作第' + currentQuarter + '季度' + actionName + ',请切换后再操作')
getCurrentFeeProject() {
return Math.floor(this.$moment().month() / 4) + 1
},
getProjectName(code) {
const options = this.dict.type.OUTLAY_QUARTERLY || []
const project = options.find((item) => String(item.code || item.value || item.dictValue) === String(code))
return project ? (project.label || project.name || project.dictLabel || code) : code
},
validateCurrentProjectAction(actionName) {
const currentProject = this.getCurrentFeeProject()
const selectedProject = Number(this.getCurrentProjectParams().quarterly)
if (selectedProject !== currentProject) {
this.$message.warning('当前仅允许操作【' + this.getProjectName(currentProject) + '】' + actionName + ',请切换后再操作')
return false
}
return true
@@ -237,7 +287,7 @@ layout("/layouts/platform.html"){
})
},
deleteAllocateRecord() {
if (!this.validateCurrentQuarterAction('记录重置')) {
if (!this.validateCurrentProjectAction('记录重置')) {
return
}
// 重置动作以当前列表是否已有记录为前置条件,避免用户在空列表场景下误操作。
@@ -245,13 +295,13 @@ layout("/layouts/platform.html"){
this.$message.warning('当前列表无可重置记录')
return
}
this.$confirm('确定要重置【' + this.getPromptQuarter() + '季度】的预算记录吗?', '提示', {
this.$confirm('确定要重置【' + this.getPromptProjectName() + '】的预算记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.formLoading = true
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/deleteAllocateRecord", this.getCurrentQuarterParams()).then((resp) => {
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/deleteAllocateRecord", this.getCurrentProjectParams()).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.doSearch()
@@ -262,16 +312,16 @@ layout("/layouts/platform.html"){
})
},
doAllocateRecord() {
if (!this.validateCurrentQuarterAction('记录生成')) {
if (!this.validateCurrentProjectAction('记录生成')) {
return
}
this.$confirm('确定要生成【' + this.getPromptQuarter() + '季度】的预算记录吗?', '提示', {
this.$confirm('确定要生成【' + this.getPromptProjectName() + '】的预算记录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.formLoading = true
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAllocateRecord", this.getCurrentQuarterParams()).then((resp) => {
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAllocateRecord", this.getCurrentProjectParams()).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.doSearch()
@@ -282,14 +332,14 @@ layout("/layouts/platform.html"){
})
},
showBatchAllocateDialog() {
if (!this.validateCurrentQuarterAction('一键分配')) {
if (!this.validateCurrentProjectAction('一键分配')) {
return
}
if (this.tableData.length === 0) {
this.$message.warning('当前没有可分配的工会记录,请先生成季度记录')
this.$message.warning('当前没有可分配的工会记录,请先生成分配记录')
return
}
const currentParams = this.getCurrentQuarterParams()
const currentParams = this.getCurrentProjectParams()
const openDialog = () => {
this.resetBatchAllocateForm()
this.batchAllocateDialogVisible = true
@@ -302,7 +352,7 @@ layout("/layouts/platform.html"){
return
}
if (resp.data) {
this.$confirm('温馨提示:当前季度已分配过额度,再次分配将覆盖本季度原有分配结果,是否继续?', '温馨提示', {
this.$confirm('温馨提示:当前分配项目已分配过额度,再次分配将覆盖本项目原有分配结果,是否继续?', '温馨提示', {
confirmButtonText: '继续',
cancelButtonText: '取消',
type: 'warning'
@@ -323,6 +373,46 @@ layout("/layouts/platform.html"){
}
this.importFileList = []
},
showAwardAllocateDialog() {
this.$set(this.awardAllocateForm, "year", this.pageForm.year)
this.$set(this.awardAllocateForm, "unionId", this.pageForm.unionId || "")
this.$set(this.awardAllocateForm, "allocateMoney", 0)
this.$set(this, "awardAllocateDialogVisible", true)
},
closeAwardAllocateDialog() {
this.$set(this, "awardAllocateDialogVisible", false)
},
doAddAwardAllocate() {
if (!this.awardAllocateForm.year) {
this.$message.warning("请选择年度")
return
}
if (!this.awardAllocateForm.unionId) {
this.$message.warning("请选择所属工会")
return
}
if (!this.awardAllocateForm.allocateMoney || this.awardAllocateForm.allocateMoney <= 0) {
this.$message.warning("请输入有效的评优奖励金额")
return
}
this.formLoading = true
this.$axios.post("/platform/outlay/outlayManage/unionAllocate/doAddAwardAllocate", {
year: this.awardAllocateForm.year,
unionId: this.awardAllocateForm.unionId,
allocateMoney: this.awardAllocateForm.allocateMoney
}).then((resp) => {
if (resp.code === 0) {
this.$message.success(resp.msg)
this.closeAwardAllocateDialog()
this.$set(this.pageForm, "year", this.awardAllocateForm.year)
this.$set(this.pageForm, "quarterly", "4")
this.$set(this.pageForm, "unionId", this.awardAllocateForm.unionId)
this.doSearch()
}
}).finally(() => {
this.formLoading = false
})
},
downloadImportTemplate() {
this.$downLoad("/platform/outlay/outlayManage/unionAllocate/downloadImportTemplate")
},
@@ -349,7 +439,7 @@ layout("/layouts/platform.html"){
this.$set(this.batchAllocateForm, "importPreviewList", [])
},
doBatchAllocate() {
const currentParams = this.getCurrentQuarterParams()
const currentParams = this.getCurrentProjectParams()
if (this.batchAllocateForm.allocateMode === "uniform") {
if (!this.batchAllocateForm.allocateMoney || this.batchAllocateForm.allocateMoney <= 0) {
this.$message.warning('请输入有效的分配额度')
@@ -401,8 +491,8 @@ layout("/layouts/platform.html"){
this.unionList = data
})
this.$businessTool.getDictOptions("OUTLAY_QUARTERLY").then((data) => {
let quarter = this.$moment().quarter();
this.$set(this.pageForm, "quarterly", data[quarter - 1].code)
let project = this.getCurrentFeeProject();
this.$set(this.pageForm, "quarterly", data[project - 1].code)
this.pageData()
})
@@ -0,0 +1,163 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div class="platform" id="app" v-cloak>
<guava ref="guava">
<template>
<el-card shadow="never">
<search @search="doSearch">
<search-item label="年度">
<el-date-picker
@change="doSearch"
placeholder="选择年度"
style="width: 100%" type="year"
v-model="pageForm.year"
:clearable="false"
value-format="yyyy">
</el-date-picker>
</search-item>
<search-item label="所属工会" v-if="$auth.hasRoleOr(['SYSADMIN', 'SCHOOL_UNION_ADMIN'])">
<el-select placeholder="请选择所属工会" v-model="pageForm.unionId"
style="width: 100%;"
clearable
@change="doSearch"
filterable>
<el-option v-for="item in unions"
:label="item.name"
:key="item.id"
:value="item.id"></el-option>
</el-select>
</search-item>
</search>
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="经费收支使用情况表">
<el-button size="mini" type="primary" @click="doExport">导出</el-button>
</table-tool>
<el-table :data="tableData" style="width: 100%" row-key="unionId"
v-loading="tableLoading" :size="tableSize" class="vi-table"
border>
<el-table-column
show-overflow-tooltip
align="center"
header-align="center"
label="单位"
prop="unionName"
min-width="140"></el-table-column>
<el-table-column
align="center"
header-align="center"
label="年初数"
prop="beginMoney"
min-width="120">
<template v-slot="{row}">
{{formatMoney(row.beginMoney)}}
</template>
</el-table-column>
<el-table-column align="center" header-align="center" :label="pageForm.year + '年会费收入'">
<el-table-column
align="center"
header-align="center"
label="1-4月会费"
prop="feeJanApr"
min-width="120">
<template v-slot="{row}">
{{formatMoney(row.feeJanApr)}}
</template>
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="5-8月会费"
prop="feeMayAug"
min-width="120">
<template v-slot="{row}">
{{formatMoney(row.feeMayAug)}}
</template>
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="9-12月会费"
prop="feeSepDec"
min-width="120">
<template v-slot="{row}">
{{formatMoney(row.feeSepDec)}}
</template>
</el-table-column>
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="评优奖励"
prop="awardMoney"
min-width="120">
<template v-slot="{row}">
{{formatMoney(row.awardMoney)}}
</template>
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="1-12月支出"
prop="usedMoney"
min-width="120">
<template v-slot="{row}">
{{formatMoney(row.usedMoney)}}
</template>
</el-table-column>
<el-table-column
align="center"
header-align="center"
label="经费余额"
prop="remainMoney"
min-width="120">
<template v-slot="{row}">
{{formatMoney(row.remainMoney)}}
</template>
</el-table-column>
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
</template>
</guava>
</div>
<script nonce="${cspNonce!}">
const vue = new Vue({
el: '#app',
store,
mixins: [initTableMixins],
data() {
return {
pageForm: {
year: this.$moment().format("YYYY"),
unionId: ""
},
unions: []
}
},
methods: {
formatMoney(value) {
return Number(value || 0).toFixed(2)
},
doExport() {
const unionId = this.pageForm.unionId || ""
window.open(loc() + "/doExport?year=" + this.pageForm.year + "&unionId=" + unionId)
}
},
created() {
this.$businessTool.listUnion().then((data) => {
this.unions = data
})
this.pageData()
}
})
</script>
<!--#
}
#-->
@@ -4,10 +4,10 @@ let OUTLAY_MANAGE_UNION_QUARTERLY_ALLOCATE = {
`
<div>
<template>
<table-tool label="季度分配记录"></table-tool>
<table-tool label="分配记录"></table-tool>
<el-table :data="tableData" style="width: 100%" row-key="id" class="vi-table">
<el-table-column type="index" label="序号" width="80px"></el-table-column>
<el-table-column label="季度" prop="quarterly">
<el-table-column label="分配项目" prop="quarterly">
<template v-slot="{row}">
<dict-tag :options="dict.type.OUTLAY_QUARTERLY"
:value="row.quarterly"></dict-tag>
@@ -175,9 +175,9 @@ const apply = {
<el-col :span="24">
<el-form-item label="批量预约">
<div style="display: flex; align-items: flex-start; column-gap: 12px; flex-wrap: wrap; line-height: 1.7;">
<el-checkbox v-model="yearlyReserve">预约本后续每周同一时段</el-checkbox>
<el-checkbox v-model="yearlyReserve">预约本后续每周同一时段</el-checkbox>
<span style="color: #909399;">
例如先选某个周一 09:00-11:00勾选后会自动预约本剩余所有周一的这个时段
例如先选某个周一 09:00-11:00勾选后会自动预约本剩余所有周一的这个时段
</span>
</div>
<div v-if="yearlyReserve" style="margin-top: 10px; max-width: 320px;">
@@ -222,6 +222,8 @@ const apply = {
filterHolidays: false,
holidayList: [],
notApplyTimeList: [],
termStartDate: '',
termEndDate: '',
},
availabilityData: {
date: '',
@@ -342,7 +344,10 @@ const apply = {
if (!this.formData.reserveStartTime) {
return false
}
return this.$moment(time).format('YYYY-MM-DD') < this.formData.reserveStartTime.slice(0, 10)
const targetDay = this.$moment(time).format('YYYY-MM-DD')
const startDay = this.formData.reserveStartTime.slice(0, 10)
const monthEndDay = this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')
return targetDay < startDay || targetDay > monthEndDay
},
}
},
@@ -395,10 +400,10 @@ const apply = {
return ''
}
if (!this.formData.reserveStartTime || !this.formData.reserveEndTime) {
return '请先选择开始和结束时间后,再批量预约本同星期时段'
return '请先选择开始和结束时间后,再批量预约本同星期时段'
}
if (!this.yearlyReserveDates.length) {
return '当前时间段无法生成本批量预约日期'
return '当前时间段无法生成本批量预约日期'
}
return '将从 ' + this.yearlyReserveDates[0] + ' 开始,自动预约到 ' + this.yearlyReserveDates[this.yearlyReserveDates.length - 1] + ',共 ' + this.yearlyReserveDates.length + ' 个时段'
},
@@ -496,6 +501,10 @@ const apply = {
}
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate < this.formData.reserveStartTime.slice(0, 10)) {
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
return
}
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > defaultDate) {
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
}
},
getInitialScheduleDate() {
@@ -513,6 +522,8 @@ const apply = {
filterHolidays: !!this.row.filterHolidays,
holidayList: [],
notApplyTimeList: Array.isArray(this.row.notApplyTimeList) ? this.row.notApplyTimeList : [],
termStartDate: this.row.termStartDate || '',
termEndDate: this.row.termEndDate || '',
}
try {
const res = await this.$axios.post('/platform/siteCug/apply/timeLimitConfig', {
@@ -523,6 +534,8 @@ const apply = {
filterHolidays: !!res.data.filterHolidays,
holidayList: Array.isArray(res.data.holidayList) ? res.data.holidayList : [],
notApplyTimeList: Array.isArray(res.data.notApplyTimeList) ? res.data.notApplyTimeList : [],
termStartDate: res.data.termStartDate || '',
termEndDate: res.data.termEndDate || '',
}
} else {
this.timeLimitConfig = fallback
@@ -599,6 +612,9 @@ const apply = {
this.$nextTick(() => {
this.$refs.formRef?.clearValidate(['applyUnionName', 'clubId'])
})
this.pickerRefreshKey += 1
this.scheduleDate = this.getInitialScheduleDate()
await this.queryAvailability(this.scheduleDate)
},
async loadManagedClubs() {
try {
@@ -671,6 +687,11 @@ const apply = {
if (currentDay.day() === 0 || currentDay.day() === 6) {
return true
}
if (this.formData.reserveType === 'union' && this.timeLimitConfig.termStartDate && this.timeLimitConfig.termEndDate) {
if (currentDay.isBefore(this.timeLimitConfig.termStartDate) || currentDay.isAfter(this.timeLimitConfig.termEndDate)) {
return true
}
}
return this.timeLimitConfig.filterHolidays && this.timeLimitConfig.holidayList.includes(day)
},
normalizeTime(timeStr) {
@@ -1006,12 +1027,16 @@ const apply = {
this.$message.warning('批量预约截止日期不能早于开始日期')
return false
}
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')) {
this.$message.warning('批量预约截止日期不能超过预约开始时间所在月份')
return false
}
if (!this.yearlyReserveDates.length) {
this.$message.warning('当前选择的时间段在截止日期内无法生成可批量预约的日期')
return false
}
if (!this.yearlyReserveDates.length) {
this.$message.warning('当前选择的时间段无法生成本批量预约日期')
this.$message.warning('当前选择的时间段无法生成本批量预约日期')
return false
}
return true
@@ -1024,7 +1049,7 @@ const apply = {
if (!this.yearlyReserve) {
return baseText + ',是否确定提交预约?'
}
return baseText + '。系统将继续预约本后续 ' + this.yearlyReserveDates.length + ' 个同星期时段,是否确定提交?'
return baseText + '。系统将继续预约本后续 ' + this.yearlyReserveDates.length + ' 个同星期时段,是否确定提交?'
},
validateYearlyReserve() {
if (!this.yearlyReserve) {
@@ -1038,6 +1063,10 @@ const apply = {
this.$message.warning('批量预约截止日期不能早于开始日期')
return false
}
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')) {
this.$message.warning('批量预约截止日期不能超过预约开始时间所在月份')
return false
}
if (!this.yearlyReserveDates.length) {
this.$message.warning('当前选择的时间段在截止日期内无法生成可批量预约的日期')
return false
@@ -81,7 +81,7 @@
<el-tab-pane label="设置场地" name="siteSetting">
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-col :span="8">
<el-form-item prop="state" label="开启状态">
<el-radio-group v-model="formData.state" size="medium">
<el-radio-button :label="true">开启</el-radio-button>
@@ -89,7 +89,7 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="8">
<el-form-item prop="sexLimit" label="性别限制">
<el-radio-group v-model="formData.sexLimit" size="medium">
<el-radio-button :label="0">不限制</el-radio-button>
@@ -98,10 +98,23 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="本学期时间">
<el-date-picker
v-model="formData.termDateRange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
style="width: 100%">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="12">
<el-col :span="8">
<el-form-item prop="reserveTimeType" label="预约时间段类型">
<el-radio-group v-model="formData.reserveTimeType" @change="handleReserveTimeTypeChange" size="medium">
<el-radio-button :label="1">分段预约</el-radio-button>
@@ -109,7 +122,7 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="8">
<el-form-item prop="filterHolidays" label="排除节假日">
<el-radio-group v-model="formData.filterHolidays" size="medium">
<el-radio-button :label="true"></el-radio-button>
@@ -117,7 +130,7 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="8">
<el-form-item label="禁用时间">
<el-button type="primary" @click="openSetUpTime" size="small">点击设置禁用时间</el-button>
<span style="color: #c64120">您已设置{{ formData.notApplyTimeList ? formData.notApplyTimeList.length : 0 }}个禁用时间</span>
@@ -125,6 +138,33 @@
</el-col>
</el-row>
<el-row :gutter="20" type="flex">
<el-col :span="8">
<el-form-item prop="unionYearReserveLimit" label="分工会每年预约次数">
<el-input-number
v-model="formData.unionYearReserveLimit"
:min="1"
:step="1"
:precision="0"
controls-position="right"
style="width: 160px">
</el-input-number>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item prop="clubWeekReserveLimit" label="社团每周预约次数">
<el-input-number
v-model="formData.clubWeekReserveLimit"
:min="1"
:step="1"
:precision="0"
controls-position="right"
style="width: 160px">
</el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-divider content-position="left">场次信息</el-divider>
<div v-if="formData.reserveTimeType === 1">
@@ -325,6 +365,9 @@
formData: {
state: true,
sexLimit: 0,
termDateRange: [],
unionYearReserveLimit: 2,
clubWeekReserveLimit: 2,
filterHolidays: false,
reserveTimeType: 1,
openHours: [{ startTime: '', endTime: '', timeUnit: 30 }],
@@ -344,6 +387,8 @@
maxNum: [{required: true, message: '必填', trigger: ['blur', 'change']}],
typeId: [{required: true, message: '必填', trigger: ['blur', 'change']}],
sexLimit: [{required: true, message: '必填', trigger: ['blur', 'change']}],
unionYearReserveLimit: [{required: true, type: 'number', min: 1, message: '必填且必须大于0', trigger: ['blur', 'change']}],
clubWeekReserveLimit: [{required: true, type: 'number', min: 1, message: '必填且必须大于0', trigger: ['blur', 'change']}],
filterHolidays: [{required: true, message: '必填', trigger: ['blur', 'change']}],
state: [{required: true, message: '必填', trigger: ['blur', 'change']}],
reserveTimeType: [{required: true, message: '必填', trigger: ['blur', 'change']}],
@@ -408,6 +453,14 @@
} else {
submitData.openHours = [clone(this.fullDayOpenHourCache || { startTime: '', endTime: '', timeUnit: 60 })]
}
if (Array.isArray(submitData.termDateRange) && submitData.termDateRange.length === 2) {
submitData.termStartDate = submitData.termDateRange[0]
submitData.termEndDate = submitData.termDateRange[1]
} else {
submitData.termStartDate = ''
submitData.termEndDate = ''
}
delete submitData.termDateRange
return submitData
},
initOpenHoursCache() {
@@ -654,11 +707,19 @@
if (!this.formData.fullDayOpenHour) {
this.$set(this.formData, 'fullDayOpenHour', { startTime: '', endTime: '', timeUnit: 30 })
}
if (this.formData.termStartDate && this.formData.termEndDate) {
this.$set(this.formData, 'termDateRange', [this.formData.termStartDate, this.formData.termEndDate])
} else {
this.$set(this.formData, 'termDateRange', [])
}
this.initOpenHoursCache()
} else {
this.formData = {
state: true,
sexLimit: 0,
termDateRange: [],
unionYearReserveLimit: 2,
clubWeekReserveLimit: 2,
filterHolidays: false,
reserveTimeType: 1,
openHours: [{ startTime: '', endTime: '', timeUnit: 30 }],
@@ -698,6 +759,11 @@
if (!this.formData.fullDayOpenHour) {
this.$set(this.formData, 'fullDayOpenHour', { startTime: '', endTime: '', timeUnit: 30 })
}
if (this.formData.termStartDate && this.formData.termEndDate) {
this.$set(this.formData, 'termDateRange', [this.formData.termStartDate, this.formData.termEndDate])
} else {
this.$set(this.formData, 'termDateRange', [])
}
this.initOpenHoursCache()
}
if (!stayOnPage) {
@@ -9,9 +9,7 @@ layout("/layouts/platform.html"){
}
.record-batch-empty {
display: inline-block;
width: 16px;
height: 16px;
display: none;
}
.record-batch-child-row {
@@ -31,6 +29,13 @@ layout("/layouts/platform.html"){
height: 1px;
background: #c8d3df;
}
.record-site-name-cell {
display: inline-flex;
align-items: center;
gap: 6px;
max-width: 100%;
}
</style>
<div id="app" v-cloak>
@@ -113,25 +118,16 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool label="申请列表">
<el-button v-if="$auth.hasRole('SYSADMIN')" type="primary" size="small" @click="openBatchOccupyDialog">占用</el-button>
<el-button type="primary" size="small" @click="doExport">导出表格</el-button>
</table-tool>
<el-table
:data="tableData"
:row-class-name="tableRowClassName"
@selection-change="handleSelectionChange"
@sort-change="pageOrder"
style="width: 100%">
<el-table-column label="" width="54" align="center" header-align="center">
<template v-slot="{ row }">
<el-button
v-if="row._hasFoldChildren"
class="record-batch-toggle"
type="text"
@click="toggleBatchGroup(row)">
<i :class="row._expanded ? 'el-icon-caret-bottom' : 'el-icon-caret-right'"></i>
</el-button>
<span v-else class="record-batch-empty"></span>
</template>
</el-table-column>
<el-table-column v-if="$auth.hasRole('SYSADMIN')" type="selection" width="48" :selectable="canSelectOccupy"></el-table-column>
<el-table-column type="index" width="50" label="序号" :index="indexMethod"></el-table-column>
<el-table-column
v-for="column in tableColumns"
@@ -144,8 +140,18 @@ layout("/layouts/platform.html"){
header-align="center"
show-overflow-tooltip>
<template v-slot="{ row }" v-if="column.prop === 'siteName'">
<span v-if="row._isBatchChild" class="record-batch-child-label">{{ row.siteName }}</span>
<span v-else>{{ row.siteName }}</span>
<span class="record-site-name-cell">
<el-button
v-if="row._hasFoldChildren"
class="record-batch-toggle"
type="text"
@click="toggleBatchGroup(row)">
<i :class="row._expanded ? 'el-icon-caret-bottom' : 'el-icon-caret-right'"></i>
</el-button>
<span v-else class="record-batch-empty"></span>
<span v-if="row._isBatchChild" class="record-batch-child-label">{{ row.siteName }}</span>
<span v-else>{{ row.siteName }}</span>
</span>
</template>
<template v-slot="{ row }" v-else-if="column.prop === 'reserveTargetName'">
<span>{{ row.reserveType === 'club' ? (row.clubName || '-') : (row.applyUnionName || '-') }}</span>
@@ -154,7 +160,7 @@ layout("/layouts/platform.html"){
<span>{{ normalizeBatchFlag(row) ? '是' : '否' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="180">
<el-table-column label="操作" fixed="right" width="150">
<template v-slot="{ row }">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
@@ -163,6 +169,32 @@ layout("/layouts/platform.html"){
</el-table>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
<el-dialog title="占用预约" :visible.sync="occupyDialogVisible" width="520px" append-to-body :close-on-click-modal="false">
<el-form label-width="90px">
<el-form-item label="预约信息">
<div v-if="occupyForm.batch">已选择 {{ occupyForm.count }} 条预约</div>
<template v-else>
<div>{{ occupyForm.siteName || '-' }}</div>
<div>{{ occupyForm.applyUserName || '-' }}{{ occupyForm.reserveStartTime }} 至 {{ occupyForm.reserveEndTime }}</div>
</template>
</el-form-item>
<el-form-item label="通知内容" required>
<el-input
type="textarea"
:rows="6"
maxlength="1000"
show-word-limit
v-model="occupyForm.message"
placeholder="请输入发送给预约人的通知内容">
</el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="closeOccupyDialog">取消</el-button>
<el-button type="primary" :loading="occupySubmitting" @click="submitOccupy">确定占用</el-button>
</span>
</el-dialog>
</template>
<template #edit>
@@ -195,6 +227,20 @@ layout("/layouts/platform.html"){
siteOptions: [],
rawTableData: [],
expandedBatchKeys: {},
selectedOccupyRows: [],
occupyDialogVisible: false,
occupySubmitting: false,
occupyForm: {
id: '',
ids: '',
batch: false,
count: 0,
siteName: '',
applyUserName: '',
reserveStartTime: '',
reserveEndTime: '',
message: '',
},
tableColumns: [
{ prop: 'siteName', label: '场地名称', sortable: 'custom' },
{ prop: 'applyUserName', label: '预约人', sortable: 'custom' },
@@ -267,6 +313,99 @@ layout("/layouts/platform.html"){
this.$refs.infoRef.onOpen(row)
})
},
canSelectOccupy(row) {
return this.canOccupy(row)
},
handleSelectionChange(rows) {
this.$set(this, 'selectedOccupyRows', rows || [])
},
canOccupy(row) {
if (!row || !row.reserveStartTime) {
return false
}
const currentUserId = (this.$store.state.user && this.$store.state.user.id) || ''
if (row.occupyUserId && row.occupyUserId !== currentUserId) {
return false
}
return Number(row.instanceState) === 20 && this.$moment(row.reserveStartTime).isAfter(this.$moment())
},
buildOccupyMessage(row) {
return '您预约的' + (row.siteName || '场地') + '' + row.reserveStartTime + ' 至 ' + row.reserveEndTime + ')因场地安排需要被占用,请您知悉并重新协调预约时间。'
},
openOccupyDialog(row) {
const occupyForm = {
id: row.id || '',
ids: row.id || '',
batch: false,
count: 1,
siteName: row.siteName || '',
applyUserName: row.applyUserName || '',
reserveStartTime: row.reserveStartTime || '',
reserveEndTime: row.reserveEndTime || '',
message: row.occupyMessage || this.buildOccupyMessage(row),
}
Object.keys(occupyForm).forEach(key => {
this.$set(this.occupyForm, key, occupyForm[key])
})
this.$set(this, 'occupyDialogVisible', true)
},
openBatchOccupyDialog() {
if (!this.selectedOccupyRows || this.selectedOccupyRows.length === 0) {
this.$message.warning('请选择需要占用的预约')
return
}
const ids = this.selectedOccupyRows.map(row => row.id).filter(id => !!id)
if (ids.length === 0) {
this.$message.warning('请选择需要占用的预约')
return
}
const occupyForm = {
id: '',
ids: ids.join(','),
batch: true,
count: ids.length,
siteName: '',
applyUserName: '',
reserveStartTime: '',
reserveEndTime: '',
message: '您预约的场地因场地安排需要被占用,请您知悉并重新协调预约时间。',
}
Object.keys(occupyForm).forEach(key => {
this.$set(this.occupyForm, key, occupyForm[key])
})
this.$set(this, 'occupyDialogVisible', true)
},
closeOccupyDialog() {
this.$set(this, 'occupyDialogVisible', false)
},
async submitOccupy() {
if (!this.occupyForm.message || !this.occupyForm.message.trim()) {
this.$message.warning('请填写通知内容')
return
}
this.$set(this, 'occupySubmitting', true)
try {
const url = this.occupyForm.batch ? '/platform/siteCug/record/occupyBatch' : '/platform/siteCug/record/occupy'
const params = {
message: this.occupyForm.message,
}
if (this.occupyForm.batch) {
this.$set(params, 'ids', this.occupyForm.ids)
} else {
this.$set(params, 'id', this.occupyForm.id)
}
const res = await this.$axios.post(url, params)
if (res.code === 0) {
this.$message.success(res.msg || '占用成功')
this.closeOccupyDialog()
window.location.href = '/platform/siteCug/apply'
} else {
this.$message.warning(res.msg || '占用失败')
}
} finally {
this.$set(this, 'occupySubmitting', false)
}
},
onDelete(id) {
this.$confirm('您确定要删除吗?', '提示', {
confirmButtonText: '确定',
@@ -299,6 +438,7 @@ layout("/layouts/platform.html"){
if (res.code === 0) {
this.rawTableData = Array.isArray(res.data.list) ? res.data.list : []
this.tableData = this.buildTableData(this.rawTableData)
this.$set(this, 'selectedOccupyRows', [])
this.pageForm.totalCount = res.data.totalCount
}
})
@@ -288,7 +288,7 @@ layout("/layouts/platform.html"){
return
}
const message = this.formData.yearlyBatch
? ('该记录属于“预约本”批量预约,提交后将一并审核同批次的 ' + (this.formData.batchAuditCount || 0) + ' 条预约记录,是否继续?')
? ('该记录属于“预约本”批量预约,提交后将一并审核同批次的 ' + (this.formData.batchAuditCount || 0) + ' 条预约记录,是否继续?')
: '您确定要提交吗?'
this.$confirm(message, '提示', {
confirmButtonText: '确定',
@@ -317,7 +317,7 @@ layout("/layouts/platform.html"){
return
}
const message = this.normalizeBatchFlag(row)
? ('该记录属于“预约本”批量预约,撤回后将一并撤回同批次的 ' + (row.batchAuditCount || row._batchCount || 0) + ' 条审核任务,是否继续?')
? ('该记录属于“预约本”批量预约,撤回后将一并撤回同批次的 ' + (row.batchAuditCount || row._batchCount || 0) + ' 条审核任务,是否继续?')
: '您确定要撤回吗?'
this.$confirm(message, '提示', {
confirmButtonText: '确定',
File diff suppressed because it is too large Load Diff
@@ -47,7 +47,7 @@ layout("/layouts/platform.html"){
<el-card shadow="never">
<table-tool label="申请列表">
<el-button type="primary" size="small" @click="exportSkr">导出收款人名册</el-button>
<!-- <el-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出</el-button>-->
<el-button @click="onExport" icon="el-icon-s-promotion" type="primary" size="small">导出表格</el-button>
</table-tool>
<el-table :data="tableData" @sort-change="pageOrder" style="width: 100%">
<el-table-column type="index" width="50px" label="序号" :index="indexMethod"></el-table-column>
@@ -89,7 +89,7 @@ layout("/layouts/platform.html"){
<el-table-column label="操作" fixed="right" width="350px">
<template slot-scope="{row}">
<el-button @click="onView(row)" size="mini" type="primary">查看</el-button>
<el-button v-if="isAdmin" @click="openEdit(row)" size="mini" type="primary">实际金额</el-button>
<el-button v-if="isAdmin && row.stateId == 3" @click="openEdit(row)" size="mini" type="primary">实际金额</el-button>
<el-button v-if="row.stateId == 3" @click="doPrint(row)" size="mini" type="primary">打印</el-button>
<el-button v-if="$auth.hasRole('SYSADMIN')" @click="onDelete(row.id)" size="mini" type="danger">删除</el-button>
</template>
@@ -8,25 +8,19 @@ const unionReimburseInfo = {
<el-tabs v-model="activeTabName" style="margin-top: 10px;">
<el-tab-pane label="申请基本信息" name="basic">
<el-descriptions :column="2" border class="flow-task-form">
<el-descriptions-item label="经费来源" :span="2">
<el-descriptions :column="3" border class="flow-task-form">
<el-descriptions-item label="经费来源" :span="3">
<dict-tag :options="dict.type.UNION_REIMBURSE_FUND_SOURCE"
:value="viewData.reimburseFundSource">
</dict-tag>
</el-descriptions-item>
<el-descriptions-item label="报销项目" :span="2">
<el-descriptions-item label="报销项目" :span="3">
<dict-tag :options="dict.type.UNION_REIMBURSE_PROJECT"
:value="viewData.reimburseProject">
</dict-tag>
</el-descriptions-item>
<el-descriptions-item label="支付方式">
<dict-tag :options="dict.type.UNION_REIMBURSE_PAYMENT_WAY"
:value="viewData.paymentWay">
</dict-tag>
</el-descriptions-item>
<el-descriptions-item label="工号">{{viewData.loginName}}</el-descriptions-item>
<el-descriptions-item label="经办人">{{viewData.userName}}</el-descriptions-item>
<el-descriptions-item label="单位">{{viewData.unitName}}</el-descriptions-item>
@@ -44,20 +38,45 @@ const unionReimburseInfo = {
<span>{{ viewData.mobile }}</span>
</el-descriptions-item>
<el-descriptions-item label="付款人" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<span>{{ viewData.payerName }}</span>
</el-descriptions-item>
<el-descriptions-item label="户名" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<span>{{ viewData.bankUserName }}</span>
</el-descriptions-item>
<el-descriptions-item label="开户行" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<span>{{ viewData.bankOfDeposit }}</span>
</el-descriptions-item>
<el-descriptions-item label="银行卡号" v-if="viewData.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">
<span>{{ viewData.bankCardNumber }}</span>
<el-descriptions-item label="支付信息" :span="3">
<el-table :data="paymentInfoRows" border empty-text="暂无支付信息" style="width: 100%">
<el-table-column label="支付方式" min-width="140">
<template slot-scope="scope">
<dict-tag :options="dict.type.UNION_REIMBURSE_PAYMENT_WAY"
:value="scope.row.paymentWay">
</dict-tag>
</template>
</el-table-column>
<el-table-column label="金额" min-width="120">
<template slot-scope="scope">
<span>{{ formatMoney(scope.row.money) }}</span>
</template>
</el-table-column>
<el-table-column label="付款人" min-width="160">
<template slot-scope="scope">
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.payerName }}</span>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="户名" min-width="160">
<template slot-scope="scope">
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.bankUserName }}</span>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="开户行" min-width="200">
<template slot-scope="scope">
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.bankOfDeposit }}</span>
<span v-else>无需填写</span>
</template>
</el-table-column>
<el-table-column label="银行卡号" min-width="200">
<template slot-scope="scope">
<span v-if="scope.row.paymentWay === 'UNION_REIMBURSE_PAYMENT_WAY_2'">{{ scope.row.bankCardNumber }}</span>
<span v-else>无需填写</span>
</template>
</el-table-column>
</el-table>
</el-descriptions-item>
<el-descriptions-item label="慰问对象" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
@@ -159,20 +178,20 @@ const unionReimburseInfo = {
<span>{{ viewData.condolenceRelationship }}</span>
</el-descriptions-item>
<el-descriptions-item label="参加随行人员" :span="2"
<el-descriptions-item label="参加随行人员" :span="3"
v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.participants }}</span>
</el-descriptions-item>
<el-descriptions-item label="报销事由" :span="2" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-descriptions-item label="报销事由" :span="3" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.paymentNotes }}</span>
</el-descriptions-item>
<el-descriptions-item label="备注" :span="2" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<el-descriptions-item label="备注" :span="3" v-if="viewData.reimburseProject === 'UNION_REIMBURSE_PROJECT_1'">
<span>{{ viewData.notes }}</span>
</el-descriptions-item>
<el-descriptions-item label="附件" :span="2">
<el-descriptions-item label="附件" :span="3">
<file-preview v-if="viewData.files && viewData.files.length > 0"
:files="viewData.files"
complete_result></file-preview>
@@ -285,7 +304,8 @@ const unionReimburseInfo = {
visible: false,
viewData: {
files: [],
invoiceDetails: []
invoiceDetails: [],
paymentDetails: []
},
typeName: '',
row: null
@@ -294,6 +314,9 @@ const unionReimburseInfo = {
computed: {
showInvoiceTab() {
return !!this.viewData.reimburseProject
},
paymentInfoRows() {
return this.viewData.paymentDetails || []
}
},
methods: {
@@ -317,7 +340,8 @@ const unionReimburseInfo = {
buildViewData(data) {
const viewData = Object.assign({
files: [],
invoiceDetails: []
invoiceDetails: [],
paymentDetails: []
}, data || {})
if (!Array.isArray(viewData.files)) {
viewData.files = []
@@ -325,8 +349,32 @@ const unionReimburseInfo = {
if (!Array.isArray(viewData.invoiceDetails)) {
viewData.invoiceDetails = []
}
const hasLegacyPayment = viewData.paymentWay || viewData.payer || viewData.bankUserName || viewData.bankCardNumber || viewData.bankOfDeposit
if (Array.isArray(viewData.paymentDetails) && viewData.paymentDetails.length > 0) {
viewData.paymentDetails = viewData.paymentDetails.map(item => this.buildPaymentDetail(item))
} else {
viewData.paymentDetails = hasLegacyPayment ? [this.buildPaymentDetail({
paymentWay: viewData.paymentWay,
money: viewData.money,
payerName: viewData.payerName,
bankUserName: viewData.bankUserName,
bankOfDeposit: viewData.bankOfDeposit,
bankCardNumber: viewData.bankCardNumber
})] : []
}
return viewData
},
buildPaymentDetail(detail) {
const currentDetail = detail || {}
return {
paymentWay: currentDetail.paymentWay || "",
money: currentDetail.money || "",
payerName: currentDetail.payerName || "",
bankUserName: currentDetail.bankUserName || "",
bankOfDeposit: currentDetail.bankOfDeposit || "",
bankCardNumber: currentDetail.bankCardNumber || ""
}
},
// 查看页金额统一保留两位小数,和申请页展示口径保持一致。
formatMoney(value) {
if (value === null || value === undefined || value === "") {
@@ -1,4 +1,4 @@
<!--#
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
@@ -46,6 +46,7 @@ layout("/layouts/platform_h5.html"){
<table-column label="校区">{{row.campus}}</table-column>
<table-column label="地点">{{row.courseLocation}}</table-column>
<table-column label="联系人">{{row.courseInstructor}}</table-column>
<table-column v-if="row.courseInstructorMobile" label="联系方式">{{row.courseInstructorMobile}}</table-column>
<table-column label="时间">
<span v-if="row.courseTimes && row.courseTimes.length === 1" class="primary-color" @click="onTime(row)">
{{ weekdayCNMap[$moment(row.courseTimes[0].courseDate).day()]
@@ -17,6 +17,8 @@ new Vue({
filterHolidays: false,
holidayList: [],
notApplyTimeList: [],
termStartDate: '',
termEndDate: '',
},
availabilityData: {
date: '',
@@ -140,7 +142,10 @@ new Vue({
return base.startOf('day').toDate()
},
yearlyReserveMaxDate() {
return this.$moment().add(2, 'year').endOf('year').toDate()
const base = this.formData.reserveStartTime
? this.$moment(this.formData.reserveStartTime)
: (this.scheduleDate ? this.$moment(this.scheduleDate, 'YYYY-MM-DD') : this.$moment())
return base.endOf('month').toDate()
},
yearlyReserveDates() {
if (!this.yearlyReserve || !this.formData.reserveStartTime || !this.formData.reserveEndTime || !this.formData.yearlyReserveEndDate) {
@@ -253,6 +258,10 @@ new Vue({
}
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate < this.formData.reserveStartTime.slice(0, 10)) {
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
return
}
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > defaultDate) {
this.$set(this.formData, 'yearlyReserveEndDate', defaultDate)
}
},
openReserveTypePicker() {
@@ -282,7 +291,6 @@ new Vue({
this.formData.applyUnionName = user.union ? user.union.name : ''
this.formData.clubId = ''
this.formData.clubName = ''
return
}
if (value === 'club') {
this.formData.applyUnionId = ''
@@ -291,6 +299,9 @@ new Vue({
this.formData.clubName = ''
await this.loadManagedClubs()
}
this.scheduleDate = this.getInitialScheduleDate()
this.schedulePickerDate = this.$moment(this.scheduleDate, 'YYYY-MM-DD').toDate()
await this.queryAvailability(this.scheduleDate)
},
async loadManagedClubs() {
try {
@@ -484,6 +495,20 @@ new Vue({
result.push('slot-block--closed')
return result
},
formatSlotLabel(block) {
const label = block && block.label ? block.label : ''
const match = label.match(/^(.+?)\s+(\d{2}:\d{2}(?::\d{2})?\s*-\s*\d{2}:\d{2}(?::\d{2})?)$/)
if (match) {
return {
name: match[1],
time: match[2],
}
}
return {
name: label,
time: '',
}
},
onAvailabilityBlockClick(block) {
if (!block || !block.key) {
return
@@ -710,6 +735,11 @@ new Vue({
if (currentDay.day() === 0 || currentDay.day() === 6) {
return true
}
if (this.formData.reserveType === 'union' && this.timeLimitConfig.termStartDate && this.timeLimitConfig.termEndDate) {
if (currentDay.isBefore(this.timeLimitConfig.termStartDate) || currentDay.isAfter(this.timeLimitConfig.termEndDate)) {
return true
}
}
return this.timeLimitConfig.filterHolidays && this.timeLimitConfig.holidayList.includes(day)
},
getDisabledRangesByDay(dayStr) {
@@ -838,6 +868,10 @@ new Vue({
this.$toast('批量预约截止日期不能早于开始日期')
return false
}
if (this.formData.reserveStartTime && this.formData.yearlyReserveEndDate > this.$moment(this.formData.reserveStartTime).endOf('month').format('YYYY-MM-DD')) {
this.$toast('批量预约截止日期不能超过预约开始时间所在月份')
return false
}
if (!this.yearlyReserveDates.length) {
this.$toast('当前截止日期内没有可批量预约的同星期时段')
return false
@@ -924,6 +958,8 @@ new Vue({
filterHolidays: !!this.row.filterHolidays,
holidayList: [],
notApplyTimeList: Array.isArray(this.row.notApplyTimeList) ? this.row.notApplyTimeList : [],
termStartDate: this.row.termStartDate || '',
termEndDate: this.row.termEndDate || '',
}
try {
const res = await this.$axios.post('/platform/siteCug/apply/timeLimitConfig', {
@@ -934,6 +970,8 @@ new Vue({
filterHolidays: !!res.data.filterHolidays,
holidayList: Array.isArray(res.data.holidayList) ? res.data.holidayList : [],
notApplyTimeList: Array.isArray(res.data.notApplyTimeList) ? res.data.notApplyTimeList : [],
termStartDate: res.data.termStartDate || '',
termEndDate: res.data.termEndDate || '',
}
return
}

Some files were not shown because too many files have changed in this diff Show More