commit
This commit is contained in:
@@ -68,11 +68,11 @@ public class NutShiroProcessor extends AbstractProcessor {
|
|||||||
//不需要认证授权的url
|
//不需要认证授权的url
|
||||||
String[] authIgnoreUrlArr = Lang.array("/",
|
String[] authIgnoreUrlArr = Lang.array("/",
|
||||||
"/sso/login",
|
"/sso/login",
|
||||||
// "/platform/login",
|
"/platform/login",
|
||||||
"/platform/login(/doLogin|/logout|/captcha)",
|
"/platform/login(/doLogin|/logout|/captcha)",
|
||||||
"/platform/qywechat/.*",
|
"/platform/qywechat/.*",
|
||||||
"/platform/home/(500|403|404|UnknownAccountError|LockedAccountError)",
|
"/platform/home/(500|403|404|UnknownAccountError|LockedAccountError)",
|
||||||
// "/mobile/login",
|
"/mobile/login",
|
||||||
"/mobile/login/doLogin",
|
"/mobile/login/doLogin",
|
||||||
"/platform/jsz/login",
|
"/platform/jsz/login",
|
||||||
"/platform/activity/basic/scope/getScopeUser",
|
"/platform/activity/basic/scope/getScopeUser",
|
||||||
|
|||||||
+53
-6
@@ -3,6 +3,7 @@ package io.v.nutz.zhgh.activity.controller.basic;
|
|||||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.wizzer.framework.base.Result;
|
import cn.wizzer.framework.base.Result;
|
||||||
import io.v.nutz.base.utils.ViTool;
|
import io.v.nutz.base.utils.ViTool;
|
||||||
@@ -31,9 +32,12 @@ import org.nutz.json.Json;
|
|||||||
import org.nutz.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.util.NutMap;
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.AdaptBy;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
import org.nutz.mvc.annotation.POST;
|
import org.nutz.mvc.annotation.POST;
|
||||||
import org.nutz.mvc.annotation.Param;
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
import org.nutz.mvc.upload.TempFile;
|
||||||
|
import org.nutz.mvc.upload.UploadAdaptor;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -105,7 +109,8 @@ public class ActivityBasicScopeController {
|
|||||||
@Param(value = "clubId", required = false) String clubId,
|
@Param(value = "clubId", required = false) String clubId,
|
||||||
@Param(value = "reverseSelection") boolean reverseSelection,
|
@Param(value = "reverseSelection") boolean reverseSelection,
|
||||||
@Param(value = "activityGroupId", required = false) Integer activityGroupId,
|
@Param(value = "activityGroupId", required = false) Integer activityGroupId,
|
||||||
@Param(value = "activityUserCnd", required = false) String activityUserCndStr) {
|
@Param(value = "activityUserCnd", required = false) String activityUserCndStr,
|
||||||
|
@Param(value = "existsLoginNameRedisKey", required = false) String existsLoginNameRedisKey) {
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
DISTINCT(u.id) as id,
|
DISTINCT(u.id) as id,
|
||||||
@@ -127,6 +132,7 @@ public class ActivityBasicScopeController {
|
|||||||
""");
|
""");
|
||||||
try {
|
try {
|
||||||
Cnd cnd = getCnd(pageForm, unionId, unitId, personTypes, userStates, memberTypes, sexTypes, age, teacherMeetingId, roleIds, userId, clubId, reverseSelection, activityGroupId, activityUserCndStr);
|
Cnd cnd = getCnd(pageForm, unionId, unitId, personTypes, userStates, memberTypes, sexTypes, age, teacherMeetingId, roleIds, userId, clubId, reverseSelection, activityGroupId, activityUserCndStr);
|
||||||
|
activityBasicScopeService.appendImportUserCnd(cnd, existsLoginNameRedisKey);
|
||||||
|
|
||||||
|
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
@@ -169,7 +175,8 @@ public class ActivityBasicScopeController {
|
|||||||
@Param(value = "userId", required = false) String[] userId,
|
@Param(value = "userId", required = false) String[] userId,
|
||||||
@Param(value = "clubId", required = false) String clubId,
|
@Param(value = "clubId", required = false) String clubId,
|
||||||
@Param(value = "reverseSelection") boolean reverseSelection,
|
@Param(value = "reverseSelection") boolean reverseSelection,
|
||||||
@Param(value = "activityUserCnd", required = false) String activityUserCndStr) {
|
@Param(value = "activityUserCnd", required = false) String activityUserCndStr,
|
||||||
|
@Param(value = "existsLoginNameRedisKey", required = false) String existsLoginNameRedisKey) {
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT DISTINCT
|
SELECT DISTINCT
|
||||||
( u.id ) AS userId
|
( u.id ) AS userId
|
||||||
@@ -180,6 +187,7 @@ public class ActivityBasicScopeController {
|
|||||||
$condition
|
$condition
|
||||||
""");
|
""");
|
||||||
Cnd cnd = getCnd(pageForm, unionId, unitId, personTypes, userStates, memberTypes, sexTypes, age, teacherMeetingId, roleIds, userId, clubId, reverseSelection, activityGroupId, activityUserCndStr);
|
Cnd cnd = getCnd(pageForm, unionId, unitId, personTypes, userStates, memberTypes, sexTypes, age, teacherMeetingId, roleIds, userId, clubId, reverseSelection, activityGroupId, activityUserCndStr);
|
||||||
|
activityBasicScopeService.appendImportUserCnd(cnd, existsLoginNameRedisKey);
|
||||||
|
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
sql.setCallback(Sqls.callback.entities());
|
sql.setCallback(Sqls.callback.entities());
|
||||||
@@ -322,7 +330,7 @@ public class ActivityBasicScopeController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@Ok("void")
|
||||||
@RequiresPermissions("activity.basic.scope")
|
@RequiresPermissions("activity.basic.scope")
|
||||||
public void doExportUser(PageForm pageForm,
|
public void doExportUser(PageForm pageForm,
|
||||||
@Param(value = "props", required = false) String props,
|
@Param(value = "props", required = false) String props,
|
||||||
@@ -339,7 +347,9 @@ public class ActivityBasicScopeController {
|
|||||||
@Param(value = "clubId", required = false) String clubId,
|
@Param(value = "clubId", required = false) String clubId,
|
||||||
@Param(value = "reverseSelection") boolean reverseSelection,
|
@Param(value = "reverseSelection") boolean reverseSelection,
|
||||||
@Param(value = "activityGroupId", required = false) Integer activityGroupId,
|
@Param(value = "activityGroupId", required = false) Integer activityGroupId,
|
||||||
@Param(value = "activityUserCnd", required = false) String activityUserCndStr, HttpServletResponse response) {
|
@Param(value = "activityUserCnd", required = false) String activityUserCndStr,
|
||||||
|
@Param(value = "existsLoginNameRedisKey", required = false) String existsLoginNameRedisKey,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
|
||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
@@ -363,6 +373,7 @@ public class ActivityBasicScopeController {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Cnd cnd = getCnd(pageForm, unionId, unitId, personTypes, userStates, memberTypes, sexTypes, age, teacherMeetingId, roleIds, userId, clubId, reverseSelection, activityGroupId, activityUserCndStr);
|
Cnd cnd = getCnd(pageForm, unionId, unitId, personTypes, userStates, memberTypes, sexTypes, age, teacherMeetingId, roleIds, userId, clubId, reverseSelection, activityGroupId, activityUserCndStr);
|
||||||
|
activityBasicScopeService.appendImportUserCnd(cnd, existsLoginNameRedisKey);
|
||||||
|
|
||||||
sql.setCondition(cnd);
|
sql.setCondition(cnd);
|
||||||
|
|
||||||
@@ -377,14 +388,50 @@ public class ActivityBasicScopeController {
|
|||||||
entityList.add(new ExcelExportEntity(v, k, 40));
|
entityList.add(new ExcelExportEntity(v, k, 40));
|
||||||
});
|
});
|
||||||
|
|
||||||
ViTool.excelResponse(response, "人员名单.xls");
|
ViTool.excelResponse(response, "人员名单.xlsx");
|
||||||
Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(), entityList, map);
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, map);
|
||||||
workbook.write(response.getOutputStream());
|
workbook.write(response.getOutputStream());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@RequiresPermissions("activity.basic.scope")
|
||||||
|
public void downloadImport(HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
ViTool.excelResponse(response, "人员导入模板.xlsx");
|
||||||
|
List<ExcelExportEntity> entityList = new ArrayList<>();
|
||||||
|
entityList.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||||
|
entityList.add(new ExcelExportEntity("姓名", "username", 20));
|
||||||
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, new ArrayList<>());
|
||||||
|
workbook.write(response.getOutputStream());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("activity.basic.scope")
|
||||||
|
public Object clearSearchCnd(String existsLoginNameRedisKey) {
|
||||||
|
activityBasicScopeService.clearImportUserCnd(existsLoginNameRedisKey);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@AdaptBy(type = UploadAdaptor.class, args = {"ioc:fileUpload"})
|
||||||
|
@RequiresPermissions("activity.basic.scope")
|
||||||
|
public Object doImport(TempFile file) {
|
||||||
|
return activityBasicScopeService.checkImportUser(file.getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private Cnd getCnd(PageForm pageForm,
|
private Cnd getCnd(PageForm pageForm,
|
||||||
String unionId,
|
String unionId,
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package io.v.nutz.zhgh.activity.controller.template;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserTemp {
|
||||||
|
|
||||||
|
@Excel(name = "工号")
|
||||||
|
private String loginname;
|
||||||
|
|
||||||
|
@Excel(name = "姓名")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Excel(name = "备注")
|
||||||
|
private String remarks;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -4,7 +4,9 @@ import io.v.nutz.zhgh.activity.models.ActivityUserScope;
|
|||||||
import io.v.nutz.base.service.ViService;
|
import io.v.nutz.base.service.ViService;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -21,4 +23,27 @@ public interface ActivityBasicScopeService extends ViService<ActivityUserScope>
|
|||||||
*/
|
*/
|
||||||
void largeDataInsert(List<ActivityUserScope> list) ;
|
void largeDataInsert(List<ActivityUserScope> list) ;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析人员导入模板,核对系统中存在的工号,并把匹配到的工号暂存为后续查询条件。
|
||||||
|
*
|
||||||
|
* @param file 上传的人员导入 Excel 文件
|
||||||
|
* @return 导入总数、成功数、错误数、错误明细和临时查询 key
|
||||||
|
*/
|
||||||
|
NutMap checkImportUser(File file);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将导入核对成功的工号追加到当前查询条件中。
|
||||||
|
*
|
||||||
|
* @param cnd 查询条件
|
||||||
|
* @param existsLoginNameRedisKey 导入核对成功工号的临时缓存 key
|
||||||
|
*/
|
||||||
|
void appendImportUserCnd(Cnd cnd, String existsLoginNameRedisKey);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理导入人员临时查询条件。
|
||||||
|
*
|
||||||
|
* @param existsLoginNameRedisKey 导入核对成功工号的临时缓存 key
|
||||||
|
*/
|
||||||
|
void clearImportUserCnd(String existsLoginNameRedisKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+123
@@ -1,24 +1,37 @@
|
|||||||
package io.v.nutz.zhgh.activity.services.impl;
|
package io.v.nutz.zhgh.activity.services.impl;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.ExcelImportUtil;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.ImportParams;
|
||||||
import cn.hutool.core.collection.CollectionUtil;
|
import cn.hutool.core.collection.CollectionUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
import io.v.nutz.zhgh.activity.models.ActivityUserScope;
|
import io.v.nutz.zhgh.activity.models.ActivityUserScope;
|
||||||
import io.v.nutz.zhgh.activity.services.ActivityBasicScopeService;
|
import io.v.nutz.zhgh.activity.services.ActivityBasicScopeService;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.base.service.impl.ViServiceImpl;
|
import io.v.nutz.base.service.impl.ViServiceImpl;
|
||||||
|
import io.v.nutz.zhgh.activity.controller.template.UserTemp;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
import org.nutz.dao.impl.NutTxDao;
|
import org.nutz.dao.impl.NutTxDao;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
import org.nutz.dao.sql.Sql;
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.integration.jedis.RedisService;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author zxy
|
* @author zxy
|
||||||
@@ -28,6 +41,11 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
@IocBean(args = {"refer:dao"})
|
@IocBean(args = {"refer:dao"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class ActivityBasicScopeServiceImpl extends ViServiceImpl<ActivityUserScope> implements ActivityBasicScopeService {
|
public class ActivityBasicScopeServiceImpl extends ViServiceImpl<ActivityUserScope> implements ActivityBasicScopeService {
|
||||||
|
private static final String IMPORT_NO_MATCH_LOGIN_NAME = "__activity_scope_import_no_match__";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private RedisService redisService;
|
||||||
|
|
||||||
public ActivityBasicScopeServiceImpl(Dao dao) {
|
public ActivityBasicScopeServiceImpl(Dao dao) {
|
||||||
super(dao);
|
super(dao);
|
||||||
}
|
}
|
||||||
@@ -79,4 +97,109 @@ public class ActivityBasicScopeServiceImpl extends ViServiceImpl<ActivityUserSco
|
|||||||
}
|
}
|
||||||
log.info("结束时间" + DateUtil.getDateTime());
|
log.info("结束时间" + DateUtil.getDateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析导入模板并缓存匹配到的工号,缓存 key 会返回给前端继续用于查询和分组设置。
|
||||||
|
*
|
||||||
|
* @param file 上传的人员导入 Excel 文件
|
||||||
|
* @return 导入核对结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public NutMap checkImportUser(File file) {
|
||||||
|
String matchUserLoginNamesKey = "ActivityBasicScopeService.checkImportUser.time=" + System.currentTimeMillis();
|
||||||
|
List<UserTemp> userImportList = ExcelImportUtil.importExcel(file, UserTemp.class, new ImportParams());
|
||||||
|
if (userImportList == null) {
|
||||||
|
userImportList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
Set<String> sysLoginNames = getSysLoginNames();
|
||||||
|
List<String> existsLoginNames = new ArrayList<>();
|
||||||
|
|
||||||
|
for (UserTemp excelUser : userImportList) {
|
||||||
|
if (excelUser == null || StrUtil.isBlank(excelUser.getLoginname())) {
|
||||||
|
if (excelUser != null) {
|
||||||
|
excelUser.setRemarks("工号不能为空");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (sysLoginNames.contains(excelUser.getLoginname())) {
|
||||||
|
existsLoginNames.add(excelUser.getLoginname());
|
||||||
|
} else {
|
||||||
|
excelUser.setRemarks("系统查不到此人");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<UserTemp> errorExcelTempUsers = userImportList.stream()
|
||||||
|
.filter(v -> v != null && StrUtil.isNotBlank(v.getRemarks()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
NutMap nutMap = NutMap.NEW();
|
||||||
|
nutMap.setv("totalCount", userImportList.size());
|
||||||
|
nutMap.setv("successCount", existsLoginNames.size());
|
||||||
|
nutMap.setv("errorCount", errorExcelTempUsers.size());
|
||||||
|
nutMap.setv("errorList", errorExcelTempUsers.stream().map(v -> NutMap.NEW()
|
||||||
|
.addv("工号", v.getLoginname())
|
||||||
|
.addv("姓名", v.getUsername())
|
||||||
|
.addv("错误原因", v.getRemarks())).collect(Collectors.toList()));
|
||||||
|
nutMap.setv("existsLoginNameRedisKey", matchUserLoginNamesKey);
|
||||||
|
|
||||||
|
// 没有匹配人员时写入一个不可能存在的工号,避免后续查询误变成全量。
|
||||||
|
String[] cacheLoginNames = Lang.isNotEmpty(existsLoginNames)
|
||||||
|
? existsLoginNames.toArray(new String[0])
|
||||||
|
: new String[]{IMPORT_NO_MATCH_LOGIN_NAME};
|
||||||
|
redisService.lpush(matchUserLoginNamesKey, cacheLoginNames);
|
||||||
|
redisService.expire(matchUserLoginNamesKey, 60 * 60);
|
||||||
|
|
||||||
|
return nutMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据导入核对返回的 Redis key,给现有查询条件追加工号范围。
|
||||||
|
*
|
||||||
|
* @param cnd 查询条件
|
||||||
|
* @param existsLoginNameRedisKey 导入核对成功工号的临时缓存 key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void appendImportUserCnd(Cnd cnd, String existsLoginNameRedisKey) {
|
||||||
|
if (StrUtil.isBlank(existsLoginNameRedisKey)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> loginNames = redisService.lrange(existsLoginNameRedisKey, 0, -1);
|
||||||
|
if (Lang.isEmpty(loginNames)) {
|
||||||
|
cnd.and("u.loginname", "=", IMPORT_NO_MATCH_LOGIN_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cnd.andEX("u.loginname", "in", loginNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理导入核对成功工号的临时缓存。
|
||||||
|
*
|
||||||
|
* @param existsLoginNameRedisKey 导入核对成功工号的临时缓存 key
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void clearImportUserCnd(String existsLoginNameRedisKey) {
|
||||||
|
if (StrUtil.isNotBlank(existsLoginNameRedisKey)) {
|
||||||
|
redisService.del(existsLoginNameRedisKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> getSysLoginNames() {
|
||||||
|
Sql sql = Sqls.queryString("""
|
||||||
|
SELECT
|
||||||
|
u.loginname
|
||||||
|
FROM
|
||||||
|
`user` u
|
||||||
|
""");
|
||||||
|
dao().execute(sql);
|
||||||
|
String[] sysLoginNames = (String[]) sql.getResult();
|
||||||
|
Set<String> loginNameSet = new HashSet<>();
|
||||||
|
if (sysLoginNames != null) {
|
||||||
|
for (String loginName : sysLoginNames) {
|
||||||
|
if (StrUtil.isNotBlank(loginName)) {
|
||||||
|
loginNameSet.add(loginName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loginNameSet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+78
-1
@@ -21,6 +21,7 @@ import io.v.nutz.base.utils.ViTool;
|
|||||||
import io.v.nutz.sys.models.SysHoliday;
|
import io.v.nutz.sys.models.SysHoliday;
|
||||||
import io.v.nutz.sys.models.User;
|
import io.v.nutz.sys.models.User;
|
||||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||||
|
import io.v.nutz.zhgh.therapyRecuperation.constant.TheRapyRecuperationState;
|
||||||
import io.v.nutz.zhgh.therapyRecuperation.model.*;
|
import io.v.nutz.zhgh.therapyRecuperation.model.*;
|
||||||
import io.v.nutz.zhgh.therapyRecuperation.service.baseManage.TheRapyRecuperationBaseManagerService;
|
import io.v.nutz.zhgh.therapyRecuperation.service.baseManage.TheRapyRecuperationBaseManagerService;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
@@ -117,6 +118,7 @@ public class TheRapyRecuperationBaseManagerController {
|
|||||||
tb.activityStartTime,
|
tb.activityStartTime,
|
||||||
tb.activityEndTime,
|
tb.activityEndTime,
|
||||||
tb.files,
|
tb.files,
|
||||||
|
tb.maxSignCount,
|
||||||
tb.baseContactPerson,
|
tb.baseContactPerson,
|
||||||
tb.baseContactNumber,
|
tb.baseContactNumber,
|
||||||
tb.files as fileId,
|
tb.files as fileId,
|
||||||
@@ -286,7 +288,11 @@ public class TheRapyRecuperationBaseManagerController {
|
|||||||
return Result.error("参数错误");
|
return Result.error("参数错误");
|
||||||
}
|
}
|
||||||
|
|
||||||
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
|
// 手机端日历只使用最新提交配置,保持活动时间和页面展示一致。
|
||||||
|
TheRapyRecuperationConfig config = dao.fetch(TheRapyRecuperationConfig.class, Cnd.where("latestConfig", "=", true));
|
||||||
|
if (config == null) {
|
||||||
|
return Result.error("未找到最新疗休养配置,请联系管理员");
|
||||||
|
}
|
||||||
//获取线路对应的标段
|
//获取线路对应的标段
|
||||||
TheRapyRecuperationBaseManagement management = dao.fetch(TheRapyRecuperationBaseManagement.class, id);
|
TheRapyRecuperationBaseManagement management = dao.fetch(TheRapyRecuperationBaseManagement.class, id);
|
||||||
//TheRapyRecuperationLot lot = dao.fetch(TheRapyRecuperationLot.class, management.getLotId());
|
//TheRapyRecuperationLot lot = dao.fetch(TheRapyRecuperationLot.class, management.getLotId());
|
||||||
@@ -306,6 +312,7 @@ public class TheRapyRecuperationBaseManagerController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
List<Integer> weeks = management.getWeekCheckIn();
|
List<Integer> weeks = management.getWeekCheckIn();
|
||||||
|
Set<String> fullDays = getFullBaseManagementDays(management);
|
||||||
|
|
||||||
// 解析日期
|
// 解析日期
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
@@ -330,6 +337,10 @@ public class TheRapyRecuperationBaseManagerController {
|
|||||||
currentDate = currentDate.plusDays(1);
|
currentDate = currentDate.plusDays(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (fullDays.contains(currentDateString)) {
|
||||||
|
currentDate = currentDate.plusDays(1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
// 检查是否为需要排除的周几
|
// 检查是否为需要排除的周几
|
||||||
int dayOfWeek = currentDate.getDayOfWeek().getValue() % 7; // 1是周一,7是周日
|
int dayOfWeek = currentDate.getDayOfWeek().getValue() % 7; // 1是周一,7是周日
|
||||||
if (Lang.isNotEmpty(weeks) && !weeks.contains(dayOfWeek)) {
|
if (Lang.isNotEmpty(weeks) && !weeks.contains(dayOfWeek)) {
|
||||||
@@ -343,11 +354,77 @@ public class TheRapyRecuperationBaseManagerController {
|
|||||||
|
|
||||||
return Map.of("days", resultDates,
|
return Map.of("days", resultDates,
|
||||||
"holidays", holidays,
|
"holidays", holidays,
|
||||||
|
"fullDays", fullDays,
|
||||||
"lotValue", 0,
|
"lotValue", 0,
|
||||||
"minDate", DateUtil.formatDate(config.getFragmentPlayStartTime()),
|
"minDate", DateUtil.formatDate(config.getFragmentPlayStartTime()),
|
||||||
"maxDate", DateUtil.formatDate(config.getFragmentPlayEndTime()));
|
"maxDate", DateUtil.formatDate(config.getFragmentPlayEndTime()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取指定酒店报名已满的日期,手机端日历用来过滤不可选入住日。
|
||||||
|
*
|
||||||
|
* @param management 酒店信息
|
||||||
|
* @return 已达到每日最高报名人数的日期集合
|
||||||
|
*/
|
||||||
|
private Set<String> getFullBaseManagementDays(TheRapyRecuperationBaseManagement management) {
|
||||||
|
if (management == null || management.getMaxSignCount() == null || management.getMaxSignCount() <= 0) {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
List<TheRapyRecuperationEnroll> enrolls = dao.query(TheRapyRecuperationEnroll.class,
|
||||||
|
Cnd.where("takePartInBaseManagementId", "=", management.getId())
|
||||||
|
.and("specificTime", "is not", null)
|
||||||
|
.and("isNormal", "=", true)
|
||||||
|
.and("stateId", "in", Lang.array(TheRapyRecuperationState.UNIT, TheRapyRecuperationState.LINEUNIT, TheRapyRecuperationState.SCHOOL, TheRapyRecuperationState.PASS))
|
||||||
|
.and("YEAR(signingUptime)", "=", DateUtil.thisYear()));
|
||||||
|
Map<String, Integer> dayCountMap = new HashMap<>();
|
||||||
|
for (TheRapyRecuperationEnroll enroll : enrolls) {
|
||||||
|
for (String day : parseSpecificTimeDays(enroll.getSpecificTime())) {
|
||||||
|
dayCountMap.put(day, dayCountMap.getOrDefault(day, 0) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dayCountMap.entrySet().stream()
|
||||||
|
.filter(entry -> entry.getValue() >= management.getMaxSignCount())
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把“06月01日-06月03日”格式的报名时间拆成逐日日期。
|
||||||
|
*
|
||||||
|
* @param specificTime 报名时间段
|
||||||
|
* @return 报名时间段覆盖的日期集合,格式 yyyy-MM-dd
|
||||||
|
*/
|
||||||
|
private List<String> parseSpecificTimeDays(String specificTime) {
|
||||||
|
if (StrUtil.isBlank(specificTime) || !specificTime.contains("-")) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
String[] times = specificTime.split("-");
|
||||||
|
if (times.length != 2 || StrUtil.isBlank(times[0]) || StrUtil.isBlank(times[1])) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
DateTimeFormatter sourceFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
|
||||||
|
DateTimeFormatter targetFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||||
|
LocalDate start;
|
||||||
|
LocalDate end;
|
||||||
|
try {
|
||||||
|
start = LocalDate.parse(DateUtil.thisYear() + "年" + times[0].trim(), sourceFormatter);
|
||||||
|
end = LocalDate.parse(DateUtil.thisYear() + "年" + times[1].trim(), sourceFormatter);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
if (end.isBefore(start)) {
|
||||||
|
end = end.plusYears(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> days = new ArrayList<>();
|
||||||
|
LocalDate current = start;
|
||||||
|
while (!current.isAfter(end)) {
|
||||||
|
days.add(current.format(targetFormatter));
|
||||||
|
current = current.plusDays(1);
|
||||||
|
}
|
||||||
|
return days;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 目的地导入模版
|
* 目的地导入模版
|
||||||
|
|||||||
+26
@@ -37,10 +37,12 @@ import org.nutz.mvc.annotation.At;
|
|||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
import org.nutz.mvc.upload.TempFile;
|
import org.nutz.mvc.upload.TempFile;
|
||||||
import org.nutz.mvc.upload.UploadAdaptor;
|
import org.nutz.mvc.upload.UploadAdaptor;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -183,6 +185,30 @@ public class TheRapyRecuperationUserQueryController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载参加人员导入模板
|
||||||
|
*
|
||||||
|
* @param response 响应
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@RequiresAuthentication
|
||||||
|
public void downloadImportTemplate(HttpServletResponse response) {
|
||||||
|
String templatePath = "templates/travel/TravelEnrollImport.xlsx";
|
||||||
|
try (InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(templatePath)) {
|
||||||
|
if (inputStream == null) {
|
||||||
|
response.sendError(HttpServletResponse.SC_NOT_FOUND, "模板文件不存在");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
response.setContentType("application/octet-stream");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + new String(("参加人员导入模板.xlsx").getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
|
||||||
|
IOUtils.copy(inputStream, response.getOutputStream());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参加人员导入
|
* 参加人员导入
|
||||||
*
|
*
|
||||||
|
|||||||
+18
-2
@@ -94,7 +94,10 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
|
|||||||
state.stateColor,
|
state.stateColor,
|
||||||
line.regionalNature,
|
line.regionalNature,
|
||||||
line.lineName,
|
line.lineName,
|
||||||
agency.travelAgencyName,
|
COALESCE(agency.travelAgencyName, lineAgency.travelAgencyName) AS travelAgencyName,
|
||||||
|
lot.lotName,
|
||||||
|
lot.activityCost,
|
||||||
|
CASE WHEN lineu.playStartTime IS NULL AND lineu.playEndTime IS NULL THEN '' ELSE CONCAT(IFNULL(DATE_FORMAT(lineu.playStartTime,'%Y-%m-%d'), ''), '至', IFNULL(DATE_FORMAT(lineu.playEndTime,'%Y-%m-%d'), '')) END AS travelTime,
|
||||||
ma.baseName,
|
ma.baseName,
|
||||||
enroll.*,
|
enroll.*,
|
||||||
lineu.lineId,
|
lineu.lineId,
|
||||||
@@ -107,6 +110,8 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
|
|||||||
LEFT JOIN the_rapy_recuperation_line_union_select lineu ON lineu.id=enroll.takePartInLineId
|
LEFT JOIN the_rapy_recuperation_line_union_select lineu ON lineu.id=enroll.takePartInLineId
|
||||||
LEFT JOIN the_rapy_recuperation_line line ON line.id = lineu.lineId
|
LEFT JOIN the_rapy_recuperation_line line ON line.id = lineu.lineId
|
||||||
LEFT JOIN the_rapy_recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
|
LEFT JOIN the_rapy_recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
|
||||||
|
LEFT JOIN the_rapy_recuperation_travel_agency lineAgency ON lineAgency.id = line.travelAgencyId
|
||||||
|
LEFT JOIN the_rapy_recuperation_lot lot ON lot.id = line.lotId
|
||||||
LEFT JOIN the_rapy_recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
|
LEFT JOIN the_rapy_recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
|
||||||
LEFT JOIN audit_state state ON state.stateId = enroll.stateId
|
LEFT JOIN audit_state state ON state.stateId = enroll.stateId
|
||||||
$condition
|
$condition
|
||||||
@@ -293,7 +298,10 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
|
|||||||
state.stateColor,
|
state.stateColor,
|
||||||
line.regionalNature,
|
line.regionalNature,
|
||||||
line.lineName,
|
line.lineName,
|
||||||
agency.travelAgencyName,
|
COALESCE(agency.travelAgencyName, lineAgency.travelAgencyName) AS travelAgencyName,
|
||||||
|
lot.lotName,
|
||||||
|
lot.activityCost,
|
||||||
|
CASE WHEN lineu.playStartTime IS NULL AND lineu.playEndTime IS NULL THEN '' ELSE CONCAT(IFNULL(DATE_FORMAT(lineu.playStartTime,'%Y-%m-%d'), ''), '至', IFNULL(DATE_FORMAT(lineu.playEndTime,'%Y-%m-%d'), '')) END AS travelTime,
|
||||||
ma.baseName,
|
ma.baseName,
|
||||||
enroll.*,
|
enroll.*,
|
||||||
lineu.lineId,
|
lineu.lineId,
|
||||||
@@ -306,6 +314,8 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
|
|||||||
LEFT JOIN the_rapy_recuperation_line_union_select lineu ON lineu.id=enroll.takePartInLineId
|
LEFT JOIN the_rapy_recuperation_line_union_select lineu ON lineu.id=enroll.takePartInLineId
|
||||||
LEFT JOIN the_rapy_recuperation_line line ON line.id = lineu.lineId
|
LEFT JOIN the_rapy_recuperation_line line ON line.id = lineu.lineId
|
||||||
LEFT JOIN the_rapy_recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
|
LEFT JOIN the_rapy_recuperation_travel_agency agency ON agency.id = enroll.takePartInTravelAgencyId
|
||||||
|
LEFT JOIN the_rapy_recuperation_travel_agency lineAgency ON lineAgency.id = line.travelAgencyId
|
||||||
|
LEFT JOIN the_rapy_recuperation_lot lot ON lot.id = line.lotId
|
||||||
LEFT JOIN the_rapy_recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
|
LEFT JOIN the_rapy_recuperation_base_management ma on ma.id = enroll.takePartInBaseManagementId
|
||||||
LEFT JOIN audit_state state ON state.stateId = enroll.stateId
|
LEFT JOIN audit_state state ON state.stateId = enroll.stateId
|
||||||
$condition
|
$condition
|
||||||
@@ -378,6 +388,12 @@ public class TheRapyRecuperationSchoolUnionUserQueryController {
|
|||||||
excelEntities.add(new ExcelExportEntity("工会", "unionName", 20));
|
excelEntities.add(new ExcelExportEntity("工会", "unionName", 20));
|
||||||
excelEntities.add(new ExcelExportEntity("身份证号", "idCard", 30));
|
excelEntities.add(new ExcelExportEntity("身份证号", "idCard", 30));
|
||||||
excelEntities.add(new ExcelExportEntity("手机号", "mobile", 20));
|
excelEntities.add(new ExcelExportEntity("手机号", "mobile", 20));
|
||||||
|
// 导出线路关联信息,与列表查询使用同一批筛选条件,确保列表查到什么导出什么。
|
||||||
|
excelEntities.add(new ExcelExportEntity("出行时间", "travelTime", 30));
|
||||||
|
excelEntities.add(new ExcelExportEntity("标段", "lotName", 20));
|
||||||
|
excelEntities.add(new ExcelExportEntity("标段费用", "activityCost", 20));
|
||||||
|
excelEntities.add(new ExcelExportEntity("线路", "lineName", 30));
|
||||||
|
excelEntities.add(new ExcelExportEntity("旅行社", "travelAgencyName", 30));
|
||||||
if (config.getFamilyInfo() == 2) {
|
if (config.getFamilyInfo() == 2) {
|
||||||
excelEntities.add(new ExcelExportEntity("与本人关系", "relation", 10));
|
excelEntities.add(new ExcelExportEntity("与本人关系", "relation", 10));
|
||||||
excelEntities.add(new ExcelExportEntity("床型", "bedType", 10));
|
excelEntities.add(new ExcelExportEntity("床型", "bedType", 10));
|
||||||
|
|||||||
+14
-65
@@ -1,32 +1,14 @@
|
|||||||
package io.v.nutz.zhgh.therapyRecuperation.controller.theRapyConfig;
|
package io.v.nutz.zhgh.therapyRecuperation.controller.theRapyConfig;
|
||||||
|
|
||||||
import io.v.nutz.base.annontation.ViReturn;
|
import io.v.nutz.base.annontation.ViReturn;
|
||||||
import io.v.nutz.base.model.msgUser;
|
|
||||||
import io.v.nutz.base.utils.MsgApi;
|
|
||||||
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationBaseManagement;
|
|
||||||
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
|
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
|
||||||
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLine;
|
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
|
||||||
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLot;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
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.Inject;
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
import org.nutz.lang.Lang;
|
|
||||||
import org.nutz.lang.Strings;
|
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
import org.nutz.mvc.annotation.Ok;
|
import org.nutz.mvc.annotation.Ok;
|
||||||
import org.nutz.trans.Trans;
|
|
||||||
import org.springframework.util.CollectionUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rapy休养配置控制器
|
* rapy休养配置控制器
|
||||||
@@ -41,9 +23,7 @@ public class TheRapyRecuperationConfigController {
|
|||||||
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private Dao dao;
|
private TheRapyRecuperationConfigService configService;
|
||||||
@Inject
|
|
||||||
private MsgApi msgApi;
|
|
||||||
|
|
||||||
|
|
||||||
@At("")
|
@At("")
|
||||||
@@ -55,29 +35,23 @@ public class TheRapyRecuperationConfigController {
|
|||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
@Aop(TransAop.READ_COMMITTED)
|
|
||||||
public Object operation(TheRapyRecuperationConfig config, String[] lotDeleteList) {
|
public Object operation(TheRapyRecuperationConfig config, String[] lotDeleteList) {
|
||||||
if (Strings.isNotBlank(config.getId())) {
|
configService.saveConfig(config, lotDeleteList);
|
||||||
if (Lang.isNotEmpty(lotDeleteList)) {
|
|
||||||
dao.clear(TheRapyRecuperationLot.class, Cnd.where("id", "in", lotDeleteList));
|
|
||||||
}
|
|
||||||
dao.updateWith(config, "lots");
|
|
||||||
List<TheRapyRecuperationLot> collect = config.getLots().stream().filter(v -> v.getConfigId() == null).collect(Collectors.toList());
|
|
||||||
for (TheRapyRecuperationLot obj : collect) {
|
|
||||||
obj.setConfigId(config.getId());
|
|
||||||
}
|
|
||||||
dao.insert(collect);
|
|
||||||
} else {
|
|
||||||
dao.insertWith(config, "lots");
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@At
|
@At
|
||||||
@ViReturn
|
@ViReturn
|
||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
public Object findOne() {
|
public Object findOne(Integer year) {
|
||||||
return dao.fetchLinks(dao.fetch(TheRapyRecuperationConfig.class), "lots",Cnd.NEW().desc("lotValue"));
|
return configService.findByYear(year);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresAuthentication
|
||||||
|
public Object copyLastYear(Integer year) {
|
||||||
|
return configService.copyLastYear(year);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -90,20 +64,7 @@ public class TheRapyRecuperationConfigController {
|
|||||||
@ViReturn
|
@ViReturn
|
||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
public Object getLotsById(String lotId){
|
public Object getLotsById(String lotId){
|
||||||
List<String> lineNames = new ArrayList<>();
|
return configService.getLotsById(lotId);
|
||||||
List<String> baseNames = new ArrayList<>();
|
|
||||||
Map<String, List<String>> map = new HashMap<>();
|
|
||||||
List<TheRapyRecuperationLine> lineList = dao.query(TheRapyRecuperationLine.class, Cnd.where("lotId", "=", lotId));
|
|
||||||
if (!CollectionUtils.isEmpty(lineList)){
|
|
||||||
lineList.forEach(v-> lineNames.add(v.getLineName()));
|
|
||||||
map.put("line",lineNames);
|
|
||||||
}
|
|
||||||
List<TheRapyRecuperationBaseManagement> managementList = dao.query(TheRapyRecuperationBaseManagement.class, Cnd.where("lotId", "=", lotId));
|
|
||||||
if (!CollectionUtils.isEmpty(managementList)){
|
|
||||||
managementList.forEach(v-> baseNames.add(v.getBaseName()));
|
|
||||||
map.put("base",baseNames);
|
|
||||||
}
|
|
||||||
return map;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -116,19 +77,7 @@ public class TheRapyRecuperationConfigController {
|
|||||||
@ViReturn
|
@ViReturn
|
||||||
@RequiresAuthentication
|
@RequiresAuthentication
|
||||||
public Object deleteLotById(String lotId){
|
public Object deleteLotById(String lotId){
|
||||||
Trans.exec(()->{
|
configService.deleteLotById(lotId);
|
||||||
dao.clear(TheRapyRecuperationLot.class, Cnd.where("id","=",lotId));
|
|
||||||
List<TheRapyRecuperationLine> lineList = dao.query(TheRapyRecuperationLine.class, Cnd.where("lotId", "=", lotId));
|
|
||||||
if (!CollectionUtils.isEmpty(lineList)) {
|
|
||||||
lineList.forEach(v -> v.setLotId(null));
|
|
||||||
dao.update(lineList);
|
|
||||||
}
|
|
||||||
List<TheRapyRecuperationBaseManagement> managementList = dao.query(TheRapyRecuperationBaseManagement.class, Cnd.where("lotId", "=", lotId));
|
|
||||||
if (!CollectionUtils.isEmpty(managementList)) {
|
|
||||||
managementList.forEach(v -> v.setLotId(null));
|
|
||||||
dao.update(managementList);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -165,6 +165,12 @@ public class TheRapyRecuperationBaseManagement {
|
|||||||
@Comment("天数")
|
@Comment("天数")
|
||||||
private List<String> allowDay;
|
private List<String> allowDay;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.INT)
|
||||||
|
@Comment("同一酒店每日最高报名人数")
|
||||||
|
@Excel(name = "同一酒店每日最高报名人数")
|
||||||
|
private Integer maxSignCount;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@ColDefine(type = ColType.VARCHAR)
|
@ColDefine(type = ColType.VARCHAR)
|
||||||
@Comment("旅行社地点")
|
@Comment("旅行社地点")
|
||||||
|
|||||||
@@ -26,6 +26,16 @@ public class TheRapyRecuperationConfig {
|
|||||||
@Comment("配置名称")
|
@Comment("配置名称")
|
||||||
private String configName;
|
private String configName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.INT)
|
||||||
|
@Comment("配置年度")
|
||||||
|
private Integer configYear;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
@Comment("是否最新提交配置")
|
||||||
|
private Boolean latestConfig;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
@ColDefine(type = ColType.INT, width = 32)
|
@ColDefine(type = ColType.INT, width = 32)
|
||||||
@Comment("参加人员范围")
|
@Comment("参加人员范围")
|
||||||
|
|||||||
+50
@@ -0,0 +1,50 @@
|
|||||||
|
package io.v.nutz.zhgh.therapyRecuperation.service;
|
||||||
|
|
||||||
|
import io.v.nutz.base.service.ViService;
|
||||||
|
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 疗休养基础配置服务。
|
||||||
|
*/
|
||||||
|
public interface TheRapyRecuperationConfigService extends ViService<TheRapyRecuperationConfig> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按年度查询基础配置;年度为空时使用当前年度。
|
||||||
|
*
|
||||||
|
* @param configYear 配置年度
|
||||||
|
* @return 年度配置
|
||||||
|
*/
|
||||||
|
TheRapyRecuperationConfig findByYear(Integer configYear);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存年度基础配置,已存在配置时更新,不存在时新增。
|
||||||
|
*
|
||||||
|
* @param config 基础配置
|
||||||
|
* @param lotDeleteList 需要删除的标段id
|
||||||
|
*/
|
||||||
|
void saveConfig(TheRapyRecuperationConfig config, String[] lotDeleteList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将上一年度配置复制为当前年度配置。
|
||||||
|
*
|
||||||
|
* @param configYear 当前配置年度
|
||||||
|
* @return 复制后的当前年度配置
|
||||||
|
*/
|
||||||
|
TheRapyRecuperationConfig copyLastYear(Integer configYear);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询使用该标段的线路和目的地。
|
||||||
|
*
|
||||||
|
* @param lotId 标段id
|
||||||
|
* @return 使用情况
|
||||||
|
*/
|
||||||
|
NutMap getLotsById(String lotId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 强制删除标段,并清空已绑定线路和目的地上的标段。
|
||||||
|
*
|
||||||
|
* @param lotId 标段id
|
||||||
|
*/
|
||||||
|
void deleteLotById(String lotId);
|
||||||
|
}
|
||||||
+236
@@ -0,0 +1,236 @@
|
|||||||
|
package io.v.nutz.zhgh.therapyRecuperation.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import io.v.nutz.base.service.impl.ViServiceImpl;
|
||||||
|
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationBaseManagement;
|
||||||
|
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationConfig;
|
||||||
|
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLine;
|
||||||
|
import io.v.nutz.zhgh.therapyRecuperation.model.TheRapyRecuperationLot;
|
||||||
|
import io.v.nutz.zhgh.therapyRecuperation.service.TheRapyRecuperationConfigService;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.dao.Chain;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.Strings;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.nutz.trans.Trans;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.temporal.ChronoField;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 疗休养基础配置服务实现。
|
||||||
|
*/
|
||||||
|
@IocBean(args = {"refer:dao"})
|
||||||
|
public class TheRapyRecuperationConfigServiceImpl extends ViServiceImpl<TheRapyRecuperationConfig> implements TheRapyRecuperationConfigService {
|
||||||
|
|
||||||
|
private static final int DEFAULT_CONFIG_YEAR = 2025;
|
||||||
|
|
||||||
|
public TheRapyRecuperationConfigServiceImpl(Dao dao) {
|
||||||
|
super(dao);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 年度为空时统一使用 2025 年,兼容原有无年度的基础配置。
|
||||||
|
*
|
||||||
|
* @param configYear 配置年度
|
||||||
|
* @return 有效年度
|
||||||
|
*/
|
||||||
|
private Integer getConfigYear(Integer configYear) {
|
||||||
|
return configYear == null ? DEFAULT_CONFIG_YEAR : configYear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TheRapyRecuperationConfig findByYear(Integer configYear) {
|
||||||
|
if (configYear == null) {
|
||||||
|
return findLatestConfig();
|
||||||
|
}
|
||||||
|
Integer year = getConfigYear(configYear);
|
||||||
|
TheRapyRecuperationConfig config = fetch(Cnd.where("configYear", "=", year));
|
||||||
|
if (config == null && year == DEFAULT_CONFIG_YEAR) {
|
||||||
|
config = fetch(Cnd.where("configYear", "is", null));
|
||||||
|
}
|
||||||
|
if (config == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return dao().fetchLinks(config, "lots", Cnd.NEW().desc("lotValue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 其他业务页面不传年度时,只使用最新提交的基础配置。
|
||||||
|
*
|
||||||
|
* @return 最新基础配置
|
||||||
|
*/
|
||||||
|
private TheRapyRecuperationConfig findLatestConfig() {
|
||||||
|
TheRapyRecuperationConfig config = fetch(Cnd.where("latestConfig", "=", true));
|
||||||
|
if (config == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return dao().fetchLinks(config, "lots", Cnd.NEW().desc("lotValue"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public void saveConfig(TheRapyRecuperationConfig config, String[] lotDeleteList) {
|
||||||
|
Integer year = getConfigYear(config.getConfigYear());
|
||||||
|
config.setConfigYear(year);
|
||||||
|
config.setLatestConfig(true);
|
||||||
|
TheRapyRecuperationConfig oldConfig = findByYear(year);
|
||||||
|
if (Strings.isBlank(config.getId()) && oldConfig != null) {
|
||||||
|
config.setId(oldConfig.getId());
|
||||||
|
}
|
||||||
|
resetLatestConfig(config.getId());
|
||||||
|
if (Strings.isNotBlank(config.getId())) {
|
||||||
|
if (Lang.isNotEmpty(lotDeleteList)) {
|
||||||
|
dao().clear(TheRapyRecuperationLot.class, Cnd.where("id", "in", lotDeleteList));
|
||||||
|
}
|
||||||
|
dao().updateWith(config, "lots");
|
||||||
|
List<TheRapyRecuperationLot> lots = config.getLots() == null ? new ArrayList<>() : config.getLots();
|
||||||
|
List<TheRapyRecuperationLot> collect = lots.stream().filter(v -> v.getConfigId() == null).collect(Collectors.toList());
|
||||||
|
for (TheRapyRecuperationLot obj : collect) {
|
||||||
|
obj.setConfigId(config.getId());
|
||||||
|
}
|
||||||
|
if (Lang.isNotEmpty(collect)) {
|
||||||
|
dao().insert(collect);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dao().insertWith(config, "lots");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每次提交年度配置后,仅保留当前配置为最新配置。
|
||||||
|
*
|
||||||
|
* @param currentConfigId 当前配置id
|
||||||
|
*/
|
||||||
|
private void resetLatestConfig(String currentConfigId) {
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
if (Strings.isNotBlank(currentConfigId)) {
|
||||||
|
cnd.and("id", "!=", currentConfigId);
|
||||||
|
}
|
||||||
|
dao().update(TheRapyRecuperationConfig.class, Chain.make("latestConfig", false), cnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public TheRapyRecuperationConfig copyLastYear(Integer configYear) {
|
||||||
|
Integer year = getConfigYear(configYear);
|
||||||
|
TheRapyRecuperationConfig currentConfig = findByYear(year);
|
||||||
|
TheRapyRecuperationConfig lastConfig = findByYear(year - 1);
|
||||||
|
if (lastConfig == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
lastConfig.setId(currentConfig == null ? null : currentConfig.getId());
|
||||||
|
lastConfig.setConfigYear(year);
|
||||||
|
lastConfig.setLatestConfig(true);
|
||||||
|
resetConfigTimeYear(lastConfig, year);
|
||||||
|
resetLatestConfig(null);
|
||||||
|
if (currentConfig == null) {
|
||||||
|
copyLotsToNewConfig(lastConfig);
|
||||||
|
dao().insertWith(lastConfig, "lots");
|
||||||
|
} else {
|
||||||
|
dao().clear(TheRapyRecuperationLot.class, Cnd.where("configId", "=", currentConfig.getId()));
|
||||||
|
copyLotsToNewConfig(lastConfig);
|
||||||
|
dao().update(lastConfig);
|
||||||
|
for (TheRapyRecuperationLot lot : lastConfig.getLots()) {
|
||||||
|
lot.setConfigId(currentConfig.getId());
|
||||||
|
}
|
||||||
|
if (Lang.isNotEmpty(lastConfig.getLots())) {
|
||||||
|
dao().insert(lastConfig.getLots());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return findByYear(year);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 沿用上一年度配置时,将所有年度相关时间改为当前配置年度,月日和时分秒保持不变。
|
||||||
|
*
|
||||||
|
* @param config 待复制配置
|
||||||
|
* @param year 当前配置年度
|
||||||
|
*/
|
||||||
|
private void resetConfigTimeYear(TheRapyRecuperationConfig config, Integer year) {
|
||||||
|
config.setCreateLineStartTime(resetDateTimeYear(config.getCreateLineStartTime(), year));
|
||||||
|
config.setCreateLineEndTime(resetDateTimeYear(config.getCreateLineEndTime(), year));
|
||||||
|
config.setImplodeStartTime(resetDateTimeYear(config.getImplodeStartTime(), year));
|
||||||
|
config.setImplodeEndTime(resetDateTimeYear(config.getImplodeEndTime(), year));
|
||||||
|
config.setFragmentStartTime(resetDateTimeYear(config.getFragmentStartTime(), year));
|
||||||
|
config.setFragmentEndTime(resetDateTimeYear(config.getFragmentEndTime(), year));
|
||||||
|
config.setFragmentPlayStartTime(resetDateTimeYear(config.getFragmentPlayStartTime(), year));
|
||||||
|
config.setFragmentPlayEndTime(resetDateTimeYear(config.getFragmentPlayEndTime(), year));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换时间年份;闰年 2 月 29 日复制到平年时,自动落到该年 2 月最后一天。
|
||||||
|
*
|
||||||
|
* @param dateTime 原时间
|
||||||
|
* @param year 目标年度
|
||||||
|
* @return 替换年份后的时间
|
||||||
|
*/
|
||||||
|
private DateTime resetDateTimeYear(DateTime dateTime, Integer year) {
|
||||||
|
if (dateTime == null || year == null) {
|
||||||
|
return dateTime;
|
||||||
|
}
|
||||||
|
LocalDateTime sourceTime = LocalDateTime.ofInstant(dateTime.toInstant(), ZoneId.systemDefault());
|
||||||
|
int dayOfMonth = (int) Math.min(sourceTime.getDayOfMonth(), sourceTime.withYear(year).range(ChronoField.DAY_OF_MONTH).getMaximum());
|
||||||
|
LocalDateTime targetTime = sourceTime.withYear(year).withDayOfMonth(dayOfMonth);
|
||||||
|
return new DateTime(java.util.Date.from(targetTime.atZone(ZoneId.systemDefault()).toInstant()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复制上一年度标段时清空主键和配置外键,让数据库生成当前年度独立数据。
|
||||||
|
*
|
||||||
|
* @param config 待复制配置
|
||||||
|
*/
|
||||||
|
private void copyLotsToNewConfig(TheRapyRecuperationConfig config) {
|
||||||
|
if (config.getLots() == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (TheRapyRecuperationLot lot : config.getLots()) {
|
||||||
|
lot.setId(null);
|
||||||
|
lot.setConfigId(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NutMap getLotsById(String lotId) {
|
||||||
|
List<String> lineNames = new ArrayList<>();
|
||||||
|
List<String> baseNames = new ArrayList<>();
|
||||||
|
NutMap map = new NutMap();
|
||||||
|
List<TheRapyRecuperationLine> lineList = dao().query(TheRapyRecuperationLine.class, Cnd.where("lotId", "=", lotId));
|
||||||
|
if (!CollectionUtils.isEmpty(lineList)) {
|
||||||
|
lineList.forEach(v -> lineNames.add(v.getLineName()));
|
||||||
|
map.put("line", lineNames);
|
||||||
|
}
|
||||||
|
List<TheRapyRecuperationBaseManagement> managementList = dao().query(TheRapyRecuperationBaseManagement.class, Cnd.where("lotId", "=", lotId));
|
||||||
|
if (!CollectionUtils.isEmpty(managementList)) {
|
||||||
|
managementList.forEach(v -> baseNames.add(v.getBaseName()));
|
||||||
|
map.put("base", baseNames);
|
||||||
|
}
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteLotById(String lotId) {
|
||||||
|
Trans.exec(() -> {
|
||||||
|
dao().clear(TheRapyRecuperationLot.class, Cnd.where("id", "=", lotId));
|
||||||
|
List<TheRapyRecuperationLine> lineList = dao().query(TheRapyRecuperationLine.class, Cnd.where("lotId", "=", lotId));
|
||||||
|
if (!CollectionUtils.isEmpty(lineList)) {
|
||||||
|
lineList.forEach(v -> v.setLotId(null));
|
||||||
|
dao().update(lineList);
|
||||||
|
}
|
||||||
|
List<TheRapyRecuperationBaseManagement> managementList = dao().query(TheRapyRecuperationBaseManagement.class, Cnd.where("lotId", "=", lotId));
|
||||||
|
if (!CollectionUtils.isEmpty(managementList)) {
|
||||||
|
managementList.forEach(v -> v.setLotId(null));
|
||||||
|
dao().update(managementList);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
+113
-3
@@ -35,6 +35,7 @@ import org.nutz.lang.util.NutMap;
|
|||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.Period;
|
import java.time.Period;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@@ -543,8 +544,11 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
@Override
|
@Override
|
||||||
public Map<Boolean, String> validSignUpInfo(String loginName, TheRapyRecuperationEnroll enrollInfo) {
|
public Map<Boolean, String> validSignUpInfo(String loginName, TheRapyRecuperationEnroll enrollInfo) {
|
||||||
|
|
||||||
//配置信息
|
// 配置信息只取当前最新配置,避免报名校验和页面展示使用不同年度配置。
|
||||||
TheRapyRecuperationConfig config = dao().fetch(TheRapyRecuperationConfig.class);
|
TheRapyRecuperationConfig config = fetchLatestConfig();
|
||||||
|
if (config == null) {
|
||||||
|
return Map.of(false, "未找到最新疗休养配置,请联系管理员");
|
||||||
|
}
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(loginName) && loginName.startsWith("2025")) {
|
if (StrUtil.isNotBlank(loginName) && loginName.startsWith("2025")) {
|
||||||
return Map.of(false, "抱歉,您是今年新入职,不能报名!");
|
return Map.of(false, "抱歉,您是今年新入职,不能报名!");
|
||||||
@@ -710,7 +714,10 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<Boolean, String> validSignTime(TheRapyRecuperationEnroll currentEnroll) {
|
public Map<Boolean, String> validSignTime(TheRapyRecuperationEnroll currentEnroll) {
|
||||||
TheRapyRecuperationConfig config = dao().fetch(TheRapyRecuperationConfig.class, Cnd.NEW());
|
TheRapyRecuperationConfig config = fetchLatestConfig();
|
||||||
|
if (config == null) {
|
||||||
|
return Map.of(false, "未找到最新疗休养配置,请联系管理员");
|
||||||
|
}
|
||||||
DateTime signUpStartTime = null;
|
DateTime signUpStartTime = null;
|
||||||
DateTime signUpEndTime = null;
|
DateTime signUpEndTime = null;
|
||||||
if (StrUtil.isNotBlank(currentEnroll.getTakePartInLineId())) {
|
if (StrUtil.isNotBlank(currentEnroll.getTakePartInLineId())) {
|
||||||
@@ -729,7 +736,21 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取最新提交的疗休养配置。
|
||||||
|
*
|
||||||
|
* @return 最新疗休养配置
|
||||||
|
*/
|
||||||
|
private TheRapyRecuperationConfig fetchLatestConfig() {
|
||||||
|
return dao().fetch(TheRapyRecuperationConfig.class, Cnd.where("latestConfig", "=", true));
|
||||||
|
}
|
||||||
|
|
||||||
public Map<Boolean, String> validBaseManagementCount(String loginName, TheRapyRecuperationEnroll currentEnroll) {
|
public Map<Boolean, String> validBaseManagementCount(String loginName, TheRapyRecuperationEnroll currentEnroll) {
|
||||||
|
Map<Boolean, String> dailySignCountResult = validBaseManagementDailySignCount(currentEnroll);
|
||||||
|
if (dailySignCountResult != null && dailySignCountResult.containsKey(false)) {
|
||||||
|
return dailySignCountResult;
|
||||||
|
}
|
||||||
|
|
||||||
if(StrUtil.isBlank(currentEnroll.getId())) {
|
if(StrUtil.isBlank(currentEnroll.getId())) {
|
||||||
int count = dao().count(TheRapyRecuperationEnroll.class,
|
int count = dao().count(TheRapyRecuperationEnroll.class,
|
||||||
Cnd.where("takePartInBaseManagementId", "=", currentEnroll.getTakePartInBaseManagementId())
|
Cnd.where("takePartInBaseManagementId", "=", currentEnroll.getTakePartInBaseManagementId())
|
||||||
@@ -790,6 +811,95 @@ public class TheRapyRecuperationEnrollServiceImpl extends ViServiceImpl<TheRapyR
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验分段疗休养同一酒店每日最高报名人数,报名时间段中任意一天满员都不能继续报名。
|
||||||
|
*
|
||||||
|
* @param currentEnroll 当前报名信息
|
||||||
|
* @return 校验失败原因;返回 null 表示未配置上限或未触发限制
|
||||||
|
*/
|
||||||
|
public Map<Boolean, String> validBaseManagementDailySignCount(TheRapyRecuperationEnroll currentEnroll) {
|
||||||
|
if (StrUtil.isBlank(currentEnroll.getTakePartInBaseManagementId())
|
||||||
|
|| StrUtil.isBlank(currentEnroll.getSpecificTime())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
TheRapyRecuperationBaseManagement management = dao().fetch(TheRapyRecuperationBaseManagement.class, currentEnroll.getTakePartInBaseManagementId());
|
||||||
|
if (management == null || management.getMaxSignCount() == null || management.getMaxSignCount() <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<LocalDate> currentDays = parseSpecificTimeDays(currentEnroll.getSpecificTime());
|
||||||
|
for (LocalDate currentDay : currentDays) {
|
||||||
|
int signedCount = countBaseManagementSignUserByDay(currentEnroll, currentDay);
|
||||||
|
if (signedCount + 1 > management.getMaxSignCount()) {
|
||||||
|
return Map.of(false, "该酒店%s报名人数已满,请重新选择出行时间".formatted(currentDay.format(DateTimeFormatter.ofPattern("MM月dd日"))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计同一酒店已报名且出行时间覆盖指定日期的教职工人数。
|
||||||
|
*
|
||||||
|
* @param currentEnroll 当前报名信息
|
||||||
|
* @param currentDay 需要判断的日期
|
||||||
|
* @return 已覆盖该日期的报名人数
|
||||||
|
*/
|
||||||
|
private int countBaseManagementSignUserByDay(TheRapyRecuperationEnroll currentEnroll, LocalDate currentDay) {
|
||||||
|
Cnd cnd = Cnd.where("takePartInBaseManagementId", "=", currentEnroll.getTakePartInBaseManagementId())
|
||||||
|
.and("specificTime", "is not", null)
|
||||||
|
.and("isNormal", "=", true)
|
||||||
|
.and("stateId", "in", Lang.array(TheRapyRecuperationState.UNIT, TheRapyRecuperationState.LINEUNIT, TheRapyRecuperationState.SCHOOL, TheRapyRecuperationState.PASS))
|
||||||
|
.and("YEAR(signingUptime)", "=", DateUtil.thisYear());
|
||||||
|
if (StrUtil.isNotBlank(currentEnroll.getId())) {
|
||||||
|
cnd.and("id", "!=", currentEnroll.getId());
|
||||||
|
}
|
||||||
|
List<TheRapyRecuperationEnroll> enrolls = dao().query(TheRapyRecuperationEnroll.class, cnd);
|
||||||
|
int count = 0;
|
||||||
|
for (TheRapyRecuperationEnroll enroll : enrolls) {
|
||||||
|
List<LocalDate> signDays = parseSpecificTimeDays(enroll.getSpecificTime());
|
||||||
|
if (signDays.contains(currentDay)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 把“06月01日-06月03日”格式的报名时间拆成逐日日期,便于做每日容量判断。
|
||||||
|
*
|
||||||
|
* @param specificTime 报名时间段
|
||||||
|
* @return 报名时间段包含的所有日期
|
||||||
|
*/
|
||||||
|
private List<LocalDate> parseSpecificTimeDays(String specificTime) {
|
||||||
|
if (StrUtil.isBlank(specificTime) || !specificTime.contains("-")) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
String[] times = specificTime.split("-");
|
||||||
|
if (times.length != 2 || StrUtil.isBlank(times[0]) || StrUtil.isBlank(times[1])) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
|
||||||
|
LocalDate start;
|
||||||
|
LocalDate end;
|
||||||
|
try {
|
||||||
|
start = LocalDate.parse(DateUtil.thisYear() + "年" + times[0].trim(), formatter);
|
||||||
|
end = LocalDate.parse(DateUtil.thisYear() + "年" + times[1].trim(), formatter);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
if (end.isBefore(start)) {
|
||||||
|
end = end.plusYears(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<LocalDate> days = new ArrayList<>();
|
||||||
|
LocalDate current = start;
|
||||||
|
while (!current.isAfter(end)) {
|
||||||
|
days.add(current);
|
||||||
|
current = current.plusDays(1);
|
||||||
|
}
|
||||||
|
return days;
|
||||||
|
}
|
||||||
|
|
||||||
//判断一年报几次
|
//判断一年报几次
|
||||||
public Map<Boolean, String> validCountThisYear(String loginName, int travelFrequency, Boolean validHotel) {
|
public Map<Boolean, String> validCountThisYear(String loginName, int travelFrequency, Boolean validHotel) {
|
||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
|
|||||||
@@ -279,6 +279,10 @@
|
|||||||
<el-card class="mt10" shadow="never">
|
<el-card class="mt10" shadow="never">
|
||||||
<table-tool :app="this" label="筛选人员">
|
<table-tool :app="this" label="筛选人员">
|
||||||
<template #func>
|
<template #func>
|
||||||
|
<el-button v-if="is_sysadmin||is_A06"
|
||||||
|
type="primary" size="medium" icon="el-icon-printer" @click="openImport">
|
||||||
|
导入XLSX设置分组
|
||||||
|
</el-button>
|
||||||
<el-button @click="doExportUser"
|
<el-button @click="doExportUser"
|
||||||
size="medium"
|
size="medium"
|
||||||
type="primary" icon="el-icon-download">
|
type="primary" icon="el-icon-download">
|
||||||
@@ -349,6 +353,57 @@
|
|||||||
v-loading="settingLoading">确 定</el-button>
|
v-loading="settingLoading">确 定</el-button>
|
||||||
</span>
|
</span>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<el-dialog title="人员导入" :visible.sync="dialogVisible" width="50%" :close-on-click-modal="false" append-to-body>
|
||||||
|
<el-timeline>
|
||||||
|
<el-timeline-item timestamp="下载模板" placement="top">
|
||||||
|
<el-card>
|
||||||
|
<el-button size="medium" type=""
|
||||||
|
@click="window.open('/platform/activity/basic/scope/downloadImport')"
|
||||||
|
icon="el-icon-download">下载模板
|
||||||
|
</el-button>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
<el-timeline-item timestamp="上传文件" placement="top">
|
||||||
|
<el-card>
|
||||||
|
<el-upload
|
||||||
|
name="file"
|
||||||
|
ref="upload"
|
||||||
|
:on-remove="handleImportFileRemove"
|
||||||
|
:on-change="handleImportFileChange"
|
||||||
|
:auto-upload="false"
|
||||||
|
:limit="1"
|
||||||
|
:file-list="importData.fileList">
|
||||||
|
<el-button size="medium" type="" icon="el-icon-upload"
|
||||||
|
style="width: 200px">选择文件
|
||||||
|
</el-button>
|
||||||
|
<div class="el-upload__tip" slot="tip" style="color: #F56C6C">
|
||||||
|
只能上传 xls/xlsx 文件
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
<el-timeline-item placement="top" timestamp="导入结果">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<p>总记录数:{{ errorInfoData.totalCount }}</p>
|
||||||
|
<p>成功数:<span class="text-success">{{ errorInfoData.successCount }}</span></p>
|
||||||
|
<p>错误数:<span class="text-danger">{{ errorInfoData.errorCount }}</span></p>
|
||||||
|
<el-link @click="exportErrors" type="primary" v-if="errorInfoData.errorCount>0">下载错误记录
|
||||||
|
</el-link>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
</el-timeline>
|
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false" type="primary"
|
||||||
|
:disabled="importLoading">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="clearSearchCnd"
|
||||||
|
:loading="importLoading">清空查询条件</el-button>
|
||||||
|
<el-button type="primary" @click="doImport" :loading="importLoading">核对人员</el-button>
|
||||||
|
<el-button type="primary" @click="doImportSearch"
|
||||||
|
:loading="importLoading">查询人员</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -405,6 +460,7 @@ module.exports = {
|
|||||||
roleIds: [],
|
roleIds: [],
|
||||||
userId: [],
|
userId: [],
|
||||||
activityUserCnd: '',
|
activityUserCnd: '',
|
||||||
|
existsLoginNameRedisKey: '',
|
||||||
reverseSelection: false
|
reverseSelection: false
|
||||||
},
|
},
|
||||||
activityUnions: [],
|
activityUnions: [],
|
||||||
@@ -434,7 +490,18 @@ module.exports = {
|
|||||||
setGroupName: [{required: true, message: '请输入分组名称', trigger: ['blur', 'change']}]
|
setGroupName: [{required: true, message: '请输入分组名称', trigger: ['blur', 'change']}]
|
||||||
},
|
},
|
||||||
relatedSessionMenus: ['aca4d14498c145ceb5b24ed70776aae2', '733d7266652740a3aeac9da97ab5eeca', 'fe2d0768e26d4a80beeb159306bb8d01'],
|
relatedSessionMenus: ['aca4d14498c145ceb5b24ed70776aae2', '733d7266652740a3aeac9da97ab5eeca', 'fe2d0768e26d4a80beeb159306bb8d01'],
|
||||||
roleData: {}
|
roleData: {},
|
||||||
|
dialogVisible: false,
|
||||||
|
importLoading: false,
|
||||||
|
importData: {
|
||||||
|
fileList: [],
|
||||||
|
},
|
||||||
|
errorInfoData: {
|
||||||
|
totalCount: 0,
|
||||||
|
successCount: 0,
|
||||||
|
errorCount: 0,
|
||||||
|
errorList: [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -461,6 +528,88 @@ module.exports = {
|
|||||||
'user-cnd': httpVueLoader('/components/plugins/UserCnd.vue'),
|
'user-cnd': httpVueLoader('/components/plugins/UserCnd.vue'),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
exportErrors() {
|
||||||
|
const data = this.errorInfoData.errorList
|
||||||
|
const workbook = XLSX.utils.book_new()
|
||||||
|
const worksheet = XLSX.utils.json_to_sheet(data)
|
||||||
|
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
|
||||||
|
const excelBuffer = XLSX.write(workbook, {bookType: 'xlsx', type: 'array'})
|
||||||
|
const blob = new Blob([excelBuffer], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'})
|
||||||
|
const url = window.URL.createObjectURL(blob)
|
||||||
|
const link = document.createElement('a')
|
||||||
|
link.href = url
|
||||||
|
link.download = '核对记录.xlsx'
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
window.URL.revokeObjectURL(url)
|
||||||
|
},
|
||||||
|
doImportSearch() {
|
||||||
|
this.doSearch()
|
||||||
|
this.dialogVisible = false
|
||||||
|
},
|
||||||
|
doImport() {
|
||||||
|
if (this.importData.fileList.length === 0) {
|
||||||
|
this.notifyWarning("请选择文件!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const data = new FormData()
|
||||||
|
this.importData.fileList.forEach((val) => {
|
||||||
|
data.append("file", val.raw, val.raw.name)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.importLoading = true
|
||||||
|
$.ajax({
|
||||||
|
url: "/platform/activity/basic/scope/doImport",
|
||||||
|
type: "post",
|
||||||
|
data: data,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: (data) => {
|
||||||
|
this.importLoading = false
|
||||||
|
if (data.code === 0) {
|
||||||
|
this.notifySuccess("核对成功")
|
||||||
|
this.errorInfoData = data.data
|
||||||
|
this.$set(this.pageForm, "existsLoginNameRedisKey", data.data.existsLoginNameRedisKey)
|
||||||
|
} else {
|
||||||
|
this.notifyWarning("核对失败")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
this.notifyWarning("导入失败")
|
||||||
|
this.importLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
clearSearchCnd() {
|
||||||
|
const existsLoginNameRedisKey = this.pageForm.existsLoginNameRedisKey
|
||||||
|
this.$set(this.importData, "fileList", [])
|
||||||
|
this.errorInfoData = {
|
||||||
|
totalCount: 0,
|
||||||
|
successCount: 0,
|
||||||
|
errorCount: 0,
|
||||||
|
errorList: [],
|
||||||
|
}
|
||||||
|
this.$set(this.pageForm, "existsLoginNameRedisKey", "")
|
||||||
|
this.doSearch()
|
||||||
|
this.dialogVisible = false
|
||||||
|
$.get('/platform/activity/basic/scope/clearSearchCnd', {existsLoginNameRedisKey: existsLoginNameRedisKey}).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success(res.msg)
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
openImport() {
|
||||||
|
this.dialogVisible = true
|
||||||
|
},
|
||||||
|
handleImportFileRemove(file, fileList) {
|
||||||
|
this.$set(this.importData, "fileList", this.fileHandleRemove(file, fileList))
|
||||||
|
},
|
||||||
|
handleImportFileChange(file, fileList) {
|
||||||
|
this.$set(this.importData, "fileList", this.fileHandleChange(file, fileList, {type: ['xls', 'xlsx']}))
|
||||||
|
},
|
||||||
doExportUser() {
|
doExportUser() {
|
||||||
const {
|
const {
|
||||||
userId,
|
userId,
|
||||||
@@ -476,7 +625,8 @@ module.exports = {
|
|||||||
activityGroupId,
|
activityGroupId,
|
||||||
age,
|
age,
|
||||||
reverseSelection,
|
reverseSelection,
|
||||||
activityUserCnd
|
activityUserCnd,
|
||||||
|
existsLoginNameRedisKey
|
||||||
} = this.pageForm
|
} = this.pageForm
|
||||||
|
|
||||||
let props = {}
|
let props = {}
|
||||||
@@ -495,6 +645,7 @@ module.exports = {
|
|||||||
"&reverseSelection=" + reverseSelection +
|
"&reverseSelection=" + reverseSelection +
|
||||||
"&clubId=" + clubId +
|
"&clubId=" + clubId +
|
||||||
"&activityGroupId=" + activityGroupId +
|
"&activityGroupId=" + activityGroupId +
|
||||||
|
"&existsLoginNameRedisKey=" + existsLoginNameRedisKey +
|
||||||
"&teacherMeetingId=" + teacherMeetingId +
|
"&teacherMeetingId=" + teacherMeetingId +
|
||||||
"&unionId=" + unionId +
|
"&unionId=" + unionId +
|
||||||
"&unitId=" + unitId
|
"&unitId=" + unitId
|
||||||
@@ -514,6 +665,7 @@ module.exports = {
|
|||||||
this.pageForm.clubId = ''
|
this.pageForm.clubId = ''
|
||||||
this.pageForm.activityGroupId = ''
|
this.pageForm.activityGroupId = ''
|
||||||
this.pageForm.activityUserCnd = ''
|
this.pageForm.activityUserCnd = ''
|
||||||
|
this.pageForm.existsLoginNameRedisKey = ''
|
||||||
this.pageForm.age = [0, 0]
|
this.pageForm.age = [0, 0]
|
||||||
this.pageForm.reverseSelection = false
|
this.pageForm.reverseSelection = false
|
||||||
this.doSearch()
|
this.doSearch()
|
||||||
|
|||||||
Binary file not shown.
@@ -527,6 +527,7 @@ layout("/mobile/platform.html"){
|
|||||||
minDate: new Date(2010, 0, 1),
|
minDate: new Date(2010, 0, 1),
|
||||||
maxDate: new Date(2010, 0, 31),
|
maxDate: new Date(2010, 0, 31),
|
||||||
holidays: [],
|
holidays: [],
|
||||||
|
fullDays: [],
|
||||||
timeVisible: false,
|
timeVisible: false,
|
||||||
active: 0,
|
active: 0,
|
||||||
tarBarActive: 0,
|
tarBarActive: 0,
|
||||||
@@ -623,6 +624,12 @@ layout("/mobile/platform.html"){
|
|||||||
this.$refs.cal.reset(null)
|
this.$refs.cal.reset(null)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
if(this.fullDays.includes(afterDateStr)) {
|
||||||
|
this.$toast(afterDateStr + '报名人数已满,请更换出行时间')
|
||||||
|
this.chooseDate = []
|
||||||
|
this.$refs.cal.reset(null)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
this.chooseDate.push(afterDateStr)
|
this.chooseDate.push(afterDateStr)
|
||||||
if(i === (this.lotValue - 1)) {
|
if(i === (this.lotValue - 1)) {
|
||||||
@@ -639,6 +646,10 @@ layout("/mobile/platform.html"){
|
|||||||
if(this.timeArray.indexOf(date) === -1) {
|
if(this.timeArray.indexOf(date) === -1) {
|
||||||
day.type = 'disabled'
|
day.type = 'disabled'
|
||||||
}
|
}
|
||||||
|
if(this.fullDays.includes(date)) {
|
||||||
|
day.type = 'disabled'
|
||||||
|
day.bottomInfo = '已满'
|
||||||
|
}
|
||||||
if(this.chooseDate.length > 0 && this.chooseDate.includes(date)) {
|
if(this.chooseDate.length > 0 && this.chooseDate.includes(date)) {
|
||||||
day.className = 'cal_middle'
|
day.className = 'cal_middle'
|
||||||
if(date === this.chooseDate[this.chooseDate.length - 1]) {
|
if(date === this.chooseDate[this.chooseDate.length - 1]) {
|
||||||
@@ -801,6 +812,7 @@ layout("/mobile/platform.html"){
|
|||||||
})
|
})
|
||||||
this.timeArray = res.data.days
|
this.timeArray = res.data.days
|
||||||
this.holidays = res.data.holidays
|
this.holidays = res.data.holidays
|
||||||
|
this.$set(this, 'fullDays', res.data.fullDays || [])
|
||||||
//this.lotValue = Number(res.data.lotValue)
|
//this.lotValue = Number(res.data.lotValue)
|
||||||
this.minDate = new Date(res.data.minDate)
|
this.minDate = new Date(res.data.minDate)
|
||||||
this.maxDate = new Date(res.data.maxDate)
|
this.maxDate = new Date(res.data.maxDate)
|
||||||
|
|||||||
+17
-2
@@ -96,6 +96,9 @@ layout("/layouts/platform.html"){
|
|||||||
<span v-if="row.lotId===item.id">{{item.lotName}}</span>
|
<span v-if="row.lotId===item.id">{{item.lotName}}</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<template scope="{row}" v-else-if="column.prop==='maxSignCount'">
|
||||||
|
<span>{{row.maxSignCount == null || row.maxSignCount === '' || Number(row.maxSignCount) <= 0 ? '无限制' : row.maxSignCount}}</span>
|
||||||
|
</template>
|
||||||
<template scope="{row}" v-else-if="column.prop==='createUserName'">
|
<template scope="{row}" v-else-if="column.prop==='createUserName'">
|
||||||
{{row.createUserName + '(' + row.createUnionName + ')'}}
|
{{row.createUserName + '(' + row.createUnionName + ')'}}
|
||||||
</template>
|
</template>
|
||||||
@@ -202,7 +205,7 @@ layout("/layouts/platform.html"){
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :md="6" :sm="24" :xs="24">
|
<el-col :md="12" :sm="24" :xs="24">
|
||||||
<el-form-item label="活动范围" prop="regionalNature">
|
<el-form-item label="活动范围" prop="regionalNature">
|
||||||
<el-radio-group size="small" v-model="formData.regionalNature">
|
<el-radio-group size="small" v-model="formData.regionalNature">
|
||||||
<el-radio label="省内" border>省内</el-radio>
|
<el-radio label="省内" border>省内</el-radio>
|
||||||
@@ -210,7 +213,16 @@ layout("/layouts/platform.html"){
|
|||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :md="6" :sm="24" :xs="24">
|
<el-col :md="12" :sm="24" :xs="24">
|
||||||
|
<el-form-item label="每日最高人数" prop="maxSignCount">
|
||||||
|
<el-input-number :min="0" :precision="0" placeholder="0为不限制"
|
||||||
|
style="width: 100%" v-model="formData.maxSignCount"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :md="12" :sm="24" :xs="24">
|
||||||
<el-form-item label="周几入住" prop="weekIn">
|
<el-form-item label="周几入住" prop="weekIn">
|
||||||
<el-radio-group size="small" v-model="formData.weekIn" @input="weekChange">
|
<el-radio-group size="small" v-model="formData.weekIn" @input="weekChange">
|
||||||
<el-radio :label="1" border>不限</el-radio>
|
<el-radio :label="1" border>不限</el-radio>
|
||||||
@@ -508,6 +520,7 @@ layout("/layouts/platform.html"){
|
|||||||
baseContactNumber: '',
|
baseContactNumber: '',
|
||||||
weekIn: 1,
|
weekIn: 1,
|
||||||
allowDay: [],
|
allowDay: [],
|
||||||
|
maxSignCount: 0,
|
||||||
travelAgencyPlace: '',
|
travelAgencyPlace: '',
|
||||||
},
|
},
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
@@ -515,6 +528,7 @@ layout("/layouts/platform.html"){
|
|||||||
{label: '目的地名称', prop: 'baseName', sortable: true},
|
{label: '目的地名称', prop: 'baseName', sortable: true},
|
||||||
{label: '承担旅行社', prop: 'travelAgencyName', sortable: true},
|
{label: '承担旅行社', prop: 'travelAgencyName', sortable: true},
|
||||||
//{label: '标段时间', prop: 'lotId', sortable: true},
|
//{label: '标段时间', prop: 'lotId', sortable: true},
|
||||||
|
{label: '每日最高人数', prop: 'maxSignCount', sortable: true},
|
||||||
{label: '联系人', prop: 'baseContactPerson', sortable: true},
|
{label: '联系人', prop: 'baseContactPerson', sortable: true},
|
||||||
{label: '联系人电话', prop: 'baseContactNumber', sortable: true},
|
{label: '联系人电话', prop: 'baseContactNumber', sortable: true},
|
||||||
//{label: '活动时间', prop: 'activityTime', sortable: true},
|
//{label: '活动时间', prop: 'activityTime', sortable: true},
|
||||||
@@ -543,6 +557,7 @@ layout("/layouts/platform.html"){
|
|||||||
activityEndTime: [{required: true, validator: validateActivityEndTime, trigger: ['change', 'blur']}],
|
activityEndTime: [{required: true, validator: validateActivityEndTime, trigger: ['change', 'blur']}],
|
||||||
estimatedCost: [{required: true, message: '请输入预计费用', trigger: ['change', 'blur']}],
|
estimatedCost: [{required: true, message: '请输入预计费用', trigger: ['change', 'blur']}],
|
||||||
allowDay: [{required: true, message: '请选择天数', trigger: ['change', 'blur']}],
|
allowDay: [{required: true, message: '请选择天数', trigger: ['change', 'blur']}],
|
||||||
|
maxSignCount: [{required: false, message: '请输入每日最高人数', trigger: ['change', 'blur']}],
|
||||||
travelAgencyPlace: [{required: true, message: '请选择旅行社地点', trigger: ['change', 'blur']}],
|
travelAgencyPlace: [{required: true, message: '请选择旅行社地点', trigger: ['change', 'blur']}],
|
||||||
},
|
},
|
||||||
//目的地导入
|
//目的地导入
|
||||||
|
|||||||
+98
-3
@@ -171,6 +171,8 @@ layout("/layouts/platform.html"){
|
|||||||
<template #func>
|
<template #func>
|
||||||
<!-- <el-button icon="el-icon-s-promotion" @click="openImport" size="small" type="primary">参加人员导入-->
|
<!-- <el-button icon="el-icon-s-promotion" @click="openImport" size="small" type="primary">参加人员导入-->
|
||||||
<!-- </el-button>-->
|
<!-- </el-button>-->
|
||||||
|
<el-button icon="el-icon-upload" @click="openImport" size="small" type="primary">参加人员导入
|
||||||
|
</el-button>
|
||||||
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
|
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
|
||||||
导出未报名人员
|
导出未报名人员
|
||||||
</el-button>
|
</el-button>
|
||||||
@@ -282,6 +284,48 @@ layout("/layouts/platform.html"){
|
|||||||
<set-up-part ref="setUpRef"></set-up-part>
|
<set-up-part ref="setUpRef"></set-up-part>
|
||||||
|
|
||||||
<edit-form ref="editRef" @refresh="doSearch"></edit-form>
|
<edit-form ref="editRef" @refresh="doSearch"></edit-form>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
title="参加人员导入"
|
||||||
|
:visible.sync="importVisible"
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
width="50%">
|
||||||
|
<el-timeline>
|
||||||
|
<el-timeline-item timestamp="下载模板" placement="top">
|
||||||
|
<el-card>
|
||||||
|
<el-button size="medium" type=""
|
||||||
|
@click="downloadImportTemplate"
|
||||||
|
icon="el-icon-download">下载模板
|
||||||
|
</el-button>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
<el-timeline-item timestamp="上传文件" placement="top">
|
||||||
|
<el-card>
|
||||||
|
<el-form>
|
||||||
|
<el-upload
|
||||||
|
name="file"
|
||||||
|
ref="upload"
|
||||||
|
:on-remove="handleImportFileRemove"
|
||||||
|
:on-change="handleImportFileChange"
|
||||||
|
:auto-upload="false"
|
||||||
|
:limit="1"
|
||||||
|
:file-list="importData.fileList">
|
||||||
|
<el-button size="medium" type="" icon="el-icon-upload" style="width: 200px">选择文件
|
||||||
|
</el-button>
|
||||||
|
<div class="el-upload__tip" slot="tip" style="color: #F56C6C">
|
||||||
|
只能上传 xls/xlsx 文件,时间格式请书写为2008-10-1
|
||||||
|
</div>
|
||||||
|
</el-upload>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
</el-timeline-item>
|
||||||
|
</el-timeline>
|
||||||
|
|
||||||
|
<span slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="importVisibleClose" :disabled="importLoading">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="doImport" :loading="importLoading">确定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -318,11 +362,17 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'lineOrMaName', label: '线路'},
|
{prop: 'lineOrMaName', label: '线路'},
|
||||||
{prop: 'times', label: '出行时间'},
|
{prop: 'times', label: '出行时间'},
|
||||||
{prop: 'isFamily', label: '是否携带家属'},
|
{prop: 'isFamily', label: '是否携带家属'},
|
||||||
{prop: 'isTakePartIn', label: '是否参加'}
|
{prop: 'isTakePartIn', label: '是否参加', sortable: true}
|
||||||
],
|
],
|
||||||
viewVisible: false,
|
viewVisible: false,
|
||||||
unionOptions: [],
|
unionOptions: [],
|
||||||
config: {}
|
config: {},
|
||||||
|
// 参加人员导入弹窗和文件上传状态。
|
||||||
|
importVisible: false,
|
||||||
|
importLoading: false,
|
||||||
|
importData: {
|
||||||
|
fileList: []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@@ -389,7 +439,52 @@ layout("/layouts/platform.html"){
|
|||||||
},
|
},
|
||||||
|
|
||||||
openImport() {
|
openImport() {
|
||||||
|
this.$set(this.importData, 'fileList', [])
|
||||||
|
this.importVisible = true
|
||||||
|
},
|
||||||
|
handleImportFileRemove(file, fileList) {
|
||||||
|
this.$set(this.importData, 'fileList', this.fileHandleRemove(file, fileList))
|
||||||
|
},
|
||||||
|
handleImportFileChange(file, fileList) {
|
||||||
|
this.$set(this.importData, 'fileList', this.fileHandleChange(file, fileList, {type: ['xls', 'xlsx']}))
|
||||||
|
},
|
||||||
|
downloadImportTemplate() {
|
||||||
|
window.open('/platform/theRapyRecuperation/user/query/downloadImportTemplate')
|
||||||
|
},
|
||||||
|
doImport() {
|
||||||
|
if (this.importData.fileList.length === 0) {
|
||||||
|
this.$message.warning('请选择文件!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const data = new FormData()
|
||||||
|
this.importData.fileList.forEach((val) => {
|
||||||
|
data.append('file', val.raw, val.raw.name)
|
||||||
|
})
|
||||||
|
this.importLoading = true
|
||||||
|
$.ajax({
|
||||||
|
url: '/platform/theRapyRecuperation/user/query/enrollImport',
|
||||||
|
type: 'post',
|
||||||
|
data: data,
|
||||||
|
processData: false,
|
||||||
|
contentType: false,
|
||||||
|
success: (resp) => {
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.importVisible = false
|
||||||
|
this.doSearch()
|
||||||
|
} else {
|
||||||
|
this.$message.warning(resp.msg)
|
||||||
|
}
|
||||||
|
this.importLoading = false
|
||||||
|
},
|
||||||
|
error: () => {
|
||||||
|
this.$message.warning('导入失败')
|
||||||
|
this.importLoading = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
importVisibleClose() {
|
||||||
|
this.importVisible = false
|
||||||
|
this.doSearch()
|
||||||
},
|
},
|
||||||
noSignExport() {
|
noSignExport() {
|
||||||
window.open('/platform/theRapyRecuperation/schoolUnionUserQuery/noSignExport')
|
window.open('/platform/theRapyRecuperation/schoolUnionUserQuery/noSignExport')
|
||||||
|
|||||||
+122
-47
@@ -27,6 +27,16 @@ layout("/layouts/platform.html"){
|
|||||||
<h3 style="color: rgb(24, 103, 176);font-family: Microsoft YaHei;">疗休养配置</h3>
|
<h3 style="color: rgb(24, 103, 176);font-family: Microsoft YaHei;">疗休养配置</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px;">
|
||||||
|
<el-select v-model="currentYear" style="width: 160px;" @change="changeYear">
|
||||||
|
<el-option v-for="item in yearOptions"
|
||||||
|
:key="item"
|
||||||
|
:label="item + '年度'"
|
||||||
|
:value="item"></el-option>
|
||||||
|
</el-select>
|
||||||
|
<el-button type="primary" plain @click="copyLastYear" :loading="copyLoading">沿用去年配置</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-form ref="addForm" :model="formData" :rules="formRules" label-width="170px">
|
<el-form ref="addForm" :model="formData" :rules="formRules" label-width="170px">
|
||||||
<vi-title title="基本配置"></vi-title>
|
<vi-title title="基本配置"></vi-title>
|
||||||
<el-form-item label="配置名称" prop="configName">
|
<el-form-item label="配置名称" prop="configName">
|
||||||
@@ -326,10 +336,18 @@ layout("/layouts/platform.html"){
|
|||||||
const vue = new Vue({
|
const vue = new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
data() {
|
data() {
|
||||||
|
const startYear = 2025
|
||||||
|
const yearOptions = [startYear, startYear + 1, startYear + 2, startYear + 3, startYear + 4]
|
||||||
|
const nowYear = new Date().getFullYear()
|
||||||
|
const currentYear = yearOptions.includes(nowYear) ? nowYear : startYear
|
||||||
return {
|
return {
|
||||||
|
currentYear: currentYear,
|
||||||
|
yearOptions: yearOptions,
|
||||||
activityGroupList: [],
|
activityGroupList: [],
|
||||||
subLoading: false,
|
subLoading: false,
|
||||||
|
copyLoading: false,
|
||||||
formData: {
|
formData: {
|
||||||
|
configYear: currentYear,
|
||||||
isSnLine: 0,
|
isSnLine: 0,
|
||||||
isSwLine: 0,
|
isSwLine: 0,
|
||||||
lots: [],
|
lots: [],
|
||||||
@@ -384,6 +402,52 @@ layout("/layouts/platform.html"){
|
|||||||
'drawer-user-scope': httpVueLoader('/components/plugins/DrawerUserScope.vue?v=1.0.1'),
|
'drawer-user-scope': httpVueLoader('/components/plugins/DrawerUserScope.vue?v=1.0.1'),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getDefaultFormData(configYear) {
|
||||||
|
return {
|
||||||
|
configYear: configYear,
|
||||||
|
isSnLine: 0,
|
||||||
|
isSwLine: 0,
|
||||||
|
lots: [],
|
||||||
|
configName: '智慧工会疗休养配置',
|
||||||
|
outsideQuota: null,
|
||||||
|
outsideQuotaProportion: 0,
|
||||||
|
outsideNumber: null,
|
||||||
|
travelFrequency: null,
|
||||||
|
groupNumber: null,
|
||||||
|
modifyDays: null,
|
||||||
|
modifyNumber: null,
|
||||||
|
allLineSignUpNumber: null,
|
||||||
|
notice: null,
|
||||||
|
provinceStartYear: null,
|
||||||
|
bedInfo: true,
|
||||||
|
familyInfo: 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async changeYear() {
|
||||||
|
await this.findOne()
|
||||||
|
},
|
||||||
|
async copyLastYear() {
|
||||||
|
if (this.formData.id) {
|
||||||
|
const confirm = await this.$confirm('当前年度已有配置,沿用去年配置会覆盖当前年度配置,是否继续?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
if (confirm !== 'confirm') return
|
||||||
|
}
|
||||||
|
this.$set(this, 'copyLoading', true)
|
||||||
|
try {
|
||||||
|
const resp = await $.post(loc() + '/copyLastYear', {year: this.currentYear})
|
||||||
|
if (resp.code === 0 && resp.data) {
|
||||||
|
this.$notify.success({title: '成功', message: '已沿用去年配置'});
|
||||||
|
await this.findOne()
|
||||||
|
} else {
|
||||||
|
this.$notify.warning({title: '提示', message: resp.msg || '上一年度暂无可沿用配置'});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this.$set(this, 'copyLoading', false)
|
||||||
|
}
|
||||||
|
},
|
||||||
async deleteLotsRow(scope) {
|
async deleteLotsRow(scope) {
|
||||||
//this.lotDeleteList.push(scope.row.id);
|
//this.lotDeleteList.push(scope.row.id);
|
||||||
//console.log(this.lotDeleteList)
|
//console.log(this.lotDeleteList)
|
||||||
@@ -424,72 +488,83 @@ layout("/layouts/platform.html"){
|
|||||||
spinner: 'el-icon-loading',
|
spinner: 'el-icon-loading',
|
||||||
background: COVER_LAYER_COLOR
|
background: COVER_LAYER_COLOR
|
||||||
})
|
})
|
||||||
const cloneData = clone(this.formData)
|
try {
|
||||||
|
const cloneData = clone(this.formData)
|
||||||
|
cloneData.configYear = this.currentYear
|
||||||
|
|
||||||
if(this.formData.createLineTimes && this.formData.createLineTimes.length > 0) {
|
if(this.formData.createLineTimes && this.formData.createLineTimes.length > 0) {
|
||||||
cloneData.createLineStartTime = this.formData.createLineTimes[0]
|
cloneData.createLineStartTime = this.formData.createLineTimes[0]
|
||||||
cloneData.createLineEndTime = this.formData.createLineTimes[1]
|
cloneData.createLineEndTime = this.formData.createLineTimes[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.formData.implodeTimes && this.formData.implodeTimes.length > 0) {
|
if(this.formData.implodeTimes && this.formData.implodeTimes.length > 0) {
|
||||||
cloneData.implodeStartTime = this.formData.implodeTimes[0]
|
cloneData.implodeStartTime = this.formData.implodeTimes[0]
|
||||||
cloneData.implodeEndTime = this.formData.implodeTimes[1]
|
cloneData.implodeEndTime = this.formData.implodeTimes[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.formData.fragmentTimes && this.formData.fragmentTimes.length > 0) {
|
if(this.formData.fragmentTimes && this.formData.fragmentTimes.length > 0) {
|
||||||
cloneData.fragmentStartTime = this.formData.fragmentTimes[0]
|
cloneData.fragmentStartTime = this.formData.fragmentTimes[0]
|
||||||
cloneData.fragmentEndTime = this.formData.fragmentTimes[1]
|
cloneData.fragmentEndTime = this.formData.fragmentTimes[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.formData.fragmentPlayTimes && this.formData.fragmentPlayTimes.length > 0) {
|
if(this.formData.fragmentPlayTimes && this.formData.fragmentPlayTimes.length > 0) {
|
||||||
cloneData.fragmentPlayStartTime = this.formData.fragmentPlayTimes[0]
|
cloneData.fragmentPlayStartTime = this.formData.fragmentPlayTimes[0]
|
||||||
cloneData.fragmentPlayEndTime = this.formData.fragmentPlayTimes[1]
|
cloneData.fragmentPlayEndTime = this.formData.fragmentPlayTimes[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.formData.files && this.formData.files.length > 0) {
|
delete cloneData.createLineTimes
|
||||||
cloneData.files = JSON.stringify(this.formData.files)
|
delete cloneData.implodeTimes
|
||||||
}
|
delete cloneData.fragmentTimes
|
||||||
if (this.lotDeleteList && this.lotDeleteList.length > 0) {
|
delete cloneData.fragmentPlayTimes
|
||||||
cloneData.lotDeleteList = JSON.stringify(this.lotDeleteList)
|
|
||||||
}
|
if (this.formData.files && this.formData.files.length > 0) {
|
||||||
if (this.formData.lots && this.formData.lots.length > 0) {
|
cloneData.files = JSON.stringify(this.formData.files)
|
||||||
cloneData.lots = JSON.stringify(this.formData.lots)
|
}
|
||||||
}
|
if (this.lotDeleteList && this.lotDeleteList.length > 0) {
|
||||||
cloneData.outsideQuotaProportion = cloneData.outsideQuotaProportion / 100
|
cloneData.lotDeleteList = JSON.stringify(this.lotDeleteList)
|
||||||
const resp = await $.post(loc() + "/operation", cloneData)
|
}
|
||||||
if (resp.code === 0){
|
if (this.formData.lots && this.formData.lots.length > 0) {
|
||||||
this.$notify.success({title: '成功', message: resp.msg});
|
cloneData.lots = JSON.stringify(this.formData.lots)
|
||||||
|
}
|
||||||
|
cloneData.outsideQuotaProportion = cloneData.outsideQuotaProportion / 100
|
||||||
|
const resp = await $.post(loc() + "/operation", cloneData)
|
||||||
|
if (resp.code === 0){
|
||||||
|
this.$notify.success({title: '成功', message: resp.msg});
|
||||||
|
await this.findOne()
|
||||||
|
}else {
|
||||||
|
this.$notify.error({title: '失败', message: resp.msg});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
loading.close()
|
loading.close()
|
||||||
this.subLoading = false
|
this.subLoading = false
|
||||||
}else {
|
|
||||||
this.$notify.error({title: '失败', message: resp.msg});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async findOne() {
|
async findOne() {
|
||||||
await this.getActivityGroup()
|
await this.getActivityGroup()
|
||||||
const {data} = await $.get(loc() + "/findOne")
|
const {data} = await $.get(loc() + "/findOne", {year: this.currentYear})
|
||||||
if (data.outsideQuotaProportion) {
|
const formData = data || this.getDefaultFormData(this.currentYear)
|
||||||
data.outsideQuotaProportion = data.outsideQuotaProportion * 1000 / 10
|
this.$set(formData, 'configYear', this.currentYear)
|
||||||
|
if (formData.outsideQuotaProportion) {
|
||||||
|
this.$set(formData, 'outsideQuotaProportion', formData.outsideQuotaProportion * 1000 / 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data.createLineStartTime && data.createLineEndTime) {
|
if(formData.createLineStartTime && formData.createLineEndTime) {
|
||||||
data.createLineTimes = [data.createLineStartTime, data.createLineEndTime]
|
this.$set(formData, 'createLineTimes', [formData.createLineStartTime, formData.createLineEndTime])
|
||||||
}
|
}
|
||||||
if(data.implodeStartTime && data.implodeEndTime) {
|
if(formData.implodeStartTime && formData.implodeEndTime) {
|
||||||
data.implodeTimes = [data.implodeStartTime, data.implodeEndTime]
|
this.$set(formData, 'implodeTimes', [formData.implodeStartTime, formData.implodeEndTime])
|
||||||
}
|
}
|
||||||
if(data.fragmentStartTime && data.fragmentEndTime) {
|
if(formData.fragmentStartTime && formData.fragmentEndTime) {
|
||||||
data.fragmentTimes = [data.fragmentStartTime, data.fragmentEndTime]
|
this.$set(formData, 'fragmentTimes', [formData.fragmentStartTime, formData.fragmentEndTime])
|
||||||
}
|
}
|
||||||
if(data.fragmentPlayStartTime && data.fragmentPlayEndTime) {
|
if(formData.fragmentPlayStartTime && formData.fragmentPlayEndTime) {
|
||||||
data.fragmentPlayTimes = [data.fragmentPlayStartTime, data.fragmentPlayEndTime]
|
this.$set(formData, 'fragmentPlayTimes', [formData.fragmentPlayStartTime, formData.fragmentPlayEndTime])
|
||||||
}
|
}
|
||||||
if (!data.lots) {
|
if (!formData.lots) {
|
||||||
data.lots = []
|
this.$set(formData, 'lots', [])
|
||||||
}
|
}
|
||||||
this.formData = data
|
this.$set(this, 'formData', formData)
|
||||||
},
|
},
|
||||||
async getActivityGroup() {
|
async getActivityGroup() {
|
||||||
const {data} = await $.get('/platform/activity/basic/scope/getActivityUserScopeGroup')
|
const {data} = await $.get('/platform/activity/basic/scope/getActivityUserScopeGroup')
|
||||||
|
|||||||
Reference in New Issue
Block a user