Merge branch 'main' of https://dd3skj.picp.vip/zhaoxinyu/zhgh_njnu
This commit is contained in:
@@ -176,9 +176,9 @@ public class SysHomeController {
|
||||
Date startDate = activity.getStartDate();
|
||||
Date endDate = activity.getEndDate();
|
||||
// 判断当前时间是否在活动范围内,不在就过滤掉
|
||||
// if (!DateUtil.isIn(today, startDate, endDate)) {
|
||||
// continue;
|
||||
// }
|
||||
if (!DateUtil.isIn(today, startDate, endDate)) {
|
||||
continue;
|
||||
}
|
||||
Integer allowUserGroupId = activity.getAllowUserGroupId();
|
||||
String allowUserSql = activity.getAllowUserSql();
|
||||
activity.setAllowUserSql(null);
|
||||
|
||||
@@ -176,7 +176,97 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
// cnd = ConditionGroupUtil.applyConditionGroup(cnd, updateParam.getConditionGroup());
|
||||
}
|
||||
|
||||
// 特别人员
|
||||
List<SpecialStaff> specialStaffs = dao.query(SpecialStaff.class, Cnd.NEW());
|
||||
List<SpecialStaff> specialManyUnitStaffs = specialStaffs.stream().filter(SpecialStaff::getIsManyUnit).toList();
|
||||
List<String> specialManyUnitStaffUserIds = specialManyUnitStaffs.stream().map(SpecialStaff::getUserId).toList();
|
||||
List<String> specialManyUnitStaffUserLoginNames = dao.query(Sys_user.class, Cnd.where(Sys_user::getId, "in", specialManyUnitStaffUserIds)).stream().map(Sys_user::getLoginname).toList();
|
||||
|
||||
// 排除掉多单位人员不更新
|
||||
cnd.andEX(Sys_user_source::getLoginname, "not in", specialManyUnitStaffUserLoginNames);
|
||||
|
||||
|
||||
List<String> bsh = new ArrayList<>();
|
||||
bsh.add("91036");
|
||||
bsh.add("91035");
|
||||
bsh.add("91030");
|
||||
bsh.add("91034");
|
||||
bsh.add("91033");
|
||||
bsh.add("91031");
|
||||
bsh.add("91032");
|
||||
bsh.add("91027");
|
||||
bsh.add("91026");
|
||||
bsh.add("91024");
|
||||
bsh.add("91025");
|
||||
bsh.add("91023");
|
||||
bsh.add("91021");
|
||||
bsh.add("91020");
|
||||
bsh.add("91022");
|
||||
bsh.add("91018");
|
||||
bsh.add("91015");
|
||||
bsh.add("91017");
|
||||
bsh.add("91014");
|
||||
bsh.add("91013");
|
||||
bsh.add("91012");
|
||||
bsh.add("91011");
|
||||
bsh.add("91008");
|
||||
bsh.add("91004");
|
||||
bsh.add("90996");
|
||||
bsh.add("90994");
|
||||
bsh.add("90992");
|
||||
bsh.add("90993");
|
||||
bsh.add("90991");
|
||||
bsh.add("90990");
|
||||
bsh.add("90979");
|
||||
bsh.add("90978");
|
||||
bsh.add("90976");
|
||||
bsh.add("90975");
|
||||
bsh.add("90974");
|
||||
bsh.add("90972");
|
||||
bsh.add("90971");
|
||||
bsh.add("90973");
|
||||
bsh.add("90969");
|
||||
bsh.add("90966");
|
||||
bsh.add("90967");
|
||||
bsh.add("90965");
|
||||
bsh.add("90964");
|
||||
bsh.add("90968");
|
||||
bsh.add("90959");
|
||||
bsh.add("90957");
|
||||
bsh.add("90958");
|
||||
bsh.add("90961");
|
||||
bsh.add("90960");
|
||||
bsh.add("90952");
|
||||
bsh.add("90950");
|
||||
bsh.add("90951");
|
||||
bsh.add("90953");
|
||||
bsh.add("90954");
|
||||
bsh.add("90948");
|
||||
bsh.add("90947");
|
||||
bsh.add("90949");
|
||||
bsh.add("90946");
|
||||
bsh.add("90942");
|
||||
bsh.add("90937");
|
||||
bsh.add("90935");
|
||||
bsh.add("90934");
|
||||
bsh.add("90933");
|
||||
bsh.add("90932");
|
||||
bsh.add("90930");
|
||||
bsh.add("90927");
|
||||
bsh.add("90926");
|
||||
bsh.add("90913");
|
||||
bsh.add("90906");
|
||||
bsh.add("90904");
|
||||
bsh.add("90903");
|
||||
bsh.add("90901");
|
||||
bsh.add("90899");
|
||||
bsh.add("90898");
|
||||
bsh.add("90895");
|
||||
bsh.add("90894");
|
||||
|
||||
// cnd.and(Sys_user_source::getLoginname, "in", bsh);
|
||||
List<Sys_user_source> sources = dao.query(Sys_user_source.class, cnd.groupBy("loginname"));
|
||||
|
||||
log.info("符合条件的数据源记录数: {}", sources.size());
|
||||
|
||||
// 查询系统用户
|
||||
@@ -190,10 +280,9 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
List<String> addMemberUserIds = Collections.synchronizedList(new ArrayList<>());
|
||||
List<String> removeMemberUserIds = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
|
||||
// 处理每条数据
|
||||
for (Sys_user_source source : sources) {
|
||||
source.setMember(null);
|
||||
source.setWelfareMember(null);
|
||||
|
||||
Sys_user user = userMap.get(source.getLoginname());
|
||||
|
||||
@@ -231,6 +320,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
} else {
|
||||
// 修改现有用户
|
||||
u.setId(user.getId());
|
||||
u.setMember(user.getMember());
|
||||
|
||||
// 本人电话、身份证不覆盖
|
||||
if (StrUtil.isNotBlank(user.getMobile())) {
|
||||
@@ -280,6 +370,7 @@ public class SysDataUserAllUpdateServiceImpl implements SysDataUserUpdateService
|
||||
|
||||
// 1. 新增用户 - 使用批量处理
|
||||
if (Lang.isNotEmpty(needInitUserList)) {
|
||||
// dao.fastInsert(needInitUserList);
|
||||
CompletableFuture<Void> insertTask = CompletableFuture.runAsync(() -> {
|
||||
log.info("新增用户: {} 个", needInitUserList.size());
|
||||
// 分批处理,每批200条
|
||||
|
||||
@@ -306,7 +306,7 @@ public class SysUserServiceImpl extends BaseServiceImpl<Sys_user> implements Sys
|
||||
String decodePwd = Base64Decoder.decodeStr(passowrd);
|
||||
String hashedPassword = PwdUtil.getPassword(decodePwd, user.getSalt());
|
||||
if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) {
|
||||
// throw new BaseException("用户名或者密码不正确");
|
||||
throw new BaseException("用户名或者密码不正确");
|
||||
}
|
||||
user = this.fetchLinks(user, "unit");
|
||||
if (Lang.isNotEmpty(user.getUnit()) && StrUtil.isNotBlank(user.getUnit().getUnionId())) {
|
||||
|
||||
@@ -39,7 +39,7 @@ public class SysUserAllRenewJob implements Job {
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
|
||||
// Date pullTime = sysDataUserPullService.pull();
|
||||
Date pullTime = sysDataUserPullService.pull();
|
||||
JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
|
||||
NutMap conditionGroupMap = (NutMap)jobDataMap.get("conditionGroup");
|
||||
if(conditionGroupMap == null || conditionGroupMap.isEmpty()){
|
||||
@@ -54,8 +54,7 @@ public class SysUserAllRenewJob implements Job {
|
||||
}
|
||||
|
||||
SysDataUserUpdateParam param = new SysDataUserUpdateParam();
|
||||
// param.setPullTime(DateUtil.formatDateTime(pullTime));
|
||||
param.setPullTime("2025-09-10 16:45:01");
|
||||
param.setPullTime(DateUtil.formatDateTime(pullTime));
|
||||
param.setUpdateMode(SysDataUpdateMode.ALL.name());
|
||||
param.setConditionGroup(conditionGroup);
|
||||
|
||||
|
||||
+8
-3
@@ -12,6 +12,7 @@ import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
|
||||
import com.budwk.app.zhgh.activity.basic.param.ActivityUserScopePageParam;
|
||||
@@ -33,6 +34,7 @@ import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.management.relation.Role;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -90,10 +92,14 @@ public class ActivityBasicScopeController {
|
||||
FROM
|
||||
`vw_user` u
|
||||
LEFT JOIN sys_user_role sur on sur.userid = u.id
|
||||
LEFT JOIN club_user clubuser ON clubuser.userid=u.id
|
||||
$condition
|
||||
""");
|
||||
try {
|
||||
Cnd cnd = getCnd(pageForm);
|
||||
if(!AuthUtil.hasRole(RoleConstant.SYSADMIN.name())) {
|
||||
cnd.and("u.unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
@@ -201,8 +207,8 @@ public class ActivityBasicScopeController {
|
||||
}
|
||||
|
||||
@At
|
||||
public Object getRoleListByMenuId(String menuId) {
|
||||
return Result.success(dao.query(Sys_role.class, Cnd.where("system_name", "=", menuId).desc("code")));
|
||||
public Object getRoleListByMenuId() {
|
||||
return Result.success(dao.query(Sys_role.class, Cnd.NEW().desc("code")));
|
||||
|
||||
}
|
||||
|
||||
@@ -350,7 +356,6 @@ public class ActivityBasicScopeController {
|
||||
cnd.andEX("u.personType", IN_OR_NIN_OP, activityUserScopePageParam.getPersonTypes());
|
||||
cnd.andEX("u.userState", IN_OR_NIN_OP, activityUserScopePageParam.getUserStates());
|
||||
cnd.andEX("u.sex", IN_OR_NIN_OP, activityUserScopePageParam.getSexTypes());
|
||||
cnd.andEX("sur.jdhid", EQ_OR_NEQ_OP, activityUserScopePageParam.getTeacherMeetingId());
|
||||
cnd.andEX("sur.roleid", IN_OR_NIN_OP, activityUserScopePageParam.getRoleIds());
|
||||
cnd.andEX("clubuser.clubid", EQ_OR_NEQ_OP, activityUserScopePageParam.getClubId());
|
||||
|
||||
|
||||
+14
-1
@@ -115,11 +115,14 @@ public class ActivityCultureApplyUserController {
|
||||
@At
|
||||
@SaCheckLogin
|
||||
@ApiOperation(value = "队友搜索")
|
||||
public Result queryTeammate(@Valid String keyword) {
|
||||
public Result queryTeammate(@Valid String keyword,Integer signUpMethod) {
|
||||
Sql sql = Sqls.create("select id userId,username userName,loginname loginName,sex,mobile,unitName from vw_user $condition limit 0,10");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.or(Cnd.likeEX("username", keyword));
|
||||
cnd.or(Cnd.likeEX("loginname", keyword));
|
||||
if (signUpMethod == 3){
|
||||
cnd.and("unionid", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
List<NutMap> list = activityCultureApplyUserService.listMap(sql);
|
||||
return Result.success(list);
|
||||
@@ -142,6 +145,16 @@ public class ActivityCultureApplyUserController {
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckLogin
|
||||
@ApiOperation(value = "查询分工会报名人员")
|
||||
public Result listTeamUserUnion(@Valid String activityId) {
|
||||
List<ActivityTissuePerson> list = dao.query(ActivityTissuePerson.class, Cnd.where(ActivityTissuePerson::getTissueId, "=", activityId)
|
||||
.and(ActivityTissuePerson::getApplyUserId, "=", SecurityUtil.getUserId())
|
||||
);
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckLogin
|
||||
@ApiOperation(value = "是否报名")
|
||||
|
||||
+35
-24
@@ -129,8 +129,9 @@ public class ActivityCultureApplyUserServiceImpl extends BaseServiceImpl<Activit
|
||||
//总人数限制
|
||||
if (tissue.getUserNumberLimit() == 1) {
|
||||
Integer totalUserNumberLimit = tissue.getTotalUserNumberLimit();
|
||||
int hasRegisterCount = count(Cnd.where(ActivityTissuePerson::getTissueId, "=", activityId));
|
||||
if (!(totalUserNumberLimit - hasRegisterCount > 0)) {
|
||||
int hasRegisterCount = count(Cnd.where(ActivityTissuePerson::getTissueId, "=", activityId)
|
||||
.and(ActivityTissuePerson::getUserId, "not in", personIds));
|
||||
if (personIds.size() + hasRegisterCount > totalUserNumberLimit) {
|
||||
throw new BaseException("报名名额已满!");
|
||||
}
|
||||
}
|
||||
@@ -139,19 +140,18 @@ public class ActivityCultureApplyUserServiceImpl extends BaseServiceImpl<Activit
|
||||
if (tissue.getUserNumberLimit() == 2) {
|
||||
int limitNumByUnion = getLimitNumByUnion(tissue.getUnionUserNumberLimit(), SecurityUtil.getUnionId());
|
||||
//获取当前该分工会已报多少人
|
||||
Sql sql = Sqls.create("""
|
||||
/*Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
count(1)
|
||||
FROM
|
||||
activity_tissue_person atp
|
||||
LEFT JOIN `vw_user` u ON u.id = atp.userId
|
||||
WHERE
|
||||
atp.tissueId = @activityId
|
||||
AND u.unionid = @unionId
|
||||
AND atp.unionId = @unionId
|
||||
""");
|
||||
sql.setParam("activityId", activityId).setParam("unionId", SecurityUtil.getUnionId());
|
||||
int hasRegisterCount = count(sql);
|
||||
if (!(limitNumByUnion - hasRegisterCount > 0)) {
|
||||
int hasRegisterCount = count(sql);*/
|
||||
if (personIds.size() > limitNumByUnion) {
|
||||
throw new BaseException("该分工会报名名额已满!");
|
||||
}
|
||||
}
|
||||
@@ -202,6 +202,8 @@ public class ActivityCultureApplyUserServiceImpl extends BaseServiceImpl<Activit
|
||||
mobile,
|
||||
unitName,
|
||||
unionName,
|
||||
unionId,
|
||||
unitId,
|
||||
'$activityId' AS tissueId,
|
||||
'$applyUserId' AS applyUserId,
|
||||
'$applyUserUserName' AS applyUserUserName,
|
||||
@@ -221,23 +223,32 @@ public class ActivityCultureApplyUserServiceImpl extends BaseServiceImpl<Activit
|
||||
//分工会报名独有判断
|
||||
//判断总人数限制
|
||||
//判断分工会人数限制
|
||||
View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", SecurityUtil.getUserId()));
|
||||
ActivityTissuePerson activityTissuePerson = new ActivityTissuePerson();
|
||||
activityTissuePerson.setTissueId(activityId);
|
||||
activityTissuePerson.setUserId(user.getId());
|
||||
activityTissuePerson.setUserName(user.getUsername());
|
||||
activityTissuePerson.setLoginName(user.getLoginname());
|
||||
activityTissuePerson.setSex(user.getSex());
|
||||
activityTissuePerson.setMobile(user.getMobile());
|
||||
activityTissuePerson.setUnitId(user.getUnitId());
|
||||
activityTissuePerson.setUnitName(user.getUnitName());
|
||||
activityTissuePerson.setUnionId(user.getUnionId());
|
||||
activityTissuePerson.setUnionName(user.getUnionName());
|
||||
activityTissuePerson.setApplyDateTime(DateUtil.now());
|
||||
activityTissuePerson.setApplyUserId(user.getId());
|
||||
activityTissuePerson.setApplyUserUserName(user.getUsername());
|
||||
activityTissuePerson.setDynamicFormData(dynamicFormParam);
|
||||
insert(activityTissuePerson);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
id AS userId,
|
||||
username AS userName,
|
||||
loginname AS loginName,
|
||||
sex,
|
||||
mobile,
|
||||
unitName,
|
||||
unionName,
|
||||
unionId,
|
||||
unitId,
|
||||
'$activityId' AS tissueId,
|
||||
'$applyUserId' AS applyUserId,
|
||||
'$applyUserUserName' AS applyUserUserName,
|
||||
'$applyDateTime' AS applyDateTime
|
||||
FROM
|
||||
`vw_user`
|
||||
$condition
|
||||
""");
|
||||
sql.setVar("activityId", activityId);
|
||||
sql.setVar("applyUserId", SecurityUtil.getUserId());
|
||||
sql.setVar("applyDateTime", DateUtil.now());
|
||||
sql.setVar("applyUserUserName", SecurityUtil.getUserUsername());
|
||||
sql.setCondition(Cnd.where("id", "in", personIds));
|
||||
List<ActivityTissuePerson> fullPersonList = listEntity(sql);
|
||||
insert(fullPersonList);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.budwk.app.zhgh.activity.family.constant;
|
||||
|
||||
import com.budwk.app.base.annotation.DictEnum;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* @Author JyuHsin
|
||||
* @Date 2022/11/18
|
||||
* @Description
|
||||
*/
|
||||
@Getter
|
||||
@DictEnum(key = "ColumnFormTypeEnum", name = "控件类型")
|
||||
@AllArgsConstructor
|
||||
public enum ColumnFormTypeEnum {
|
||||
|
||||
INPUT("INPUT", "输入框"),
|
||||
SELECT("SELECT", "选择框"),
|
||||
//RADIO("RADIO", "单选框"),//选项数组
|
||||
FILE("FILE", "文件");
|
||||
|
||||
private String code;
|
||||
private String description;
|
||||
}
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
package com.budwk.app.zhgh.activity.family.controller.manage;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.sys.models.Sys_dict;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.sys.services.SysDictService;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
|
||||
import com.budwk.app.zhgh.activity.family.models.*;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityService;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.Static;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.json.Json;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "活动报名")
|
||||
@At("/platform/family/apply")
|
||||
public class FamilyActivityApplyController {
|
||||
|
||||
private final ReentrantLock lock = new ReentrantLock(true);
|
||||
|
||||
@Inject
|
||||
private FamilyActivityService familyActivityService;
|
||||
@Inject
|
||||
private SysDictService dictService;
|
||||
@Inject
|
||||
private FamilyActivityStatisticsService statisticsService;
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@At("/")
|
||||
@SaCheckPermission("family.apply")
|
||||
@Ok("beetl:/platform/zhgh/activity/family/apply/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At("/h5")
|
||||
@SaCheckPermission("h5.family.apply")
|
||||
@Ok("beetl:/platform/zhghh5/activity/family/apply/index.html")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
@At("/list/h5")
|
||||
@SaCheckPermission("h5.family.apply")
|
||||
@Ok("beetl:/platform/zhghh5/activity/family/list/index.html")
|
||||
public void listIndex() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("活动查询")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
public Result activityPageData(PageForm pageForm,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "activityType") Integer activityType,
|
||||
@Param(value = "id") String id,
|
||||
@Param(value = "dataType") String dataType) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("id", "=", id);
|
||||
cnd.andEX("`year`", "=", year);
|
||||
//查询报名中
|
||||
if (activityType == 2) {
|
||||
cnd.and(new Static("now() > activitySignUpStartTime and now() < activitySignUpEndTime"));
|
||||
}//查询已结束的
|
||||
else if (activityType == 3) {
|
||||
cnd.and(new Static("now() > activityEndTime"));
|
||||
} else if (activityType == 4) {
|
||||
cnd.and(new Static("now() < activitySignUpStartTime"));
|
||||
}
|
||||
|
||||
if (AuthUtil.hasRole("H04") && !AuthUtil.hasRoleOr("sysadmin, A06")) {
|
||||
cnd.and("activityMode", "=", 2).and("createdBy", "=", SecurityUtil.getUserId());
|
||||
}
|
||||
|
||||
if("mine".equals(dataType)) {
|
||||
cnd.and(new Static("id in (select activityId from train_sign_up_user where userId = '%s')".formatted(SecurityUtil.getUserId())));
|
||||
}
|
||||
|
||||
Pagination pagination = familyActivityService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
|
||||
List<FamilyActivity> familyActivities = pagination.getList();
|
||||
Map<String, String> familyTypeMap = dictService.getSubListByCode("FAMILY_SIGNUP_TYPE").stream().collect(Collectors.toMap(Sys_dict::getCode, Sys_dict::getName));
|
||||
familyActivities.forEach(v -> v.setTrainType(familyTypeMap.get(v.getTrainType())));
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分活动查询")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "courseTypeId") String courseTypeId,
|
||||
@Param(value = "activityId") String activityId,
|
||||
@Param(value = "assortTypes") String[] assortTypes,
|
||||
@Param(value = "dataType") String dataType) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
tsuc.*,
|
||||
type.typeName
|
||||
FROM
|
||||
`family_course` tsuc
|
||||
LEFT JOIN family_type type ON type.id = tsuc.courseType
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("type.id", "=", courseTypeId);
|
||||
cnd.and("tsuc.activityId", "=", activityId);
|
||||
if(Lang.isNotEmpty(assortTypes)) {
|
||||
cnd.and("tsuc.assort", "in", assortTypes);
|
||||
}
|
||||
|
||||
if("mine".equals(dataType)) {
|
||||
cnd.and(new Static("tsuc.id in (select courseId from train_sign_up_user where userId = '%s')".formatted(SecurityUtil.getUserId())));
|
||||
}
|
||||
|
||||
List<FamilyCourse> courseArray = familyActivityService.dao().query(FamilyCourse.class, Cnd.where("activityId", "=", activityId));
|
||||
courseArray = familyActivityService.filterCourseByHostUnion(courseArray);
|
||||
cnd.and("tsuc.id", "in", courseArray.stream().map(FamilyCourse::getId).toList());
|
||||
|
||||
cnd.asc("tsuc.orderNum");
|
||||
cnd.asc("type.code");
|
||||
sql.setCondition(cnd);
|
||||
|
||||
Pagination pagination = familyActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
List<NutMap> courseList = pagination.getList();
|
||||
|
||||
courseList.forEach(c -> {
|
||||
List<FamilyActivityCourse> courseTimes = dao.query(FamilyActivityCourse.class, Cnd.where("courseId", "=", c.getString("id")).asc("courseDate"));
|
||||
c.put("courseTimes", courseTimes);
|
||||
|
||||
c.put("hasRegisterNum", statisticsService.queryCourseCount(c.getString("id"), c.getString("courseType")));
|
||||
c.put("hasWaitingNum", statisticsService.queryCourseWaitCount(c.getString("id"), c.getString("courseType")));
|
||||
//当前用户是否报过
|
||||
c.put("isSign", familyActivityService.isSignCourseByUser(c.getString("id"), SecurityUtil.getUserId()));
|
||||
|
||||
if(StrUtil.isNotBlank(c.getString("unionLimit"))) {
|
||||
List<NutMap> unionLimit = Json.fromJsonAsList(NutMap.class, c.getString("unionLimit"));
|
||||
if(Lang.isNotEmpty(unionLimit)) {
|
||||
NutMap nutMap = unionLimit.stream().filter(o -> o.getString("id").equals(SecurityUtil.getUnionId())).findFirst().orElse(null);
|
||||
if(nutMap != null) {
|
||||
c.put("coursePeopleNumber", nutMap.getInt("limitCount"));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("获取分活动时间")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
public Result getCourseTime(String id) {
|
||||
List<FamilyActivityCourse> list = familyActivityService.dao().query(FamilyActivityCourse.class, Cnd.where("courseId", "=", id));
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("查询分类标识集合")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
public Result queryCourseAssort(String activityId) {
|
||||
List<FamilyCourse> courseList = familyActivityService.dao().query(
|
||||
FamilyCourse.class,
|
||||
Cnd.where(FamilyCourse::getActivityId, "=", activityId).asc(FamilyCourse::getOrderNum)
|
||||
);
|
||||
if(Lang.isEmpty(courseList)) {
|
||||
return Result.success(new ArrayList<>());
|
||||
}
|
||||
List<String> assortList = courseList.stream().map(FamilyCourse::getAssort).filter(StrUtil::isNotBlank).toList();
|
||||
return Result.success(assortList);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("验证是否能报名")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
public Result validateSignUp(String courseId,
|
||||
@Param(value = "currentFamilyNumber") Integer currentFamilyNumber) {
|
||||
try {
|
||||
lock.lock();
|
||||
if(StrUtil.isBlank(courseId)) {
|
||||
return Result.error(99, "报名信息为空");
|
||||
}
|
||||
|
||||
currentFamilyNumber = currentFamilyNumber != null ? currentFamilyNumber : 0;
|
||||
FamilyCourse course = dao.fetch(FamilyCourse.class, courseId);
|
||||
FamilyActivity activity = dao.fetch(FamilyActivity.class, course.getActivityId());
|
||||
|
||||
//判断时间
|
||||
if(DateUtil.compare(new Date(), activity.getActivitySignUpStartTime(), "yyyy-MM-dd HH:mm:ss") < 0) {
|
||||
return Result.error(99,"报名未开始");
|
||||
}
|
||||
if(DateUtil.compare(new Date(), activity.getActivitySignUpEndTime(), "yyyy-MM-dd HH:mm:ss") > 0) {
|
||||
return Result.error(99,"报名已结束");
|
||||
}
|
||||
|
||||
//判断活动组别
|
||||
int count = dao.count(ActivityUserScope.class, Cnd.where("groupId", "=", activity.getActivityGroupId()).and("userId", "=", SecurityUtil.getUserId()));
|
||||
if(count == 0) {
|
||||
return Result.error(99,"抱歉,您没有此次活动的权限");
|
||||
}
|
||||
|
||||
//判断是否报名
|
||||
boolean courseByUser = familyActivityService.isSignCourseByUser(courseId, SecurityUtil.getUserId());
|
||||
if(courseByUser) {
|
||||
return Result.error(99,"抱歉,您已经报名");
|
||||
}
|
||||
|
||||
//判断活动人数
|
||||
boolean signFull = familyActivityService.isSignFull(course, currentFamilyNumber);
|
||||
if(signFull) {
|
||||
return Result.error(99,"啊哦,目前报名人数已达上限。您可保持关注,如有老师取消之前的报名从而释放出名额,您可再来试试。谢谢!");
|
||||
}
|
||||
|
||||
//判断活动限制
|
||||
boolean signCourse = familyActivityService.isSignCourse(course, activity);
|
||||
if(!signCourse) {
|
||||
if(activity.getRestrictLimit() != 3) {
|
||||
return Result.error(99,"您选择的类型已达上限,不能再报该类型的了");
|
||||
} else {
|
||||
return Result.error(99,activity.getActivityName() + "限制报" + activity.getLimitNum() + "个活动,已达上限");
|
||||
}
|
||||
}
|
||||
|
||||
//判断分工会人数限制
|
||||
boolean signFullByUnionId = familyActivityService.isSignFullByUnionId(course, currentFamilyNumber);
|
||||
if(signFullByUnionId) {
|
||||
return Result.error(99,"您所在的分工会名额不足");
|
||||
}
|
||||
|
||||
return Result.success();
|
||||
}catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error(99,"报名失败");
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("查询子活动时间段")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
public Object getCourseTimeSelectList(String courseId) {
|
||||
// 查课程的时间段
|
||||
List<FamilyActivityCourse> courseList = dao.query(FamilyActivityCourse.class, Cnd.where("courseId", "=", courseId).asc("courseStartTime"));
|
||||
|
||||
// 查课程的报名人数
|
||||
List<FamilyUserCourse> applyUserList = dao.query(FamilyUserCourse.class, Cnd.where("courseId", "=", courseId));
|
||||
|
||||
List<FamilyUser> userList = dao.query(FamilyUser.class, Cnd.where("courseId", "=", courseId).and("state", "=", 1));
|
||||
List<String> idList = userList.stream().map(FamilyUser::getUserId).toList();
|
||||
|
||||
applyUserList = applyUserList.stream().filter(o -> idList.contains(o.getUserId())).toList();
|
||||
|
||||
// 按照课程下面时间段去分组
|
||||
Map<String, List<FamilyUserCourse>> collectMap = applyUserList.stream().collect(Collectors.groupingBy(FamilyUserCourse::getActivityCourseId));
|
||||
List<NutMap> list = courseList.stream().map(v -> {
|
||||
String id = v.getId();
|
||||
NutMap nutMap = NutMap.NEW();
|
||||
List<FamilyUserCourse> familyUserCourses = collectMap.get(id);
|
||||
int remainingNum = v.getCourseLimitNum() != null ? v.getCourseLimitNum() : 0;
|
||||
if (Lang.isNotEmpty(familyUserCourses)) {
|
||||
remainingNum = v.getCourseLimitNum() - familyUserCourses.size();
|
||||
}
|
||||
nutMap.put("remainingNum", remainingNum);
|
||||
nutMap.put("text", DateUtil.format(v.getCourseStartTime(), "HH:mm") + "至" + DateUtil.format(v.getCourseEndTime(), "HH:mm") + "段(剩" + remainingNum + ")");
|
||||
nutMap.put("value", id);
|
||||
nutMap.put("disabled", remainingNum == 0);
|
||||
return nutMap;
|
||||
}).filter(v -> v.getInt("remainingNum") != 0).toList();
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("验证子活动是否能报名")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
public Object validateSourceSignUp(String activityCourseId, String courseId) {
|
||||
try {
|
||||
lock.lock();
|
||||
|
||||
List<FamilyUser> userList = dao.query(FamilyUser.class, Cnd.where("courseId", "=", courseId).and("state", "=", 1));
|
||||
List<String> isList = userList.stream().map(FamilyUser::getUserId).toList();
|
||||
|
||||
// 该时间段下已报名的人数
|
||||
int count = dao.count(FamilyUserCourse.class, Cnd.where("activityCourseId", "=", activityCourseId)
|
||||
.and("courseId", "=", courseId).and("userId", "in", isList));
|
||||
// 获取改时间段下的活动课程限制报名人数
|
||||
FamilyActivityCourse course = dao.fetch(FamilyActivityCourse.class, activityCourseId);
|
||||
Integer courseLimitNum = course.getCourseLimitNum();
|
||||
// 报名加上自己,如果大于了限制人数,那就无法报名
|
||||
if (count + 1 > courseLimitNum) {
|
||||
return Result.error(99,"该时间段名额已报满,请选择其他时段报名");
|
||||
} else {
|
||||
return Result.success();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error(99,"报名失败");
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("活动报名")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
@SLog(tag = "亲子活动-活动报名", msg = "活动报名")
|
||||
public Result doSignUp(FamilyUser familyUser) {
|
||||
try {
|
||||
lock.lock();
|
||||
boolean courseByUser = familyActivityService.isSignCourseByUser(familyUser.getCourseId(), SecurityUtil.getUserId());
|
||||
if(courseByUser) {
|
||||
return Result.error(99,"您已报过该活动");
|
||||
}
|
||||
FamilyActivity activity = familyActivityService.fetch(familyUser.getActivityId());
|
||||
boolean validFamilyCount = familyActivityService.validFamilyCount(familyUser);
|
||||
if(validFamilyCount) {
|
||||
return Result.error(99,activity.getKeyWord() + "人数最多为" + activity.getFamilyMaxCount());
|
||||
}
|
||||
//判断人数
|
||||
int number = 0;
|
||||
FamilyCourse course = familyActivityService.dao().fetch(FamilyCourse.class, familyUser.getCourseId());
|
||||
FamilyType type = familyActivityService.dao().fetch(FamilyType.class, course.getCourseType());
|
||||
if(type != null) {
|
||||
if(type.getIsBringFamily() && type.getIsAddFamily()) {
|
||||
List<List<NutMap>> mobileColumnsValue = familyUser.getMobileColumnsValue();
|
||||
number = Lang.isNotEmpty(mobileColumnsValue) ? mobileColumnsValue.size() : 0;
|
||||
}
|
||||
}
|
||||
boolean signFull = familyActivityService.isSignFull(course, number);
|
||||
if(signFull) {
|
||||
return Result.error(99,"当前报名人数已满");
|
||||
}
|
||||
boolean signFullByUnionId = familyActivityService.isSignFullByUnionId(course, number);
|
||||
if(signFullByUnionId) {
|
||||
return Result.error(99,"该活动您所在的分工会名额不足");
|
||||
}
|
||||
familyActivityService.doSignUp(familyUser);
|
||||
return Result.success("祝贺您!您已报名成功!请留意各分场活动的准确时间、地点,提前10-15分钟到达活动现场做好准备。如您因故不能参加活动,还请及时登录系统取消报名,以便将机会留给其他有需要的教职工。谢谢!");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return Result.error("报名失败");
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("取消报名")
|
||||
@SaCheckPermission(value = {"family.apply", "h5.family.apply"}, mode = SaMode.OR)
|
||||
@SLog(tag = "亲子活动-活动报名", msg = "取消报名")
|
||||
public Result cancelSignUp(@Param("activityId") String activityId, @Param("courseId") String courseId) {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
//取消分两种情况
|
||||
//第一种没有设置分工会人数限制,那么将候补的人按时间倒叙往上补
|
||||
//第二种如果设置了分工会人数限制,那么只将本分工会的候补人员按照时间倒叙往上补,如果本分工会没有候补人员,则名额空出来,由校工会手动调整
|
||||
FamilyCourse course = dao.fetch(FamilyCourse.class, courseId);
|
||||
FamilyType type = dao.fetch(FamilyType.class, course.getCourseType());
|
||||
//如果是正常报名取消了,将候补报名的按时间倒叙第一个改为正常报名
|
||||
Cnd cnd = Cnd.where("activityId", "=", activityId).and("courseId", "=", courseId)
|
||||
.and("state", "=", 2);
|
||||
//如果设置了分工会报名人数限制,则只查本分工会
|
||||
if (Lang.isNotEmpty(course.getUnionLimit())) {
|
||||
cnd.and(new Static(" userId in (select id from user where unionid = '%s')".formatted(SecurityUtil.getUnionId())));
|
||||
}
|
||||
cnd.asc("signUpTime");
|
||||
if (!type.getIsBringFamily() && course.getReserveMode() == 2) {
|
||||
List<FamilyUser> signUpUsers = dao.query(FamilyUser.class, cnd);
|
||||
int thisSignUpUserCount = dao.count(FamilyUser.class,
|
||||
Cnd.where("activityId", "=", activityId)
|
||||
.and("courseId", "=", courseId).and("userId", "=", userId)
|
||||
.and("state", "in", List.of(1, 3)));
|
||||
if (!signUpUsers.isEmpty() && thisSignUpUserCount > 0) {
|
||||
FamilyUser familyUser = signUpUsers.get(0);
|
||||
familyUser.setState(1);
|
||||
dao.update(familyUser);
|
||||
Sys_user user = dao.fetch(Sys_user.class, familyUser.getUserId());
|
||||
//msgApi.sendTextMsg("【" + activity.getActivityName() + "】已候补成功,请按时参加活动!", user.getLoginname());
|
||||
}
|
||||
}
|
||||
//删除报名记录
|
||||
dao.clear("family_user_course", Cnd.where("activityId", "=", activityId)
|
||||
.and("courseId", "=", courseId).and("userId", "=", userId));
|
||||
|
||||
dao.clear("family_user", Cnd.where("activityId", "=", activityId)
|
||||
.and("courseId", "=", courseId).and("userId", "=", userId));
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
package com.budwk.app.zhgh.activity.family.controller.manage;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.zhgh.activity.family.models.*;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
import org.nutz.trans.Trans;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author zxy
|
||||
* @Description 培训报名 活动管理
|
||||
* @createTime 2022年02月23日 09:57:00
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "活动管理")
|
||||
@At("/platform/family/manage")
|
||||
public class FamilyActivityController {
|
||||
|
||||
@Inject
|
||||
private FamilyActivityService familyActivityManageService;
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("family.manage")
|
||||
@Ok("beetl:/platform/zhgh/activity/family/manage/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("family.manage")
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "activityName") String activityName) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("year", "=", year);
|
||||
cnd.and(Cnd.likeEX("activityName", activityName));
|
||||
cnd.orderBy("createdAt", "desc");
|
||||
return Result.success().addData(familyActivityManageService.pageData(pageForm, cnd));
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("活动删除")
|
||||
@SaCheckPermission("family.manage")
|
||||
@SLog(tag = "亲子活动-活动管理", msg = "删除活动")
|
||||
public Result onDelete(String id) {
|
||||
Trans.exec(() -> {
|
||||
familyActivityManageService.delete(id);
|
||||
dao.clear(FamilyCourse.class, Cnd.where("activityId", "=", id));
|
||||
dao.clear(FamilyActivityCourse.class, Cnd.where("activityId", "=", id));
|
||||
dao.clear(FamilyUser.class, Cnd.where("activityId", "=", id));
|
||||
dao.clear(FamilyUserCourse.class, Cnd.where("activityId", "=", id));
|
||||
dao.clear(FamilyActivity.class, Cnd.where("id", "=", id));
|
||||
dao.clear(FamilyTypeLimit.class, Cnd.where("activityId", "=", id));
|
||||
dao.delete(Sys_home_activity.class, id);
|
||||
});
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("活动状态变更")
|
||||
@SaCheckPermission("family.manage")
|
||||
public Result activityStatusChange(FamilyActivity activity) {
|
||||
familyActivityManageService.updateActivityStatus(activity);
|
||||
dao.update(Sys_home_activity.class,
|
||||
Chain.make("enable", !activity.isDisabled()),
|
||||
Cnd.where("id", "=", activity.getId()));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("查询单个活动")
|
||||
@SaCheckPermission("family.manage")
|
||||
public Result findOne(@Param("id") @NotNull String id) {
|
||||
NutMap dataMap = familyActivityManageService.findOne(id, null, "");
|
||||
String activityStartTime = dataMap.getString("activityStartTime");
|
||||
String activityEndTime = dataMap.getString("activityEndTime");
|
||||
if(StrUtil.isNotBlank(activityStartTime) && StrUtil.isNotBlank(activityEndTime)) {
|
||||
dataMap.put("activityTime", List.of(activityStartTime, activityEndTime));
|
||||
} else {
|
||||
dataMap.put("activityTime", new ArrayList<>());
|
||||
}
|
||||
|
||||
String activitySignUpStartTime = dataMap.getString("activitySignUpStartTime");
|
||||
String activitySignUpEndTime = dataMap.getString("activitySignUpEndTime");
|
||||
if(StrUtil.isNotBlank(activitySignUpStartTime) && StrUtil.isNotBlank(activitySignUpEndTime)) {
|
||||
dataMap.put("activitySignTime", List.of(activitySignUpStartTime, activitySignUpEndTime));
|
||||
} else {
|
||||
dataMap.put("activitySignTime", new ArrayList<>());
|
||||
}
|
||||
|
||||
List<NutMap> courseList = dataMap.getList("courseList", NutMap.class);
|
||||
|
||||
//查询所有的课程类型
|
||||
List<FamilyType> familyTypeList = dao.query(FamilyType.class, Cnd.NEW());
|
||||
Map<String, String> typeMap = familyTypeList.stream().collect(Collectors.toMap(FamilyType::getId, FamilyType::getTypeName));
|
||||
|
||||
courseList.forEach(v -> {
|
||||
|
||||
List<NutMap> courseTimeList = v.getList("courseTimeList", NutMap.class);
|
||||
//选择课程日期 下拉框
|
||||
List<String> setUpCourseData = courseTimeList.stream().map(cd -> cd.getString("courseDate")).distinct().collect(Collectors.toList());
|
||||
v.put("setUpCourseData", setUpCourseData);
|
||||
|
||||
courseTimeList.forEach(ct -> {
|
||||
String courseStartTime = DateUtil.format(ct.getTime("courseStartTime"), "HH:mm");
|
||||
String courseEndTime = DateUtil.format(ct.getTime("courseEndTime"), "HH:mm");
|
||||
ct.put("courseStartTime", courseStartTime);
|
||||
ct.put("courseEndTime", courseEndTime);
|
||||
});
|
||||
|
||||
v.put("courseTypeName", typeMap.get(v.getString("courseType")));
|
||||
});
|
||||
|
||||
return Result.success().addData(dataMap);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("json:full")
|
||||
@ApiOperation("亲子活动新增/修改")
|
||||
@SaCheckPermission("family.manage")
|
||||
@SLog(tag = "亲子活动-活动管理", msg = "新增/修改活动")
|
||||
public Result doHandle(FamilyActivity activity) {
|
||||
if (StrUtil.isBlank(activity.getId())) {
|
||||
familyActivityManageService.add(activity, null);
|
||||
} else {
|
||||
familyActivityManageService.edit(activity);
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("json:full")
|
||||
@ApiOperation("获取分工会人数限制")
|
||||
@SaCheckPermission("family.manage")
|
||||
public Result getUnionLimit(@Param(value = "activityScopeId") String activityScopeId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
gh.id,
|
||||
gh.name,
|
||||
gh.unioncode,
|
||||
(select count(1) from `vw_user` where unionid = gh.id $cnd) as teacherCount,
|
||||
NULL as ratio,
|
||||
NULL as limitCount
|
||||
FROM
|
||||
sys_union gh
|
||||
order by gh.unioncode
|
||||
""");
|
||||
if (StrUtil.isNotBlank(activityScopeId)) {
|
||||
sql.setVar("cnd", "AND id in (select userId from activity_user_scope where groupId = '" + activityScopeId + "')");
|
||||
}
|
||||
List<NutMap> list = familyActivityManageService.listMap(sql);
|
||||
return Result.success().addData(list);
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("json:full")
|
||||
@ApiOperation("获取报名人员数量")
|
||||
@SaCheckPermission("family.manage")
|
||||
public Result getRegisterUserCount(@Param(value = "courseId") String courseId) {
|
||||
return Result.success().addData(dao.count(FamilyUser.class, Cnd.where("courseId", "=", courseId)));
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("json:full")
|
||||
@ApiOperation("获取历史活动列表")
|
||||
@SaCheckPermission("family.manage")
|
||||
public Result getHistoricalActList() {
|
||||
List<FamilyActivity> query = dao.query(FamilyActivity.class, Cnd.NEW().desc("activityStartTime"));
|
||||
return Result.success().addData(query);
|
||||
}
|
||||
}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
package com.budwk.app.zhgh.activity.family.controller.manage;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.activity.family.models.*;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityService;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author JyuHsin
|
||||
* @Date 2022/9/21
|
||||
* @Description 人员调整
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "亲子活动人员调整")
|
||||
@At("/platform/family/userAdjust")
|
||||
public class FamilyAdjustController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
@Inject
|
||||
private FamilyActivityService familyActivityManageService;
|
||||
@Inject
|
||||
private FamilyActivityStatisticsService familyActivityStatisticsService;
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("family.adjust")
|
||||
@Ok("beetl:/platform/zhgh/activity/family/userAdjust/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 活动list
|
||||
* @param year 年度
|
||||
* @return
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("活动列表")
|
||||
@SaCheckPermission("family.adjust")
|
||||
public Result activityList(@Param(value = "year") Integer year) {
|
||||
List<FamilyActivity> activityList = dao.query(FamilyActivity.class, Cnd.NEW().andEX("year", "=", year).andEX("isDisabled", "=", false).desc("activityStartTime"));
|
||||
return Result.success(activityList);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("family.adjust")
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "activityId") String activityId) {
|
||||
Pagination pagination = familyActivityStatisticsService.pageData(pageForm, activityId);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("子活动查询")
|
||||
@SaCheckPermission("family.adjust")
|
||||
public Result getCourse(String activityId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
tsuc.id,
|
||||
tsuc.courseName,
|
||||
tsuc.coursePeopleNumber,
|
||||
tsuc.courseType,
|
||||
tsuc.courseLocation,
|
||||
tsuc.courseInstructor,
|
||||
tsuc.courseReservedNumber,
|
||||
tsuc.waitingNum,
|
||||
tsuc.reserveMode
|
||||
FROM
|
||||
`family_course` tsuc
|
||||
WHERE
|
||||
tsuc.activityId = @activityId
|
||||
ORDER BY courseName asc
|
||||
""");
|
||||
sql.setParam("activityId", activityId);
|
||||
List<NutMap> courseList = baseService.listMap(sql);
|
||||
courseList.forEach(c -> {
|
||||
c.put("registerNum", familyActivityStatisticsService.queryCourseCount(c.getString("id"), c.getString("courseType")));
|
||||
c.put("hasWaitingNum", familyActivityStatisticsService.queryCourseWaitCount(c.getString("id"), c.getString("courseType")));
|
||||
});
|
||||
return Result.success(courseList);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("报名用户列表")
|
||||
@SaCheckPermission("family.adjust")
|
||||
public Result registerUserList(@Param("courseId") String courseId,
|
||||
@Param(value = "unionId") String unionId,
|
||||
@Param(value = "unitId") String unitId,
|
||||
@Param(value = "searchName") String searchName,
|
||||
@Param(value = "searchKeyword") String searchKeyword) {
|
||||
List<NutMap> list = familyActivityStatisticsService.registerUserList(courseId, unionId, unitId, searchName, searchKeyword);
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("人员调整")
|
||||
@SaCheckPermission("family.adjust")
|
||||
@SLog(tag = "亲子活动-人员调整", msg = "人员调整")
|
||||
public Result adjust(String activityId, String oldCourseId, String newCourseId, String userId) {
|
||||
|
||||
Cnd oldCnd = Cnd.where("activityId", "=", activityId)
|
||||
.and("courseId", "=", oldCourseId).and("userId", "=", userId);
|
||||
|
||||
Cnd newCnd = Cnd.where("activityId", "=", activityId)
|
||||
.and("courseId", "=", newCourseId).and("userId", "=", userId);
|
||||
|
||||
//旧的报名信息
|
||||
FamilyUser oldfamilyUser = dao.fetch(FamilyUser.class, oldCnd);
|
||||
oldfamilyUser.setCourseId(newCourseId);
|
||||
oldfamilyUser.setSignUpTime(DateUtil.date());
|
||||
dao.update(oldfamilyUser);
|
||||
|
||||
//新的课程的信息,上课时间
|
||||
List<FamilyActivityCourse> activityCourseList = dao.query(FamilyActivityCourse.class, Cnd.where("activityId", "=", activityId)
|
||||
.and("courseId", "=", newCourseId));
|
||||
//先清楚旧的信息
|
||||
dao.clear(FamilyUserCourse.class, oldCnd);
|
||||
//添加新的信息
|
||||
List<FamilyUserCourse> familyUserCourseList = new ArrayList<>();
|
||||
activityCourseList.forEach(item -> {
|
||||
FamilyUserCourse course = new FamilyUserCourse();
|
||||
course.setActivityCourseId(activityId);
|
||||
course.setCourseId(newCourseId);
|
||||
course.setUserId(userId);
|
||||
course.setCourseStartTime(item.getCourseStartTime());
|
||||
course.setCourseEndTime(item.getCourseEndTime());
|
||||
course.setActivityCourseId(item.getId());
|
||||
familyUserCourseList.add(course);
|
||||
});
|
||||
dao.insert(familyUserCourseList);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("删除报名人员")
|
||||
@SaCheckPermission("family.adjust")
|
||||
@SLog(tag = "亲子活动-人员调整", msg = "删除报名人员")
|
||||
public Result deleteSignUser(String activityId, String courseId, String userId) {
|
||||
|
||||
//删除
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("activityId", "=", activityId);
|
||||
cnd.and("courseId", "=", courseId);
|
||||
cnd.and("userId", "=", userId);
|
||||
|
||||
dao.clear(FamilyUser.class, cnd);
|
||||
dao.clear(FamilyUserCourse.class, cnd);
|
||||
return Result.success();
|
||||
}
|
||||
}
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
package com.budwk.app.zhgh.activity.family.controller.manage;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.dev33.satoken.annotation.SaMode;
|
||||
import cn.hutool.core.date.DateUnit;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyUserCourse;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName FamilyMineController
|
||||
* @Author JyuHsin
|
||||
* @Date 2025/9/13 16:56
|
||||
* @Version 1.0
|
||||
* @Description TODO
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "活动报名")
|
||||
@At("/platform/family/mine")
|
||||
public class FamilyMineController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private FamilyActivityService activityService;
|
||||
|
||||
@At("/")
|
||||
@SaCheckPermission("family.mine")
|
||||
@Ok("beetl:/platform/zhgh/activity/family/mine/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At("/h5")
|
||||
@SaCheckPermission("h5.family.mine")
|
||||
@Ok("beetl:/platform/zhghh5/activity/family/mine/index.html")
|
||||
public void h5Index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("主动扫码签到")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission(value = {"family.mine", "h5.family.mine"}, mode = SaMode.OR)
|
||||
@SLog(tag = "品牌活动-活动签到", msg = "主动扫码签到")
|
||||
public Result drivingScan(String courseId) {
|
||||
|
||||
// 主动扫码签到是用户自己打开扫一扫,扫二维码签到
|
||||
int count = dao.count(FamilyUserCourse.class, Cnd.where("courseId", "=", courseId).and("userId", "=", SecurityUtil.getUserId()));
|
||||
if (count == 0) {
|
||||
return Result.error(99, "未查询到您的报名记录");
|
||||
}
|
||||
|
||||
// 获取现在的日期,并往后推1个小时
|
||||
String oneHourLater = DateUtil.offsetHour(new Date(), 1).toString("yyyy-MM-dd HH:mm:ss");
|
||||
FamilyUserCourse userCourse = dao.fetch(
|
||||
FamilyUserCourse.class,
|
||||
Cnd.where("courseId", "=", courseId)
|
||||
.and("userId", "=", SecurityUtil.getUserId())
|
||||
.and("courseStartTime", "<=", oneHourLater)
|
||||
.and("courseEndTime", ">=", oneHourLater)
|
||||
);
|
||||
if (userCourse == null) {
|
||||
return Result.error(99, "未到签到时间");
|
||||
}
|
||||
|
||||
userCourse.setAttend(true);
|
||||
userCourse.setAttendTime(DateUtil.date());
|
||||
dao.update(userCourse);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("被动扫码签到")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SaCheckPermission(value = {"family.mine", "h5.family.mine"}, mode = SaMode.OR)
|
||||
@SLog(tag = "品牌活动-活动签到", msg = "被动扫码签到")
|
||||
public Result passiveScan(String id) {
|
||||
|
||||
// id表示课程的某个时间段,userId表示是谁出示的二维码
|
||||
FamilyUserCourse userCourse = dao.fetch(FamilyUserCourse.class, id);
|
||||
if (userCourse == null) {
|
||||
return Result.error("未查询到报名记录");
|
||||
}
|
||||
int isAfter = DateUtil.compare(new Date(), userCourse.getCourseStartTime());
|
||||
if (isAfter > 0) {
|
||||
return Result.error("抱歉,已经开始,无法签到");
|
||||
}
|
||||
long diffMillis = Math.abs(DateUtil.between(new Date(), userCourse.getCourseStartTime(), DateUnit.MS));
|
||||
long oneHourInMs = 3600 * 1000;
|
||||
if (diffMillis > oneHourInMs) {
|
||||
return Result.error("签到时间为开始前1个小时");
|
||||
}
|
||||
|
||||
userCourse.setAttend(true);
|
||||
userCourse.setAttendTime(DateUtil.date());
|
||||
dao.update(userCourse);
|
||||
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分活动查询")
|
||||
@SaCheckPermission(value = {"family.mine", "h5.family.mine"}, mode = SaMode.OR)
|
||||
public Result queryCourseSign(String courseId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
uc.*,
|
||||
date(uc.courseStartTime) as courseDate
|
||||
FROM
|
||||
`family_user_course` uc
|
||||
WHERE
|
||||
courseId = @courseId and userId = @userId
|
||||
""");
|
||||
sql.setParam("userId", SecurityUtil.getUserId());
|
||||
sql.setParam("courseId", courseId);
|
||||
List<NutMap> listMap = activityService.listMap(sql);
|
||||
return Result.success(listMap);
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
package com.budwk.app.zhgh.activity.family.controller.manage;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckLogin;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.EnumUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyMobileSignColumn;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyType;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.dao.Sqls;
|
||||
import org.nutz.dao.entity.annotation.ColType;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.json.Json;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author JyuHsin
|
||||
* @Date 2022/9/22
|
||||
* @Description
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "活动类型管理")
|
||||
@At("/platform/family/type")
|
||||
public class FamilyTypeController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private BaseService baseService;
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("family.type")
|
||||
@Ok("beetl:/platform/zhgh/activity/family/type/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("family.type")
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "typeName") String typeName) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
Sql sql = Sqls.create("""
|
||||
select * from family_type $condition
|
||||
""");
|
||||
if (Strings.isNotBlank(typeName)) {
|
||||
cnd.and("typeName", "like", "%" + typeName + "%");
|
||||
}
|
||||
if(Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())){
|
||||
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
|
||||
} else {
|
||||
cnd.asc("xh");
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
List<NutMap> list = pagination.getList();
|
||||
list.forEach(item -> {
|
||||
Cnd c = Cnd.NEW();
|
||||
c.and("typeId", "=", item.getString("id"));
|
||||
c.asc("columnIndex");
|
||||
List<FamilyMobileSignColumn> signColumns = dao.query(FamilyMobileSignColumn.class, c);
|
||||
item.put("familyMobileSignColumnList", signColumns);
|
||||
|
||||
});
|
||||
return Result.success().addData(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("活动类型新增")
|
||||
@SaCheckPermission("family.type")
|
||||
@SLog(tag = "亲子活动-活动类型管理", msg = "活动类型新增")
|
||||
public Result doAdd(@Param("data") String data) throws Exception {
|
||||
FamilyType type = Json.fromJson(FamilyType.class, data);
|
||||
int count = dao.count(FamilyType.class, Cnd.where("code", "=", type.getCode()));
|
||||
if (count > 0) {
|
||||
return Result.error("编码重复!");
|
||||
}
|
||||
int totalCount = dao.count(FamilyType.class);
|
||||
type.setXh(totalCount + 1);
|
||||
dao.insertWith(type, "familyMobileSignColumnList");
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("活动类型修改")
|
||||
@SaCheckPermission("family.type")
|
||||
@SLog(tag = "亲子活动-活动类型管理", msg = "活动类型修改")
|
||||
public Result doEdit(FamilyType type) {
|
||||
int count = dao.count(FamilyType.class, Cnd.where("code", "=", type.getCode()).and("id", "!=", type.getId()));
|
||||
if (count > 0) {
|
||||
return Result.error("编码重复!");
|
||||
}
|
||||
dao.update(type);
|
||||
dao.clear(FamilyMobileSignColumn.class, Cnd.where("typeId", "=", type.getId()));
|
||||
dao.insertLinks(type, "familyMobileSignColumnList");
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("活动类型删除")
|
||||
@SaCheckPermission("family.type")
|
||||
@SLog(tag = "亲子活动-活动类型管理", msg = "活动类型删除")
|
||||
public Object doDelete(@Param(value = "id") String id) {
|
||||
dao.clear(FamilyType.class, Cnd.where("id", "=", id));
|
||||
dao.clear(FamilyMobileSignColumn.class, Cnd.where("typeId", "=", id));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@ApiOperation("排序号变更")
|
||||
@SaCheckPermission("family.type")
|
||||
public Object xhChange(String id, Integer xh, boolean toDown) {
|
||||
if (toDown) {
|
||||
FamilyType next = dao.fetch(FamilyType.class, Cnd.where("xh", "=", xh + 1));
|
||||
next.setXh(next.getXh() - 1);
|
||||
dao.update(next);
|
||||
dao.update(FamilyType.class, Chain.make("xh", xh + 1), Cnd.where("id", "=", id));
|
||||
} else {
|
||||
FamilyType pre = dao.fetch(FamilyType.class, Cnd.where("xh", "=", xh - 1));
|
||||
pre.setXh(pre.getXh() + 1);
|
||||
dao.update(pre);
|
||||
dao.update(FamilyType.class, Chain.make("xh", xh - 1), Cnd.where("id", "=", id));
|
||||
}
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("获取所有类型")
|
||||
@SaCheckLogin
|
||||
public Result getAllType(@Param(value = "id") String id) {
|
||||
List<FamilyType> familyTypeList = dao.query(FamilyType.class, Cnd.NEW().andEX("id", "=", id).asc("xh"));
|
||||
dao.fetchLinks(familyTypeList, "familyMobileSignColumnList", Cnd.NEW().asc("columnIndex"));
|
||||
return Result.success().addData(familyTypeList);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("自定义表单字段类型")
|
||||
@SaCheckPermission("family.type")
|
||||
public Result getColumnType() {
|
||||
List<String> names = EnumUtil.getNames(ColType.class);
|
||||
names.add("JSON");
|
||||
return Result.success(names);
|
||||
}
|
||||
}
|
||||
+349
@@ -0,0 +1,349 @@
|
||||
package com.budwk.app.zhgh.activity.family.controller.manage;
|
||||
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.afterturn.easypoi.excel.export.ExcelExportService;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.PageUtil;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyActivity;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyCourse;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyUser;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyBlackListService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Strings;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author zxy
|
||||
* @Description 人员管理
|
||||
* @createTime 2022年03月07日 14:27:00
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "亲子活动人员黑名单")
|
||||
@At("/platform/family/userManage")
|
||||
public class FamilyUserManageController {
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private FamilyBlackListService familyBlackListService;
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("family.userManage")
|
||||
@Ok("beetl:/platform/zhgh/activity/family/userManage/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("family.userManage")
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "activityId") String activityId,
|
||||
@Param(value = "courseId") String courseId,
|
||||
@Param(value = "year") Integer year,
|
||||
@Param(value = "userKeyWord") String userKeyWord) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("tsuu.activityId", "=", activityId);
|
||||
cnd.andEX("tsuu.courseId", "=", courseId);
|
||||
cnd.andEX("act.year", "=", year);
|
||||
if (StrUtil.isNotBlank(userKeyWord)) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
cnd.and(seg.andLike("u.username", userKeyWord).orLike("u.loginname", userKeyWord));
|
||||
}
|
||||
if(Strings.isNotBlank(pageForm.getPageOrderName()) && Strings.isNotBlank(pageForm.getPageOrderBy())){
|
||||
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
|
||||
}
|
||||
|
||||
Pagination pagination = familyBlackListService.pageData(pageForm, cnd, activityId, courseId);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("报名人员处理")
|
||||
@SaCheckPermission("family.userManage")
|
||||
@SLog(tag = "亲子活动-人员调整", msg = "报名人员处理")
|
||||
public Result doHandleUser(@Param("userId") String userId) {
|
||||
familyBlackListService.doHandleUser(userId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("根据活动Id获取子活动")
|
||||
@SaCheckPermission("family.userManage")
|
||||
public Result getCourseByActivityId(@Param("activityId") String activityId) {
|
||||
List<FamilyCourse> list = dao.query(FamilyCourse.class, Cnd.where("activityId", "=", activityId));
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("获取子活动具体时间")
|
||||
@SaCheckPermission("family.userManage")
|
||||
public Result attendClassRecord(String userId) {
|
||||
familyBlackListService.attendClassRecord(userId);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("获取候补人员")
|
||||
@SaCheckPermission("family.userManage")
|
||||
public Result getReserveUser(String courseId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
uc.* ,
|
||||
(select signUpTime from family_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as signUpTime,
|
||||
(select state from family_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as state,
|
||||
u.username,
|
||||
u.loginname,
|
||||
u.mobile,
|
||||
u.unitName,
|
||||
u.unionName
|
||||
FROM
|
||||
family_user_course uc LEFT JOIN `vw_user` u on uc.userId = u.id
|
||||
WHERE uc.courseId = @courseId and uc.isAttend = false HAVING state = 2 order by signUpTime desc
|
||||
""").setParam("courseId", courseId);
|
||||
return Result.success(familyBlackListService.listMap(sql));
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("补充人员")
|
||||
@SaCheckPermission("family.userManage")
|
||||
@SLog(tag = "亲子活动-人员管理", msg = "补充人员")
|
||||
public Result reserveSingUp(String[] ids, String courseId) {
|
||||
//先查询这个课程有多少个未签到的人员
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
uc.* ,
|
||||
(select signUpTime from family_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as signUpTime,
|
||||
(select state from family_user su where su.activityId=uc.activityId and su.courseId = uc.courseId and su.userId=uc.userId) as state
|
||||
FROM
|
||||
family_user_course uc
|
||||
WHERE uc.courseId = @courseId and uc.isAttend = false HAVING state = 1 order by signUpTime desc
|
||||
""").setParam("courseId", courseId);
|
||||
List<NutMap> list = familyBlackListService.listMap(sql);
|
||||
if(ids.length > list.size()) {
|
||||
return Result.error("您选择了" + ids.length + "位,未签到人员只有" + list.size() + "位");
|
||||
}
|
||||
//ids的长度为几,就搞几个
|
||||
List<NutMap> mapList = list.subList(0, ids.length);
|
||||
List<String> idList = mapList.stream().map(o -> o.getString("userId")).collect(Collectors.toList());
|
||||
//将这几个没签到的设置为4
|
||||
dao.update(FamilyUser.class, Chain.make("state", 4), Cnd.where("courseId", "=", courseId)
|
||||
.and("userId", "in", idList));
|
||||
//将补充的设置为1
|
||||
dao.update(FamilyUser.class, Chain.make("state", 1), Cnd.where("courseId", "=", courseId)
|
||||
.and("userId", "in", ids));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出签到人员")
|
||||
public void exportSignPerson(@Param(value = "activityId") String activityId,
|
||||
HttpServletResponse response) {
|
||||
FamilyActivity activity = dao.fetch(FamilyActivity.class, activityId);
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
uc.*,
|
||||
DATE_FORMAT(uc.courseStartTime, '%Y-%m-%d %H:%i:%s') as courseStartTimeExcel,
|
||||
DATE_FORMAT(uc.courseEndTime, '%Y-%m-%d %H:%i:%s') as courseEndTimeExcel,
|
||||
DATE_FORMAT(uc.attendTime, '%Y-%m-%d %H:%i:%s') as attendTimeExcel,
|
||||
u.username,
|
||||
u.loginname,
|
||||
u.unitName,
|
||||
u.unionName,
|
||||
u.sex
|
||||
FROM
|
||||
family_user_course uc
|
||||
left join family_course course on uc.courseId = course.id
|
||||
left join `vw_user` u on u.id = uc.userId
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("uc.activityId", "=", activityId);
|
||||
cnd.and("course.isMobileSign", "=", true);
|
||||
cnd.desc("isAttend").desc("attendTime");
|
||||
sql.setCondition(cnd);
|
||||
|
||||
List<NutMap> userList = familyBlackListService.listMap(sql);
|
||||
|
||||
List<FamilyCourse> courseList = dao.query(FamilyCourse.class, Cnd.where("activityId", "=", activityId));
|
||||
|
||||
List<Map<String, Object>> sheetsList = new ArrayList<>();
|
||||
|
||||
List<ExcelExportEntity> excelCommonExportEntity = new ArrayList<>();
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("开始时间", "courseStartTimeExcel", 22));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("结束时间", "courseEndTimeExcel", 22));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("是否签到", "isAttend", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("签到时间", "attendTimeExcel", 22));
|
||||
|
||||
for (FamilyCourse c : courseList) {
|
||||
String courseId = c.getId();
|
||||
String courseName = c.getCourseName();
|
||||
List<NutMap> v = userList.stream().filter(x -> x.getString("courseId").equals(courseId)).collect(Collectors.toList());
|
||||
ExportParams userExportParams = new ExportParams();
|
||||
userExportParams.setSheetName(courseName);
|
||||
|
||||
List<ExcelExportEntity> currentEntities = new ArrayList<>(excelCommonExportEntity);
|
||||
for (NutMap userSignData : v) {
|
||||
if(!userSignData.getBoolean("isAttend")) {
|
||||
userSignData.put("isAttend", "未签到");
|
||||
userSignData.put("attendTimeExcel", "未签到");
|
||||
}else {
|
||||
userSignData.put("isAttend", "已签到");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> userExportMap = new HashMap<>();
|
||||
userExportMap.put("name", courseName);
|
||||
userExportMap.put("title", userExportParams);
|
||||
userExportMap.put("entity", currentEntities);
|
||||
userExportMap.put("data", v);
|
||||
|
||||
sheetsList.add(userExportMap);
|
||||
}
|
||||
try {
|
||||
String fileName = activity.getActivityName() + "签到人员名单.xls";
|
||||
String disposition = "attachment;filename=" + URLEncoder.encode(fileName, "utf-8");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-Disposition", disposition);
|
||||
|
||||
Workbook workbook = new HSSFWorkbook();
|
||||
for (Map<String, Object> map : sheetsList) {
|
||||
ExcelExportService service = new ExcelExportService();
|
||||
service.createSheetForMap(workbook,(ExportParams) map.get("title"),(List<ExcelExportEntity>) map.get("entity"),(Collection<?>) map.get("data"));
|
||||
}
|
||||
|
||||
workbook.write(response.getOutputStream());
|
||||
workbook.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出领取人员")
|
||||
public void exportGiftPerson(@Param(value = "activityId") String activityId,
|
||||
HttpServletResponse response) {
|
||||
FamilyActivity activity = dao.fetch(FamilyActivity.class, activityId);
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
uc.*,
|
||||
DATE_FORMAT(uc.courseStartTime, '%Y-%m-%d %H:%i:%s') as courseStartTimeExcel,
|
||||
DATE_FORMAT(uc.courseEndTime, '%Y-%m-%d %H:%i:%s') as courseEndTimeExcel,
|
||||
DATE_FORMAT(uc.receiveTime, '%Y-%m-%d %H:%i:%s') as receiveTimeExcel,
|
||||
u.username,
|
||||
u.loginname,
|
||||
u.unitName,
|
||||
u.unionName,
|
||||
u.sex
|
||||
FROM
|
||||
family_user_course uc
|
||||
left join family_course course on uc.courseId = course.id
|
||||
left join `vw_user` u on u.id = uc.userId
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("uc.activityId", "=", activityId);
|
||||
cnd.and("course.isReceiveGift", "=", true).and("course.giftType" ,"=", 1);
|
||||
cnd.desc("isReceive").desc("receiveTime");
|
||||
sql.setCondition(cnd);
|
||||
|
||||
List<NutMap> userList = familyBlackListService.listMap(sql);
|
||||
|
||||
List<FamilyCourse> courseList = dao.query(FamilyCourse.class, Cnd.where("activityId", "=", activityId));
|
||||
|
||||
List<Map<String, Object>> sheetsList = new ArrayList<>();
|
||||
|
||||
List<ExcelExportEntity> excelCommonExportEntity = new ArrayList<>();
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("姓名", "username", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("单位", "unitName", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("分工会", "unionName", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("性别", "sex", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("开始时间", "courseStartTimeExcel", 22));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("结束时间", "courseEndTimeExcel", 22));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("是否领取", "isReceive", 20));
|
||||
excelCommonExportEntity.add(new ExcelExportEntity("领取时间", "receiveTimeExcel", 22));
|
||||
|
||||
for (FamilyCourse c : courseList) {
|
||||
String courseId = c.getId();
|
||||
String courseName = c.getCourseName();
|
||||
List<NutMap> v = userList.stream().filter(x -> x.getString("courseId").equals(courseId)).collect(Collectors.toList());
|
||||
ExportParams userExportParams = new ExportParams();
|
||||
userExportParams.setSheetName(courseName);
|
||||
|
||||
List<ExcelExportEntity> currentEntities = new ArrayList<>(excelCommonExportEntity);
|
||||
for (NutMap userSignData : v) {
|
||||
if(!userSignData.getBoolean("isReceive")) {
|
||||
userSignData.put("isReceive", "未领取");
|
||||
userSignData.put("receiveTimeExcel", "未领取");
|
||||
}else {
|
||||
userSignData.put("isReceive", "已领取");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> userExportMap = new HashMap<>();
|
||||
userExportMap.put("name", courseName);
|
||||
userExportMap.put("title", userExportParams);
|
||||
userExportMap.put("entity", currentEntities);
|
||||
userExportMap.put("data", v);
|
||||
|
||||
sheetsList.add(userExportMap);
|
||||
}
|
||||
try {
|
||||
String fileName = activity.getActivityName() + "礼品领取人员名单.xls";
|
||||
String disposition = "attachment;filename=" + URLEncoder.encode(fileName, "utf-8");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-Disposition", disposition);
|
||||
|
||||
Workbook workbook = new HSSFWorkbook();
|
||||
for (Map<String, Object> map : sheetsList) {
|
||||
ExcelExportService service = new ExcelExportService();
|
||||
service.createSheetForMap(workbook,(ExportParams) map.get("title"),(List<ExcelExportEntity>) map.get("entity"),(Collection<?>) map.get("data"));
|
||||
}
|
||||
|
||||
workbook.write(response.getOutputStream());
|
||||
workbook.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+275
@@ -0,0 +1,275 @@
|
||||
package com.budwk.app.zhgh.activity.family.controller.statistics;
|
||||
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.afterturn.easypoi.excel.export.ExcelExportService;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.sys.models.Sys_file;
|
||||
import com.budwk.app.sys.utils.SysFileMinIoUtil;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyActivity;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyCourse;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyType;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityService;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.json.Json;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* @author zxy
|
||||
* @Description 培训报名 统计
|
||||
* @createTime 2022年02月23日 09:57:00
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean
|
||||
@Ok("json:full")
|
||||
@Api(tags = "亲子活动统计")
|
||||
@At("/platform/family/statistics")
|
||||
public class FamilyActivityStatisticsController {
|
||||
|
||||
@Inject
|
||||
private FamilyActivityService familyActivityManageService;
|
||||
@Inject
|
||||
private FamilyActivityStatisticsService familyActivityStatisticsService;
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@At("")
|
||||
@SaCheckPermission("family.statistics")
|
||||
@Ok("beetl:/platform/zhgh/activity/family/statistics/index.html")
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("分页查询")
|
||||
@SaCheckPermission("family.statistics")
|
||||
public Result pageData(PageForm pageForm,
|
||||
@Param(value = "activityId") String activityId) {
|
||||
Pagination pagination = familyActivityStatisticsService.pageData(pageForm, activityId);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
/**
|
||||
* 活动list
|
||||
*
|
||||
* @param year 年度
|
||||
* @return
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("活动列表")
|
||||
@SaCheckPermission("family.statistics")
|
||||
public Result activityList(@Param(value = "year") Integer year) {
|
||||
List<FamilyActivity> list = dao.query(FamilyActivity.class, Cnd.NEW().andEX("year", "=", year).desc("activityStartTime"));
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 培训班报名人员list
|
||||
*
|
||||
* @param courseId
|
||||
* @return
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("报名人员列表")
|
||||
@SaCheckPermission("family.statistics")
|
||||
public Result registerUserList(@Param(value = "courseId") String courseId) {
|
||||
return Result.success(familyActivityStatisticsService.registerUserList(courseId));
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("报名动态列")
|
||||
@SaCheckPermission("family.statistics")
|
||||
public Object getTaleColumnInfo(@Param(value = "courseId") String courseId) {
|
||||
return Result.success(familyActivityStatisticsService.getTaleColumnInfo(courseId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 培训班上课签到信息
|
||||
*
|
||||
* @param courseId
|
||||
* @return
|
||||
*/
|
||||
@At
|
||||
@ApiOperation("获取签到信息")
|
||||
@SaCheckPermission("family.statistics")
|
||||
public Result getSignInfo(@Param("courseId") String courseId) {
|
||||
return Result.success(familyActivityStatisticsService.getSignInfo(courseId));
|
||||
}
|
||||
|
||||
@At
|
||||
@ApiOperation("开放报名")
|
||||
@SaCheckPermission("family.statistics")
|
||||
public Result signChange(@Param("courseId") String courseId, @Param("openOtherUnion") Boolean openOtherUnion) {
|
||||
dao.update(FamilyCourse.class, Chain.make("openOtherUnion", openOtherUnion)
|
||||
, Cnd.where("id", "=", courseId));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@ApiOperation("导出签到名单")
|
||||
@SaCheckPermission("family.statistics")
|
||||
public void exportSignUser(@Param(value = "activityId") String activityId,
|
||||
HttpServletResponse response) throws IOException {
|
||||
try {
|
||||
FamilyActivity activity = dao.fetch(FamilyActivity.class, activityId);
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
ts.*,
|
||||
CONCAT(DATE_FORMAT(ac.courseStartTime, '%H:%i:%s'),'至',DATE_FORMAT(ac.courseEndTime, '%H:%i:%s')) AS courseTime,
|
||||
u.username,
|
||||
u.loginname,
|
||||
u.sex,
|
||||
ifnull(u.mobile, ts.mobile) as newMobile,
|
||||
u.birthday,
|
||||
tsc.courseName
|
||||
FROM
|
||||
family_user ts
|
||||
left join family_activity_course ac on ts.activityCourseId = ac.id
|
||||
left join `vw_user` u on u.id = ts. userId
|
||||
left join family_course tsc on tsc.id = ts.courseId
|
||||
WHERE
|
||||
ts.activityId = @activityId
|
||||
""").setParam("activityId", activityId);
|
||||
List<NutMap> userList = familyActivityManageService.listMap(sql);
|
||||
|
||||
List<FamilyCourse> courseList = dao.query(FamilyCourse.class, Cnd.where("activityId", "=", activityId));
|
||||
|
||||
List<FamilyType> familyTypeList = dao.query(FamilyType.class, Cnd.NEW());
|
||||
dao.fetchLinks(familyTypeList, "familyMobileSignColumnList", Cnd.NEW().asc("columnIndex"));
|
||||
Map<String, FamilyType> typeMap = familyTypeList.stream().collect(Collectors.toMap(FamilyType::getId, o -> o));
|
||||
|
||||
List<Map<String, Object>> sheetsList = new ArrayList<>();
|
||||
|
||||
List<Map<String, String>> basicEntity = List.of(
|
||||
Map.of("name", "姓名", "key", "username"),
|
||||
Map.of("name", "工号", "key", "loginname"),
|
||||
Map.of("name", "单位", "key", "unitName"),
|
||||
Map.of("name", "分工会", "key", "unionName"),
|
||||
Map.of("name", "性别", "key", "sex"),
|
||||
Map.of("name", "人事系统手机号", "key", "newMobile"),
|
||||
Map.of("name", "报名时段", "key", "courseTime")
|
||||
);
|
||||
|
||||
List<ExcelExportEntity> excelCommonExportEntity = basicEntity.stream().map(entity -> {
|
||||
ExcelExportEntity excelExportEntity = new ExcelExportEntity();
|
||||
excelExportEntity.setKey(entity.get("key"));
|
||||
excelExportEntity.setName(entity.get("name"));
|
||||
excelExportEntity.setWidth(20);
|
||||
excelExportEntity.setNeedMerge(true);
|
||||
return excelExportEntity;
|
||||
}).collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
for (FamilyCourse c : courseList) {
|
||||
String k = c.getCourseName();
|
||||
List<NutMap> courseSignUsers = userList.stream().filter(x -> x.getString("courseName").equals(k)).collect(Collectors.toCollection(ArrayList::new));
|
||||
ExportParams userExportParams = new ExportParams();
|
||||
userExportParams.setSheetName(k);
|
||||
userExportParams.setType(ExcelType.HSSF);
|
||||
|
||||
List<ExcelExportEntity> currentEntities = new ArrayList<>(excelCommonExportEntity);
|
||||
|
||||
FamilyType signUpType = typeMap.get(c.getCourseType());
|
||||
if (Lang.isNotEmpty(signUpType.getFamilyMobileSignColumnList())) {
|
||||
ExcelExportEntity familyEntity = new ExcelExportEntity("家属信息", "familyInfos", 20);
|
||||
List<ExcelExportEntity> signColumn = signUpType.getFamilyMobileSignColumnList().stream().map(column -> {
|
||||
ExcelExportEntity entity = new ExcelExportEntity();
|
||||
entity.setName(column.getColumnName());
|
||||
entity.setKey(column.getColumnCode());
|
||||
entity.setWidth(20);
|
||||
if ("FILE".equals(column.getColumnFormType())) {
|
||||
entity.setType(2);
|
||||
entity.setExportImageType(2);
|
||||
}
|
||||
return entity;
|
||||
}).collect(Collectors.toCollection(ArrayList::new));
|
||||
familyEntity.setList(signColumn);
|
||||
currentEntities.add(familyEntity);
|
||||
}
|
||||
for (NutMap userSignData : courseSignUsers) {
|
||||
String mobileColumnsValueStr = userSignData.getString("mobileColumnsValue");
|
||||
if (StrUtil.isNotBlank(mobileColumnsValueStr)) {
|
||||
JSONArray outerArray = JSONUtil.parseArray(mobileColumnsValueStr);
|
||||
List<List<JSONObject>> result = outerArray.stream()
|
||||
.map(item -> {
|
||||
// 每个 item 又是一个数组
|
||||
JSONArray innerArray = (JSONArray) item;
|
||||
return innerArray.toList(JSONObject.class);
|
||||
})
|
||||
.toList();
|
||||
List<NutMap> familyInfos = new ArrayList<>();
|
||||
for (List<JSONObject> list : result) {
|
||||
NutMap familyMap = new NutMap();
|
||||
for (JSONObject column : list) {
|
||||
if (!"FILE".equals(column.getStr("columnFormType"))) {
|
||||
familyMap.put(column.getStr("columnCode"), column.getStr("columnValue"));
|
||||
} else {
|
||||
if (StrUtil.isNotBlank(column.getStr("columnValue"))) {
|
||||
List<JSONObject> columnValue = Json.fromJsonAsList(JSONObject.class, column.getStr("columnValue"));
|
||||
if (columnValue.size() == 1) {
|
||||
JSONObject sysFile = columnValue.get(0);
|
||||
Sys_file file = dao.fetch(Sys_file.class, Cnd.where(Sys_file::getDownloadPath, "=", sysFile.get("url")));
|
||||
byte[] imageBytes = SysFileMinIoUtil.getFileBytes(file.getBucket(), file.getStoragePath());
|
||||
if (imageBytes.length > 0) {
|
||||
familyMap.put(column.getStr("columnCode"), imageBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
familyInfos.add(familyMap);
|
||||
}
|
||||
userSignData.put("familyInfos", familyInfos);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> userExportMap = new HashMap<>();
|
||||
userExportMap.put("name", k);
|
||||
userExportMap.put("title", userExportParams);
|
||||
userExportMap.put("entity", currentEntities);
|
||||
userExportMap.put("data", courseSignUsers);
|
||||
|
||||
sheetsList.add(userExportMap);
|
||||
}
|
||||
|
||||
Workbook workbook = new HSSFWorkbook();
|
||||
for (Map<String, Object> map : sheetsList) {
|
||||
ExcelExportService service = new ExcelExportService();
|
||||
service.createSheetForMap(workbook, (ExportParams) map.get("title"), (List<ExcelExportEntity>) map.get("entity"), (Collection<?>) map.get("data"));
|
||||
}
|
||||
CommonDownloadUtil.download(activity.getActivityName() + "报名人员名单" + ".xlsx", workbook, response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.sys.services.SysHomeConvert;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
import org.nutz.lang.Lang;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动")
|
||||
@Table("family_activity")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyActivity extends BaseModel implements Serializable, SysHomeConvert {
|
||||
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
@Comment("活动名称")
|
||||
private String activityName;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("年度")
|
||||
private Integer year;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("活动报名开始时间")
|
||||
private Date activitySignUpStartTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("活动报名开始时间")
|
||||
private Date activitySignUpEndTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("活动开始时间")
|
||||
private Date activityStartTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("活动结束时间")
|
||||
private Date activityEndTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("是否禁用")
|
||||
@Default("0")
|
||||
private boolean isDisabled;
|
||||
|
||||
@Column
|
||||
@ColDefine(customType = "longtext")
|
||||
@Comment("活动介绍")
|
||||
private String introduce;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT, width = 10)
|
||||
@Comment("活动限制标识")
|
||||
private Integer restrictLimit;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT, width = 10)
|
||||
@Comment("活动限制报名个数")
|
||||
private Integer limitNum;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
@Comment("活动封面")
|
||||
private String cover;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
@Comment("微信群二维码")
|
||||
private String wechat;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("上课前是否通知")
|
||||
@Default("0")
|
||||
private boolean notice;
|
||||
|
||||
@Column
|
||||
@Comment("活动范围Id")
|
||||
@ColDefine(type = ColType.INT, width = 32)
|
||||
private Integer activityGroupId;
|
||||
|
||||
@Column
|
||||
@Comment("活动范围名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 40)
|
||||
private String activityGroupName;
|
||||
|
||||
@Many(field = "activityId")
|
||||
private List<FamilyCourse> courseList;
|
||||
|
||||
@Many(field = "activityId")
|
||||
private List<FamilyTypeLimit> typeLimits;
|
||||
|
||||
@Column
|
||||
@Comment("活动类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String trainType;
|
||||
|
||||
@Column
|
||||
@Comment("关键词")
|
||||
@Default("家属")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
private String keyWord;
|
||||
|
||||
@Column
|
||||
@Comment("家属最多数")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer familyMaxCount;
|
||||
|
||||
@Column
|
||||
@Comment("判断家属数量的唯一标识")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String onlyKey;
|
||||
|
||||
@Override
|
||||
public Sys_home_activity covertToSysHomeActivity() {
|
||||
Sys_home_activity sysHomeActivity = new Sys_home_activity();
|
||||
sysHomeActivity.setId(this.getId());
|
||||
sysHomeActivity.setName(this.getActivityName());
|
||||
sysHomeActivity.setCover(this.getCover());
|
||||
sysHomeActivity.setUrl("/platform/family/apply");
|
||||
sysHomeActivity.setH5Url("/platform/family/apply/h5?id=" + this.getId());
|
||||
if (Lang.isNotEmpty(this.getActivitySignUpStartTime())) {
|
||||
sysHomeActivity.setStartDate(this.getActivitySignUpStartTime());
|
||||
sysHomeActivity.setEndDate(this.getActivitySignUpEndTime());
|
||||
}
|
||||
sysHomeActivity.setAllowUserGroupId(this.getActivityGroupId());
|
||||
sysHomeActivity.setEnable(!this.isDisabled());
|
||||
sysHomeActivity.setClassPath(this.getClass().getPackageName() + this.getClass().getName());
|
||||
return sysHomeActivity;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动下的子活动")
|
||||
@Table("family_activity_course")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyActivityCourse {
|
||||
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("活动ID")
|
||||
private String activityId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("课程ID")
|
||||
private String courseId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("课程开始时间")
|
||||
private Date courseStartTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("课程结束时间")
|
||||
private Date courseEndTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATE)
|
||||
@Comment("课程时间")
|
||||
private Date courseDate;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT, width = 4)
|
||||
@Comment("限制人数")
|
||||
private Integer courseLimitNum;
|
||||
|
||||
private Integer hasRegisterNum;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动黑名单")
|
||||
@Table("family_black_list")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyBlackList {
|
||||
|
||||
@Name
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("用户id")
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("是否禁用")
|
||||
private Boolean isDisabled;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动的子活动")
|
||||
@Table("family_course")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyCourse extends BaseModel implements Serializable {
|
||||
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
@Comment("活动ID")
|
||||
private String activityId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
@Comment("课程名称")
|
||||
private String courseName;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("课程人数")
|
||||
private int coursePeopleNumber;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Default(value = "0")
|
||||
@Comment("预留名额")
|
||||
private int courseReservedNumber;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
@Comment("课程地点")
|
||||
private String courseLocation;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("课程类型")
|
||||
private String courseType;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
@Comment("课程地点坐标")
|
||||
private List<Double> courseLocationCoordinates;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
@Comment("课程讲师")
|
||||
private String courseInstructor;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("校区")
|
||||
private String campus;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("报名人数是否限制")
|
||||
private Boolean courseIsLimitApply;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("序号")
|
||||
private int orderNum;
|
||||
|
||||
@Column
|
||||
@ColDefine(customType = "longtext")
|
||||
@Comment("详细信息")
|
||||
private String introduce;
|
||||
|
||||
@Many(field = "courseId")
|
||||
private List<FamilyActivityCourse> courseTimeList;
|
||||
|
||||
@Column
|
||||
@Comment("分工会人数限制")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
private List<NutMap> unionLimit;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("移动端是否签到")
|
||||
@Default("0")
|
||||
private boolean isMobileSign;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("签到方式 1.扫描二维码签到 2.被扫 3.gps签到")
|
||||
private Integer signType;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("移动端是否签收礼品")
|
||||
@Default("0")
|
||||
private boolean isReceiveGift;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("领取礼品方式 1.扫描二维码 2.线下")
|
||||
private Integer giftType;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("预留名额方式 1.报名人员减少模式 2.报名人数不变模式")
|
||||
private Integer reserveMode;
|
||||
|
||||
@Column
|
||||
@Comment("承办工会")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String hostUnionId;
|
||||
|
||||
@Column
|
||||
@Comment("对内报名时间")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String interTime;
|
||||
|
||||
@Column
|
||||
@Comment("是否开放给其他工会")
|
||||
@ColDefine(type = ColType.BOOLEAN, width = 4)
|
||||
private Boolean openOtherUnion;
|
||||
|
||||
@Column
|
||||
@Comment("分类标识")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 30)
|
||||
private String assort;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Default(value = "0")
|
||||
@Comment("候补名额数")
|
||||
private Integer waitingNum;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("是否限制年龄")
|
||||
@Default("0")
|
||||
private boolean familyAgeLimit;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("最小年龄")
|
||||
private Integer minAge;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("最大年龄")
|
||||
private Integer maxAge;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("是否限制性别")
|
||||
@Default("0")
|
||||
private boolean familySexLimit;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR)
|
||||
@Comment("限制性别")
|
||||
private String familySex;
|
||||
|
||||
private Integer hasWaitingNum;
|
||||
private String courseTimeName;
|
||||
private Integer hasRegisterNum;
|
||||
private Boolean isBringFamily;
|
||||
private Boolean isAddFamily;
|
||||
private Boolean isSign;
|
||||
private Boolean canSignThisCourseType;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动移动端动态表单")
|
||||
@Table("family_mobile_sign_column")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyMobileSignColumn implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Name
|
||||
@Comment("id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("类型id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String typeId;
|
||||
|
||||
@Column
|
||||
@Comment("字段名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String columnName;
|
||||
|
||||
@Column
|
||||
@Comment("字段编码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String columnCode;
|
||||
|
||||
@Column
|
||||
@Comment("字段值")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String columnValue;
|
||||
|
||||
@Column
|
||||
@Comment("字段类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String columnType;
|
||||
|
||||
@Column
|
||||
@Comment("下拉框的值")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
private List<String> selectValues;
|
||||
|
||||
@Column
|
||||
@Comment("是否必填")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
private Boolean isRequired;
|
||||
|
||||
@Column
|
||||
@Comment("控件类型")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String columnFormType;
|
||||
|
||||
@Column
|
||||
@Comment("文件个数")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer fileNumber;
|
||||
|
||||
@Column
|
||||
@Comment("文件类型")
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
private List<String> fileType;
|
||||
|
||||
@Column
|
||||
@Comment("序号")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
private Integer columnIndex;
|
||||
|
||||
@Column
|
||||
@Comment("验证规则")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String validRule;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import com.budwk.app.base.model.BaseModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动的子活动类型")
|
||||
@Table("family_type")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyType extends BaseModel implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Name
|
||||
@Comment("id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("类型编码")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 80)
|
||||
private String code;
|
||||
|
||||
@Column
|
||||
@Comment("类型名称")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 80)
|
||||
private String typeName;
|
||||
|
||||
@Column
|
||||
@Comment("序号")
|
||||
@ColDefine(type = ColType.INT, width = 1)
|
||||
private Integer xh;
|
||||
|
||||
@Column
|
||||
@Comment("是否携带家属")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("1")
|
||||
private Boolean isBringFamily;
|
||||
|
||||
@Column
|
||||
@Comment("家属纳入总人数")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("1")
|
||||
private Boolean isAddFamily;
|
||||
|
||||
@Column
|
||||
@Comment("本人纳入总人数")
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Default("1")
|
||||
private Boolean selfAddFamily;
|
||||
|
||||
@Many(field = "typeId")
|
||||
private List<FamilyMobileSignColumn> familyMobileSignColumnList;
|
||||
|
||||
@Column
|
||||
@Comment("家属最多数")
|
||||
@ColDefine(type = ColType.INT)
|
||||
private Integer familyMaxCount;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("子活动类型限制条件")
|
||||
@Table("family_type_limit")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class FamilyTypeLimit implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Name
|
||||
@Comment("id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@Comment("活动id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String activityId;
|
||||
|
||||
@Column
|
||||
@Comment("活动类型id")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String typeId;
|
||||
|
||||
@Column
|
||||
@Comment("限制个数")
|
||||
@ColDefine(type = ColType.INT, width = 10)
|
||||
private int limitNum;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动报名人员")
|
||||
@Table("family_user")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableIndexes({@Index(name = "INDEX_FAMILY_USER_COURSEID", fields = {"courseId"}, unique = false)})
|
||||
public class FamilyUser implements Serializable {
|
||||
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("活动ID")
|
||||
private String activityId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("课程ID")
|
||||
private String courseId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("用户ID")
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("工会ID")
|
||||
private String unionId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("单位ID")
|
||||
private String unitId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
@Comment("工会")
|
||||
private String unionName;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
@Comment("单位")
|
||||
private String unitName;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("联系方式")
|
||||
private String mobile;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("报名时间")
|
||||
private Date signUpTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("活动课程时段id")
|
||||
private String activityCourseId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.MYSQL_JSON)
|
||||
@Comment("手机端报名字段和值")
|
||||
private List<List<NutMap>> mobileColumnsValue;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.INT)
|
||||
@Comment("用户报名状态(1.正常 2.待报名成功 3.也是正常,但是是从2变为1的 4.废弃[就是没签到的意思])")
|
||||
private Integer state;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.budwk.app.zhgh.activity.family.models;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.nutz.dao.entity.annotation.*;
|
||||
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
@Comment("亲子活动报名人员子活动表")
|
||||
@Table("family_user_course")
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@TableIndexes({
|
||||
@Index(name = "INDEX_FAMILY_USER_COURSE_USERID", fields = {"userId"}, unique = false),
|
||||
@Index(name = "INDEX_FAMILY_USER_COURSE_COURSEID", fields = {"courseId"}, unique = false)
|
||||
})
|
||||
public class FamilyUserCourse implements Serializable {
|
||||
|
||||
@Name
|
||||
@PrevInsert(uu32 = true)
|
||||
private String id;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("活动ID")
|
||||
private String activityId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("课程ID")
|
||||
private String courseId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("用户ID")
|
||||
private String userId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("课程开始时间")
|
||||
private Date courseStartTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("课程结束时间")
|
||||
private Date courseEndTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("是否上课")
|
||||
private boolean isAttend;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("上课打卡时间")
|
||||
private Date attendTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.BOOLEAN)
|
||||
@Comment("是否领取礼品")
|
||||
private Boolean isReceive;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.DATETIME)
|
||||
@Comment("领取礼品时间")
|
||||
private Date receiveTime;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("签到扫码人员id(二维码模式)")
|
||||
private String signScannerCodeUserId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("礼品扫码人员id(二维码模式)")
|
||||
private String giftScannerCodeUserId;
|
||||
|
||||
@Column
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
@Comment("关联family_activity_course表的id")
|
||||
private String activityCourseId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.budwk.app.zhgh.activity.family.service;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyActivity;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyCourse;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyUser;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
public interface FamilyActivityService extends BaseService<FamilyActivity> {
|
||||
|
||||
/**
|
||||
* 添加活动
|
||||
* @param activity 活动信息
|
||||
* @param course 培训班信息
|
||||
*/
|
||||
void add(FamilyActivity activity, FamilyCourse course);
|
||||
|
||||
/**
|
||||
* 编辑活动
|
||||
* @param activity 活动信息
|
||||
*/
|
||||
void edit(FamilyActivity activity);
|
||||
|
||||
/**
|
||||
* 更新活动状态
|
||||
* @param activity 活动信息
|
||||
*/
|
||||
void updateActivityStatus(FamilyActivity activity);
|
||||
|
||||
/**
|
||||
* 查询单条活动信息
|
||||
* @param id 活动ID
|
||||
* @return 返回的数据与前端符合
|
||||
*/
|
||||
NutMap findOne(String id, Cnd cnd, String fromMode);
|
||||
|
||||
/**
|
||||
* pc分页查询
|
||||
* @param pageForm
|
||||
* @param cnd
|
||||
* @return
|
||||
*/
|
||||
Pagination pageData(PageForm pageForm, Cnd cnd);
|
||||
|
||||
|
||||
/**
|
||||
* 手机端分页查询
|
||||
* @param pageForm 分页
|
||||
* @param year 年度
|
||||
* @param activityStatus 报名状态 0全部 1进行中 2结束
|
||||
* @return
|
||||
*/
|
||||
Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType);
|
||||
|
||||
/**
|
||||
* 手机端报名
|
||||
* @param familyUser 活动ID
|
||||
*/
|
||||
void doSignUp(FamilyUser familyUser) throws Exception;
|
||||
|
||||
/**
|
||||
* 异步插入每个报名成功人员的课程数据
|
||||
* @param activityId
|
||||
* @param courseId
|
||||
* @param userId
|
||||
*/
|
||||
void asyncInsertUserCourse(String activityId, String courseId, String userId);
|
||||
|
||||
/**
|
||||
* 该培训班每个分工会名额是否报满
|
||||
* @return
|
||||
*/
|
||||
boolean isSignFullByUnionId(FamilyCourse course, Integer currentFamilyNumber);
|
||||
|
||||
/**
|
||||
* 该培训班是否报满
|
||||
*/
|
||||
boolean isSignFull(FamilyCourse course, Integer currentFamilyNumber);
|
||||
|
||||
boolean validFamilyCount(FamilyUser user);
|
||||
|
||||
/**
|
||||
* 还能报该类型的培训班吗 比如书画班最多报一项 健身班两项
|
||||
* @return
|
||||
*/
|
||||
boolean isSignCourse(FamilyCourse course, FamilyActivity activity);
|
||||
|
||||
/**
|
||||
* 当前用户是否已报过该培训班
|
||||
* @param courseId
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
boolean isSignCourseByUser(String courseId, String userId);
|
||||
|
||||
/**
|
||||
* 手机端签到
|
||||
* @param id 每个培训班每节课每个用户的记录ID
|
||||
*/
|
||||
void doQd(String id);
|
||||
|
||||
/**
|
||||
* 某个用户的签到信息
|
||||
* @param userId 用户id
|
||||
* @param activityId 活动id
|
||||
*/
|
||||
List<NutMap> qdInfoByUserId(String userId, String activityId);
|
||||
|
||||
List<FamilyCourse> filterCourseByHostUnion(List<FamilyCourse> courseList);
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package com.budwk.app.zhgh.activity.family.service;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyUser;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
public interface FamilyActivityStatisticsService extends BaseService<FamilyUser> {
|
||||
|
||||
/**
|
||||
* 统计分页
|
||||
* @param pageForm
|
||||
* @param activityId
|
||||
* @return
|
||||
*/
|
||||
Pagination pageData(PageForm pageForm, String activityId);
|
||||
|
||||
/**
|
||||
* 该课程下的报名人员信息
|
||||
* @param courseId
|
||||
* @return
|
||||
*/
|
||||
List<NutMap> registerUserList(String courseId);
|
||||
|
||||
List<NutMap> getTaleColumnInfo(String courseId);
|
||||
|
||||
/**
|
||||
* 该课程下的报名人员信息
|
||||
* @param courseId
|
||||
* @return
|
||||
*/
|
||||
List<NutMap> registerUserList(String courseId, String unionId, String unitId, String searchName, String searchKeyword);
|
||||
|
||||
/**
|
||||
* 获取每个课程的签到情况
|
||||
* @param courseId
|
||||
* @return k->每个培训班每节课的上课时间 v->上课记录list
|
||||
*/
|
||||
Map<String, List<NutMap>> getSignInfo(String courseId);
|
||||
|
||||
/**
|
||||
* 报名人员list 导出
|
||||
* @param activityId
|
||||
* @return
|
||||
*/
|
||||
List<NutMap> baoMingUserList(String activityId);
|
||||
|
||||
int queryCourseCount(String courseId, String courseType);
|
||||
|
||||
int queryCourseWaitCount(String courseId, String courseType);
|
||||
|
||||
int queryCourseCount(String courseId, String courseType, String unionId);
|
||||
|
||||
int queryCourseWaitCount(String courseId, String courseType, String unionId);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.budwk.app.zhgh.activity.family.service;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.BaseService;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyBlackList;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
public interface FamilyBlackListService extends BaseService<FamilyBlackList> {
|
||||
|
||||
/**
|
||||
* 分页
|
||||
* @param pageForm 分页
|
||||
* @return Pagination
|
||||
*/
|
||||
Pagination pageData(PageForm pageForm, Cnd cnd, String activityId, String courseId);
|
||||
|
||||
/**
|
||||
* 拉黑、解封用户
|
||||
* @param userId
|
||||
*/
|
||||
void doHandleUser(String userId);
|
||||
|
||||
/**
|
||||
* 上课记录
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
List<NutMap> attendClassRecord(String userId);
|
||||
|
||||
}
|
||||
+500
@@ -0,0 +1,500 @@
|
||||
package com.budwk.app.zhgh.activity.family.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.sys.models.Sys_home_activity;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.family.models.*;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityService;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsService;
|
||||
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpActivityCourse;
|
||||
import com.budwk.app.zhgh.activity.trainSignUp.models.TrainSignUpUserCourse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.aop.interceptor.async.Async;
|
||||
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.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.Static;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author NINGMEI
|
||||
*/
|
||||
@Slf4j
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class FamilyActivityServiceImpl extends BaseServiceImpl<FamilyActivity> implements FamilyActivityService {
|
||||
|
||||
@Inject
|
||||
private FamilyActivityStatisticsService statisticsService;
|
||||
|
||||
public FamilyActivityServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void add(FamilyActivity activity, FamilyCourse course) {
|
||||
|
||||
dao().insert(activity);
|
||||
|
||||
//插入类型限制
|
||||
List<FamilyTypeLimit> typeLimits = activity.getTypeLimits();
|
||||
typeLimits.forEach(v -> v.setActivityId(activity.getId()));
|
||||
dao().insert(typeLimits);
|
||||
|
||||
List<FamilyCourse> courseList = activity.getCourseList();
|
||||
for (FamilyCourse v : courseList) {
|
||||
v.setActivityId(activity.getId());
|
||||
v.setOpenOtherUnion(false);
|
||||
dao().insert(v);
|
||||
this.setCourseTimeAndInsert(v);
|
||||
}
|
||||
|
||||
if (!activity.isDisabled()) {
|
||||
Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity();
|
||||
dao().insertOrUpdate(sysHomeActivity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void edit(FamilyActivity activity) {
|
||||
|
||||
//修改活动
|
||||
update(activity);
|
||||
|
||||
//修改类型限制
|
||||
List<FamilyTypeLimit> typeLimits = activity.getTypeLimits();
|
||||
typeLimits.forEach(v -> v.setActivityId(activity.getId()));
|
||||
if(Lang.isNotEmpty(typeLimits)) {
|
||||
insertOrUpdate(typeLimits);
|
||||
}
|
||||
|
||||
List<FamilyCourse> courseList = activity.getCourseList();
|
||||
courseList.forEach(v -> {
|
||||
v.setActivityId(activity.getId());
|
||||
dao().insertOrUpdate(v);
|
||||
if (Lang.isNotEmpty(v.getCourseTimeList())) {
|
||||
this.setCourseTimeAndInsert(v);
|
||||
}
|
||||
});
|
||||
|
||||
//查询原来的活动
|
||||
List<FamilyCourse> oldCourseList = dao().query(FamilyCourse.class, Cnd.where("activityId", "=", activity.getId()));
|
||||
//原来的培训班id
|
||||
List<String> oldCourseIdList = oldCourseList.stream().map(FamilyCourse::getId).toList();
|
||||
|
||||
//原来的上课时间
|
||||
List<FamilyActivityCourse> oldActCourseTimeList = dao().query(FamilyActivityCourse.class, Cnd.where("activityId", "=", activity.getId()));
|
||||
|
||||
//现在的上课时间
|
||||
List<String> nowCourseTimeListId = new ArrayList<>();
|
||||
activity.getCourseList().forEach(v -> {
|
||||
if (v.getCourseTimeList() != null) {
|
||||
nowCourseTimeListId.addAll(v.getCourseTimeList().stream().map(FamilyActivityCourse::getId).toList());
|
||||
}
|
||||
});
|
||||
|
||||
List<String> deleteCourseTimeListId = oldActCourseTimeList.stream().map(FamilyActivityCourse::getId).filter(id -> !nowCourseTimeListId.contains(id)).collect(Collectors.toList());
|
||||
List<String> courseIdList = courseList.stream().map(FamilyCourse::getId).collect(Collectors.toList());
|
||||
|
||||
//删除关联的培训班
|
||||
List<String> deleteIdList = oldCourseIdList.stream().filter(v -> !courseIdList.contains(v)).collect(Collectors.toList());
|
||||
dao().clear(FamilyCourse.class, Cnd.where("id", "in", deleteIdList));
|
||||
|
||||
dao().clear(FamilyActivityCourse.class, Cnd.where("id", "in", deleteCourseTimeListId));
|
||||
dao().clear(FamilyUser.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId()));
|
||||
dao().clear(FamilyUserCourse.class, Cnd.where("courseId", "not in", courseIdList).and("activityId", "=", activity.getId()));
|
||||
|
||||
//查询修改过培训时间的记录
|
||||
Sql tsuucSql = Sqls.create("""
|
||||
SELECT
|
||||
tsuuc.id,
|
||||
tsuac.courseStartTime,
|
||||
tsuac.courseEndTime
|
||||
FROM
|
||||
`family_user_course` tsuuc
|
||||
LEFT JOIN family_activity_course tsuac ON tsuac.id = tsuuc.activityCourseId
|
||||
where tsuuc.courseStartTime != tsuac.courseStartTime or tsuuc.courseEndTime != tsuac.courseEndTime
|
||||
""");
|
||||
List<NutMap> tsuucList = listMap(tsuucSql);
|
||||
tsuucList.forEach(v -> {
|
||||
Chain chain = Chain.make("courseStartTime", v.getTime("courseStartTime"));
|
||||
chain.add("courseEndTime", v.getTime("courseEndTime"));
|
||||
Cnd cnd = Cnd.where("id", "=", v.getString("id"));
|
||||
dao().update("family_user_course", chain, cnd);
|
||||
});
|
||||
|
||||
if (!activity.isDisabled()) {
|
||||
Sys_home_activity sysHomeActivity = activity.covertToSysHomeActivity();
|
||||
dao().insertOrUpdate(sysHomeActivity);
|
||||
} else {
|
||||
dao().delete(Sys_home_activity.class, activity.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void setCourseTimeAndInsert(FamilyCourse course) {
|
||||
course.getCourseTimeList().forEach(courseTime -> {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(courseTime.getCourseDate());
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
int month = calendar.get(Calendar.MONTH);
|
||||
int day = calendar.get(Calendar.DATE);
|
||||
|
||||
Calendar startCalendar = Calendar.getInstance();
|
||||
startCalendar.setTime(courseTime.getCourseStartTime());
|
||||
startCalendar.set(year, month, day);
|
||||
courseTime.setCourseStartTime(startCalendar.getTime());
|
||||
|
||||
Calendar endCalendar = Calendar.getInstance();
|
||||
endCalendar.setTime(courseTime.getCourseEndTime());
|
||||
endCalendar.set(year, month, day);
|
||||
courseTime.setCourseEndTime(endCalendar.getTime());
|
||||
|
||||
courseTime.setActivityId(course.getActivityId());
|
||||
courseTime.setCourseId(course.getId());
|
||||
dao().insertOrUpdate(courseTime);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void updateActivityStatus(FamilyActivity activity) {
|
||||
updateIgnoreNull(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NutMap findOne(String id, Cnd cnd, String fromMode) {
|
||||
if (Lang.isEmpty(cnd)) {
|
||||
cnd = Cnd.NEW();
|
||||
}
|
||||
|
||||
cnd.asc("orderNum").asc("campus").desc("courseLocation").asc("courseType").asc("courseName");
|
||||
List<FamilyCourse> courseArray = dao().query(FamilyCourse.class, cnd.and("activityId", "=", id));
|
||||
|
||||
if (StrUtil.isNotBlank(fromMode) && "mobile".equals(fromMode)) {
|
||||
courseArray = this.filterCourseByHostUnion(courseArray);
|
||||
}
|
||||
|
||||
FamilyActivity activity = fetchLinks(dao().fetch(FamilyActivity.class, id), "^(conditionStructure|typeLimits)$");
|
||||
activity.setCourseList(courseArray);
|
||||
|
||||
List<FamilyCourse> courseList = activity.getCourseList();
|
||||
|
||||
courseList.forEach(c -> {
|
||||
if (StrUtil.isNotBlank(c.getCourseType())) {
|
||||
dao().fetchLinks(c, "^(courseTimeList)$", Cnd.NEW().asc("courseStartTime"));
|
||||
int courseCount = statisticsService.queryCourseCount(c.getId(), c.getCourseType());
|
||||
c.setHasRegisterNum(courseCount);
|
||||
int courseWaitCount = statisticsService.queryCourseWaitCount(c.getId(), c.getCourseType());
|
||||
c.setHasWaitingNum(courseWaitCount);
|
||||
//当前用户是否报过
|
||||
c.setIsSign(isSignCourseByUser(c.getId(), SecurityUtil.getUserId()));
|
||||
}
|
||||
});
|
||||
return Lang.obj2nutmap(activity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination pageData(PageForm pageForm, Cnd cnd) {
|
||||
Pagination pagination = listPageLinks(pageForm.getPageNumber(), pageForm.getPageSize(), cnd, "^(courseList)$");
|
||||
return pagination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination mPageData(PageForm pageForm, Integer year, int activityStatus, Integer activityType) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("year", "=", year);
|
||||
switch (activityStatus) {
|
||||
case 2 -> {
|
||||
cnd.and(new Static("activitySignUpStartTime < now()"));
|
||||
cnd.and(new Static("activitySignUpEndTime > now()"));
|
||||
}
|
||||
case 3 -> {
|
||||
cnd.and(new Static("activityStartTime < now()"));
|
||||
cnd.and(new Static("activityEndTime > now()"));
|
||||
}
|
||||
case 4 -> cnd.and(new Static("activityEndTime < now()"));
|
||||
case 5 -> cnd.and(new Static("activityStartTime < now()"));
|
||||
case 6 -> cnd.and(new Static("activityStartTime > now()"));
|
||||
}
|
||||
if (activityType != null && activityType == 1) {
|
||||
cnd.and(new Static("id in (select activityId from family_user where userId = '%s')".formatted(SecurityUtil.getUserId())));
|
||||
}
|
||||
cnd.and("isDisabled", "=", 0);
|
||||
cnd.orderBy("activityEndTime", "desc");
|
||||
cnd.orderBy("isDisabled", "desc");
|
||||
cnd.orderBy("createdAt", "desc");
|
||||
return listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void doSignUp(FamilyUser familyUser) throws Exception {
|
||||
String userId = SecurityUtil.getUserId();
|
||||
|
||||
//查询课程
|
||||
FamilyCourse course = dao().fetch(FamilyCourse.class, familyUser.getCourseId());
|
||||
FamilyType type = dao().fetch(FamilyType.class, course.getCourseType());
|
||||
//如果这个课程的预留名额方式为报名人数不变
|
||||
if (course.getReserveMode() == 2) {
|
||||
//如果当前报名+已报小于这个课程限制人数
|
||||
//课程已报人数
|
||||
int normalCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType());
|
||||
//+1是算自己
|
||||
int hasRegisterNum = type.getSelfAddFamily() ? normalCount + 1 : 0;
|
||||
familyUser.setState((hasRegisterNum + course.getCourseReservedNumber()) > course.getCoursePeopleNumber() ? 2 : 1);
|
||||
} else {
|
||||
familyUser.setState(1);
|
||||
}
|
||||
|
||||
View_user user = dao().fetch(View_user.class, Cnd.where("id", "=", SecurityUtil.getUserId()));
|
||||
familyUser.setUnionId(SecurityUtil.getUnionId());
|
||||
familyUser.setUnionName(user.getUnionName());
|
||||
familyUser.setUnitId(SecurityUtil.getUnitId());
|
||||
familyUser.setUnitName(user.getUnitName());
|
||||
familyUser.setUserId(userId);
|
||||
familyUser.setSignUpTime(new Date());
|
||||
|
||||
dao().insert(familyUser);
|
||||
|
||||
if (StrUtil.isNotBlank(familyUser.getActivityCourseId())) {
|
||||
TrainSignUpActivityCourse fetch = dao().fetch(TrainSignUpActivityCourse.class, familyUser.getActivityCourseId());
|
||||
TrainSignUpUserCourse userCourse = new TrainSignUpUserCourse();
|
||||
userCourse.setActivityId(familyUser.getActivityId());
|
||||
userCourse.setCourseId(familyUser.getCourseId());
|
||||
userCourse.setUserId(familyUser.getUserId());
|
||||
userCourse.setCourseStartTime(fetch.getCourseStartTime());
|
||||
userCourse.setCourseEndTime(fetch.getCourseEndTime());
|
||||
userCourse.setAttend(false);
|
||||
userCourse.setAttendTime(null);
|
||||
userCourse.setActivityCourseId(fetch.getId());
|
||||
dao().insert(userCourse);
|
||||
} else {
|
||||
asyncInsertUserCourse(familyUser.getActivityId(), familyUser.getCourseId(), userId);
|
||||
}
|
||||
}
|
||||
|
||||
@Async
|
||||
@Override
|
||||
public void asyncInsertUserCourse(String activityId, String courseId, String userId) {
|
||||
log.info("异步插入{}的上课信息,课程ID为{},活动ID为{}", userId, courseId, activityId);
|
||||
List<FamilyActivityCourse> courseList = dao().query(FamilyActivityCourse.class, Cnd.where("courseId", "=", courseId));
|
||||
List<FamilyUserCourse> list = new ArrayList<>();
|
||||
courseList.forEach(v -> {
|
||||
FamilyUserCourse userCourse = new FamilyUserCourse();
|
||||
userCourse.setActivityId(activityId);
|
||||
userCourse.setCourseId(courseId);
|
||||
userCourse.setUserId(userId);
|
||||
userCourse.setCourseStartTime(v.getCourseStartTime());
|
||||
userCourse.setCourseEndTime(v.getCourseEndTime());
|
||||
userCourse.setAttend(false);
|
||||
userCourse.setAttendTime(null);
|
||||
userCourse.setActivityCourseId(v.getId());
|
||||
list.add(userCourse);
|
||||
});
|
||||
dao().insert(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 该培训班每个分工会名额是否报满
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean isSignFullByUnionId(FamilyCourse course, Integer currentFamilyNumber) {
|
||||
List<NutMap> unionLimit = course.getUnionLimit();
|
||||
if (Lang.isEmpty(unionLimit)) {
|
||||
return false;
|
||||
}
|
||||
String unionId = SecurityUtil.getUnionId();
|
||||
NutMap unionLimitMap = unionLimit.stream().filter(v -> v.getString("id").equals(unionId)).findAny().orElse(null);
|
||||
if (Lang.isEmpty(unionLimitMap)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
FamilyType type = dao().fetch(FamilyType.class, course.getCourseType());
|
||||
//分工会限制人数
|
||||
int limitCount = unionLimitMap.getInt("limitCount");
|
||||
|
||||
//该课程已经报名的总人数
|
||||
int hasSignCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType(), unionId);
|
||||
int hasWaitCount = statisticsService.queryCourseWaitCount(course.getId(), course.getCourseType());
|
||||
|
||||
//+1是算自己
|
||||
int current = type.getSelfAddFamily() ? 1 : 0;
|
||||
currentFamilyNumber = type.getIsBringFamily() && type.getIsAddFamily() ? currentFamilyNumber : 0;
|
||||
//如果还有正常名额
|
||||
if(limitCount - hasSignCount > 0) {
|
||||
return (hasSignCount + current + currentFamilyNumber) > limitCount;
|
||||
} else {
|
||||
return (hasWaitCount + current + currentFamilyNumber) > course.getWaitingNum();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSignFull(FamilyCourse course, Integer currentFamilyNumber) {
|
||||
//课程限制人数
|
||||
int coursePeopleNumber = course.getCoursePeopleNumber();
|
||||
if (coursePeopleNumber == 0) {
|
||||
return true;
|
||||
}
|
||||
//查询课程对应的类型
|
||||
FamilyType type = dao().fetch(FamilyType.class, course.getCourseType());
|
||||
//课程已报人数
|
||||
int hasSignCount = statisticsService.queryCourseCount(course.getId(), course.getCourseType());
|
||||
int hasWaitCount = statisticsService.queryCourseWaitCount(course.getId(), course.getCourseType());
|
||||
|
||||
//+1是算自己
|
||||
int current = type.getSelfAddFamily() ? 1 : 0;
|
||||
currentFamilyNumber = type.getIsBringFamily() && type.getIsAddFamily() ? currentFamilyNumber : 0;
|
||||
//如果还有正常名额
|
||||
if(coursePeopleNumber - hasSignCount > 0) {
|
||||
return (hasSignCount + current + currentFamilyNumber + course.getCourseReservedNumber()) > coursePeopleNumber;
|
||||
} else {
|
||||
return (hasWaitCount + current + currentFamilyNumber) > course.getWaitingNum();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validFamilyCount(FamilyUser user) {
|
||||
String activityId = user.getActivityId();
|
||||
// 查询报名记录
|
||||
List<FamilyUser> list = dao().query(FamilyUser.class, Cnd.where(FamilyUser::getActivityId, "=", activityId).and(FamilyUser::getUserId, "=", SecurityUtil.getUserId()));
|
||||
if(Lang.isEmpty(list)) {
|
||||
return false;
|
||||
}
|
||||
FamilyActivity activity = dao().fetch(FamilyActivity.class, activityId);
|
||||
|
||||
List<List<NutMap>> allMobileColumnsValue = new ArrayList<>(list.stream()
|
||||
.map(FamilyUser::getMobileColumnsValue)
|
||||
.filter(Objects::nonNull)
|
||||
.flatMap(List::stream)
|
||||
.toList());
|
||||
|
||||
allMobileColumnsValue.addAll(user.getMobileColumnsValue());
|
||||
|
||||
long count = allMobileColumnsValue.stream()
|
||||
.flatMap(List::stream)
|
||||
.filter(nutMap -> activity.getOnlyKey().equals(nutMap.getString("columnCode")))
|
||||
.map(nutMap -> nutMap.getString("columnValue"))
|
||||
.filter(Objects::nonNull)
|
||||
.distinct()
|
||||
.count();
|
||||
|
||||
return count > activity.getFamilyMaxCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSignCourse(FamilyCourse course, FamilyActivity activity) {
|
||||
//培训班类型
|
||||
String courseType = course.getCourseType();
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
count( tsus.id )
|
||||
FROM
|
||||
`family_user` tsus
|
||||
LEFT JOIN family_course tsuc ON tsuc.id = tsus.courseId
|
||||
WHERE
|
||||
tsuc.courseType = @courseType
|
||||
AND tsus.userId = @userId
|
||||
AND tsus.activityId = @activityId
|
||||
""");
|
||||
sql.setParam("courseType", courseType);
|
||||
sql.setParam("activityId", activity.getId());
|
||||
sql.setParam("userId", SecurityUtil.getUserId());
|
||||
int hasRegisterNum = count(sql);
|
||||
|
||||
//第一种无限制报名
|
||||
if (activity.getRestrictLimit() == null || activity.getRestrictLimit() == 1) {
|
||||
return true;
|
||||
} else if (activity.getRestrictLimit() == 2) {
|
||||
FamilyTypeLimit familyTypeLimit = dao().fetch(FamilyTypeLimit.class, Cnd.where("typeId", "=", courseType).and("activityId", "=", activity.getId()));
|
||||
if (familyTypeLimit == null) {
|
||||
return true;
|
||||
}
|
||||
//此类型的班最多可报几项
|
||||
int personMaxRegisterNum = familyTypeLimit.getLimitNum();
|
||||
if (personMaxRegisterNum == 0) {
|
||||
return true;
|
||||
}
|
||||
return hasRegisterNum < personMaxRegisterNum;
|
||||
} else if (activity.getRestrictLimit() == 3) {
|
||||
//第三种,限制报几个,不跟类型挂钩
|
||||
int aCount = dao().count(FamilyUser.class, Cnd.where("activityId", "=", activity.getId()).and("userId", "=", SecurityUtil.getUserId()));
|
||||
return aCount < activity.getLimitNum();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSignCourseByUser(String courseId, String userId) {
|
||||
return dao().count(FamilyUser.class, Cnd.where("courseId", "=", courseId).and("userId", "=", userId)) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doQd(String id) {
|
||||
NutMap updateMap = NutMap.NEW();
|
||||
updateMap.put("isAttend", true);
|
||||
updateMap.put("attendTime", new Date());
|
||||
dao().update(FamilyUserCourse.class, Chain.from(updateMap), Cnd.where("id", "=", id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> qdInfoByUserId(String userId, String activityId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
c.*,
|
||||
t.courseLocationCoordinates,
|
||||
t.isMobileSign,
|
||||
t.signType,
|
||||
t.isReceiveGift,
|
||||
t.giftType,
|
||||
(select state from family_user su where su.activityId = c.activityId and su.courseId = c.courseId and su.userId = c.userId) as state
|
||||
FROM
|
||||
`family_user_course` c
|
||||
LEFT JOIN family_course t ON t.id = c.courseId
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.and("c.activityId", "=", activityId);
|
||||
cnd.and("c.userId", "=", userId);
|
||||
cnd.asc("c.courseStartTime");
|
||||
|
||||
sql.setCondition(cnd);
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FamilyCourse> filterCourseByHostUnion(List<FamilyCourse> courseList) {
|
||||
if (Lang.isEmpty(courseList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return courseList.stream().filter(o -> {
|
||||
if (StrUtil.isBlank(o.getInterTime()) || o.getOpenOtherUnion() == null || o.getOpenOtherUnion()) {
|
||||
return true;
|
||||
} else {
|
||||
if (SecurityUtil.getUnionId().equals(o.getHostUnionId())) {
|
||||
return true;
|
||||
} else {
|
||||
int compare = cn.hutool.core.date.DateUtil.compare(cn.hutool.core.date.DateUtil.date(), cn.hutool.core.date.DateUtil.parse(o.getInterTime()), "yyyy-MM-dd HH:mm");
|
||||
return compare >= 0;
|
||||
}
|
||||
}
|
||||
}).toList();
|
||||
}
|
||||
}
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
package com.budwk.app.zhgh.activity.family.service.impl;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyMobileSignColumn;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyCourse;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyType;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyUser;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyActivityStatisticsService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @author zxy
|
||||
* @Description TODO
|
||||
* @createTime 2022年03月03日 10:02:00
|
||||
*/
|
||||
@IocBean(args = {"refer:dao"})
|
||||
@Slf4j
|
||||
public class FamilyActivityStatisticsServiceImpl extends BaseServiceImpl<FamilyUser> implements FamilyActivityStatisticsService {
|
||||
|
||||
public FamilyActivityStatisticsServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination pageData(PageForm pageForm, String activityId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
tsuc.id,
|
||||
tsuc.courseName,
|
||||
tsuc.coursePeopleNumber,
|
||||
tsuc.courseReservedNumber,
|
||||
type.typeName as courseType,
|
||||
tsuc.courseLocation,
|
||||
tsuc.courseInstructor,
|
||||
tsuc.reserveMode,
|
||||
tsuc.isMobileSign,
|
||||
tsuc.hostUnionId,
|
||||
tsuc.interTime,
|
||||
tsuc.waitingNum,
|
||||
tsuc.openOtherUnion,
|
||||
tsuc.courseType as cType
|
||||
FROM
|
||||
`family_course` tsuc
|
||||
LEFT JOIN
|
||||
family_type type on tsuc.courseType = type.id
|
||||
WHERE
|
||||
tsuc.activityId = @activityId
|
||||
ORDER BY tsuc.orderNum
|
||||
""");
|
||||
sql.setParam("activityId", activityId);
|
||||
Pagination pagination = listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
List<NutMap> courseList = pagination.getList();
|
||||
courseList.forEach(c -> {
|
||||
c.put("registerNum", queryCourseCount(c.getString("id"), c.getString("cType")));
|
||||
c.put("hasWaitingNum", queryCourseWaitCount(c.getString("id"), c.getString("cType")));
|
||||
});
|
||||
return pagination;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> registerUserList(String courseId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
u.loginname,
|
||||
u.username,
|
||||
u.sex,
|
||||
tsuu.unionId,
|
||||
tsuu.unionName,
|
||||
tsuu.unitId,
|
||||
tsuu.unitName,
|
||||
ifnull(tsuu.mobile, u.mobile) as mobile,
|
||||
tsuu.signUpTime,
|
||||
tsuu.state,
|
||||
tsuu.mobileColumnsValue
|
||||
FROM
|
||||
family_user tsuu
|
||||
LEFT JOIN `vw_user` u ON u.id = tsuu.userId
|
||||
$condition
|
||||
ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 ),u.unionid desc, u.unitid desc
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("tsuu.courseId", "=", courseId);
|
||||
sql.setCondition(cnd);
|
||||
List<NutMap> listMap = listMap(sql);
|
||||
for (NutMap nutMap : listMap) {
|
||||
// 第一步:解析为 JSONArray(外层数组)
|
||||
JSONArray outerArray = JSONUtil.parseArray(nutMap.getString("mobileColumnsValue"));
|
||||
// 第二步:转换为 List<List<JSONObject>>
|
||||
List<List<JSONObject>> result = outerArray.stream()
|
||||
.map(item -> {
|
||||
// 每个 item 又是一个数组
|
||||
JSONArray innerArray = (JSONArray) item;
|
||||
return innerArray.toList(JSONObject.class);
|
||||
})
|
||||
.toList();
|
||||
nutMap.put("mobileColumnsValue", result);
|
||||
nutMap.put("familyCount", result.size());
|
||||
}
|
||||
return listMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> getTaleColumnInfo(String courseId) {
|
||||
FamilyCourse course = dao().fetch(FamilyCourse.class, courseId);
|
||||
FamilyType upType = dao().fetch(FamilyType.class, course.getCourseType());
|
||||
dao().fetchLinks(upType, "familyMobileSignColumnList", Cnd.NEW().asc("columnIndex"));
|
||||
|
||||
List<FamilyMobileSignColumn> columnList = upType.getFamilyMobileSignColumnList();
|
||||
List<NutMap> columnTableList = columnList.stream().map(o -> NutMap.NEW().setv("label", o.getColumnName()).setv("prop", o.getColumnCode())).collect(Collectors.toList());
|
||||
return columnTableList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> registerUserList(String courseId, String unionId, String unitId, String searchName, String searchKeyword) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
tsuu.id,
|
||||
u.id as userId,
|
||||
u.loginname,
|
||||
u.username,
|
||||
u.unitname,
|
||||
u.unionname,
|
||||
u.sex,
|
||||
ifnull(tsuu.mobile, u.mobile) as mobile,
|
||||
tsuu.signUpTime,
|
||||
tsuu.state
|
||||
FROM
|
||||
family_user tsuu
|
||||
LEFT JOIN `vw_user` u ON u.id = tsuu.userId
|
||||
$condition
|
||||
ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 ),u.unionid desc, u.unitid desc
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("tsuu.courseId", "=", courseId);
|
||||
cnd.andEX("u.unionid", "=", unionId);
|
||||
cnd.andEX("u.unitid", "=", unitId);
|
||||
if (StrUtil.isNotBlank(searchKeyword)) {
|
||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||
group.andLike("username", searchKeyword).orLike("loginname", searchKeyword);
|
||||
cnd.and(group);
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, List<NutMap>> getSignInfo(String courseId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
tsuuc.courseStartTime,
|
||||
tsuuc.courseEndTime,
|
||||
tsuuc.isAttend,
|
||||
tsuuc.attendTime,
|
||||
u.username,
|
||||
u.loginname,
|
||||
u.unitname,
|
||||
u.unionname
|
||||
FROM
|
||||
`family_user_course` tsuuc
|
||||
LEFT JOIN `vw_user` u ON u.id = tsuuc.userId
|
||||
WHERE
|
||||
tsuuc.courseId = @courseId
|
||||
""");
|
||||
sql.setParam("courseId", courseId);
|
||||
List<NutMap> list = listMap(sql);
|
||||
|
||||
Map<String, List<NutMap>> courseTimeMap = list.stream().map(v -> {
|
||||
String courseTime = v.getString("courseStartTime") + " 至 " + v.getString("courseEndTime");
|
||||
v.put("courseTime", courseTime);
|
||||
return v;
|
||||
}).collect(Collectors.groupingBy(v -> v.getString("courseTime")));
|
||||
|
||||
// 使用Stream API进行降序排序
|
||||
Map<String, List<NutMap>> sortedDataMap = courseTimeMap.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
|
||||
return sortedDataMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> baoMingUserList(String activityId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
u.loginname,
|
||||
u.username,
|
||||
u.unitname,
|
||||
u.unionname,
|
||||
u.sex,
|
||||
u.mobile,
|
||||
uc.courseName,
|
||||
uc.campus
|
||||
FROM
|
||||
`family_user` uu
|
||||
RIGHT JOIN family_course uc ON uc.id = uu.courseId
|
||||
LEFT JOIN `vw_user` u ON u.id = uu.userId
|
||||
WHERE
|
||||
uc.activityId = @activityId
|
||||
ORDER BY u.unitCode,u.unioncode,u.sex
|
||||
""");
|
||||
sql.setParam("activityId", activityId);
|
||||
return listMap(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryCourseCount(String courseId, String courseType) {
|
||||
return this.queryCourseCount(courseId, courseType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryCourseWaitCount(String courseId, String courseType) {
|
||||
return this.queryCourseWaitCount(courseId, courseType, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryCourseCount(String courseId, String courseType, String unionId) {
|
||||
return this.calcSignCount(courseId, courseType, unionId, List.of(1, 3));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int queryCourseWaitCount(String courseId, String courseType, String unionId) {
|
||||
return this.calcSignCount(courseId, courseType, unionId, List.of(2));
|
||||
}
|
||||
|
||||
private int calcSignCount(String courseId, String courseType, String unionId, List<Integer> stateList) {
|
||||
if(StrUtil.isBlank(courseId) || StrUtil.isBlank(courseType)) {
|
||||
return 0;
|
||||
}
|
||||
FamilyType type = dao().fetch(FamilyType.class, courseType);
|
||||
AtomicInteger hasRegisterNum = new AtomicInteger();
|
||||
List<FamilyUser> signUpUsers = dao().query(FamilyUser.class, Cnd.where("courseId", "=", courseId)
|
||||
.and("state", "in", stateList)
|
||||
.andEX("unionId", "=", unionId));
|
||||
signUpUsers.forEach(item -> {
|
||||
if (type.getSelfAddFamily()) {
|
||||
hasRegisterNum.getAndIncrement();
|
||||
}
|
||||
if (type.getIsBringFamily() && type.getIsAddFamily()) {
|
||||
List<List<NutMap>> mapList = item.getMobileColumnsValue();
|
||||
if (Lang.isNotEmpty(mapList)) {
|
||||
hasRegisterNum.addAndGet(mapList.size());
|
||||
}
|
||||
}
|
||||
});
|
||||
return hasRegisterNum.get();
|
||||
}
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package com.budwk.app.zhgh.activity.family.service.impl;
|
||||
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.service.impl.BaseServiceImpl;
|
||||
import com.budwk.app.zhgh.activity.family.models.FamilyBlackList;
|
||||
import com.budwk.app.zhgh.activity.family.service.FamilyBlackListService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Criteria;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author zxy
|
||||
* @Description TODO
|
||||
* @createTime 2022年03月07日 14:29:00
|
||||
*/
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class FamilyUserServiceImpl extends BaseServiceImpl<FamilyBlackList> implements FamilyBlackListService {
|
||||
|
||||
public FamilyUserServiceImpl(Dao dao) {
|
||||
super(dao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pagination pageData(PageForm pageForm, Cnd cnd, String activityId, String courseId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
u.id AS userId,
|
||||
u.username,
|
||||
u.loginname,
|
||||
ifnull(tsuu.mobile, u.mobile) as mobile,
|
||||
u.unitname,
|
||||
u.unionname,
|
||||
tsuc.courseName,
|
||||
tsuu.state,
|
||||
( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId $var) courseTotal,
|
||||
( SELECT count( 1 ) FROM family_user_course WHERE userId = tsuu.userId AND isAttend = 0 and tsuu.state!=2 AND now()> courseEndTime $var) AS absentCount,
|
||||
if(tsubl.isDisabled=1,true,false) isDisabled,
|
||||
group_CONCAT( tsuc.courseName ) AS courseNames
|
||||
FROM
|
||||
`family_user` tsuu
|
||||
LEFT JOIN `vw_user` u ON u.id = tsuu.userId
|
||||
LEFT JOIN family_activity act on act.id = tsuu.activityId
|
||||
LEFT JOIN family_course tsuc ON tsuc.id = tsuu.courseId
|
||||
LEFT JOIN family_black_list tsubl on tsubl.userId = tsuu.userId
|
||||
$condition
|
||||
ORDER BY FIELD( tsuu.state, 1, 3, 2, 4 )
|
||||
""");
|
||||
cnd.groupBy("tsuu.userId");
|
||||
Criteria varCnd = Cnd.cri();
|
||||
varCnd.where().setTop(false);
|
||||
varCnd.where().andEX("activityId", "=", activityId);
|
||||
varCnd.where().andEX("courseId", "=", courseId);
|
||||
if (!varCnd.where().isEmpty()) {
|
||||
sql.vars().set("var", "and " + varCnd.toSql(null));
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void doHandleUser(String userId) {
|
||||
FamilyBlackList blackRecord = dao().fetch(FamilyBlackList.class, Cnd.where("userId", "=", userId));
|
||||
if (Lang.isEmpty(blackRecord)) {
|
||||
FamilyBlackList blackList = new FamilyBlackList();
|
||||
blackList.setUserId(userId);
|
||||
blackList.setIsDisabled(true);
|
||||
dao().insert(blackList);
|
||||
} else {
|
||||
// blackRecord.setIsDisabled(!blackRecord.getIsDisabled());
|
||||
// dao().update(blackRecord);
|
||||
dao().delete(blackRecord);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NutMap> attendClassRecord(String userId) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
c.courseName,
|
||||
uc.courseStartTime,
|
||||
courseEndTime,
|
||||
uc.isAttend,
|
||||
uc.attendTime
|
||||
FROM
|
||||
`family_user_course` uc
|
||||
LEFT JOIN family_course c ON c.id = uc.courseId
|
||||
WHERE
|
||||
uc.userId = @userId
|
||||
""");
|
||||
sql.setParam("userId", userId);
|
||||
return listMap(sql);
|
||||
}
|
||||
}
|
||||
+22
@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.zhgh.activity.sports.models.ActivitySchoolApply;
|
||||
import com.budwk.app.zhgh.activity.sports.param.ActivitySportsApplyUserPageParam;
|
||||
import com.budwk.app.zhgh.activity.sports.service.ActivitySportsApplyUserService;
|
||||
@@ -13,6 +14,7 @@ import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.dao.Sqls;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
@@ -222,4 +224,24 @@ public class ActivitySportsApplyUserController {
|
||||
return Result.success(applyList);
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("activity.apply")
|
||||
public Result getSysUser(String queryString,String[] loginnames){
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("loginname", "not in", loginnames);
|
||||
if (StrUtil.isNotBlank(queryString)) {
|
||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||
group.andLike("username", queryString).orLike("loginname", queryString);
|
||||
cnd.and(group);
|
||||
}
|
||||
|
||||
Sql sql = Sqls.create("select id,loginname,username,sex,mobile,unitId,birthday,idcard from `vw_user` $condition LIMIT 30");
|
||||
sql.setCondition(cnd);
|
||||
sql.setCallback(Sqls.callback.entities());
|
||||
sql.setEntity(activitySportsApplyUserService.getEntity());
|
||||
List<Sys_user> list = dao.execute(sql).getList(Sys_user.class);
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+158
@@ -1,17 +1,35 @@
|
||||
package com.budwk.app.zhgh.activity.sports.h5Controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnion;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityEvent;
|
||||
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
|
||||
import com.budwk.app.zhgh.activity.sports.models.ActivitySchool;
|
||||
import com.budwk.app.zhgh.activity.sports.models.ActivitySchoolApply;
|
||||
import com.budwk.app.zhgh.activity.sports.models.ActivitySchoolEvent;
|
||||
import com.budwk.app.zhgh.activity.sports.models.ActivitySchoolTeam;
|
||||
import com.budwk.app.zhgh.activity.sports.param.ActivitySportsApplyUserPageParam;
|
||||
import com.budwk.app.zhgh.activity.sports.service.ActivitySportsApplyUserService;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName H5ActivitySportsApplyUserController
|
||||
@@ -26,6 +44,9 @@ public class H5ActivitySportsApplyUserController {
|
||||
@Inject
|
||||
private ActivitySportsApplyUserService activitySportsApplyUserService;
|
||||
|
||||
@Inject
|
||||
private Dao dao;
|
||||
|
||||
@At("/applyUser")
|
||||
@Ok("beetl:platform/zhghh5/activity/sports/applyUser.html")
|
||||
@SaCheckPermission("h5.activity.sports.applyUser")
|
||||
@@ -60,5 +81,142 @@ public class H5ActivitySportsApplyUserController {
|
||||
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("h5.activity.sports.applyUser")
|
||||
public Result signUpUser(@Valid String activityId, @Valid String eventId, @Valid String schoolEventId, @Valid String teamId) {
|
||||
View_user user = dao.fetch(View_user.class, Cnd.where(View_user::getId, "=", SecurityUtil.getUserId()));
|
||||
ActivitySchoolEvent schoolEvent = dao.fetch(ActivitySchoolEvent.class, schoolEventId);
|
||||
ActivityEvent activityEvent = dao.fetch(ActivityEvent.class, eventId);
|
||||
ActivitySchool activitySchool = dao.fetch(ActivitySchool.class, activityId);
|
||||
ActivitySchoolTeam schoolTeam = dao.fetch(ActivitySchoolTeam.class, teamId);
|
||||
|
||||
ActivityBasicUnit basicUnit = dao.fetch(ActivityBasicUnit.class, Cnd.where("id", "=", SecurityUtil.getUnitId()));
|
||||
ActivityBasicUnion basicUnion = dao.fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionId()));
|
||||
if (Lang.isEmpty(basicUnion)) {
|
||||
return Result.error("请先设置活动工会");
|
||||
}
|
||||
|
||||
|
||||
//判断是否在活动组别内
|
||||
int count = dao.count(ActivityUserScope.class,
|
||||
Cnd.where(ActivityUserScope::getGroupId, "=", activitySchool.getActivityGroupId())
|
||||
.and(ActivityUserScope::getUserId, "=", SecurityUtil.getUserId()));
|
||||
if (count == 0) {
|
||||
return Result.error("您没有权限参与该活动");
|
||||
}
|
||||
//如果不等于空代表是个人项目
|
||||
if (ObjectUtil.isNotEmpty(activityEvent.getIsMenWomen())) {
|
||||
if (activityEvent.getIsMenWomen() == 1 && !user.getSex().equals("男")) {
|
||||
return Result.error("当前项目只能男性能报名!");
|
||||
}
|
||||
if (activityEvent.getIsMenWomen() == 2 && !user.getSex().equals("女")) {
|
||||
return Result.error("当前项目只能女性能报名!");
|
||||
}
|
||||
}
|
||||
List<ActivitySchoolApply> schoolApplyList = dao.query(ActivitySchoolApply.class,
|
||||
Cnd.where(ActivitySchoolApply::getActivityId, "=", activityId)
|
||||
.and(ActivitySchoolApply::getEventId, "=", eventId)
|
||||
.and(ActivitySchoolApply::getActivityUnionId, "=", basicUnit.getId())
|
||||
.and(ActivitySchoolApply::getApplyUser, "!=", SecurityUtil.getUserId()));
|
||||
|
||||
|
||||
if (ObjectUtil.isNotEmpty(schoolEvent.getRestrictGirlNum()) && user.getSex().equals("女")) {
|
||||
if (schoolEvent.getRestrictGirlNum() == 0) {
|
||||
return Result.error("当前项目女性没有报名名额!");
|
||||
}
|
||||
//找出当前工会女性报名的数量
|
||||
int size = schoolApplyList.stream().filter(girl -> girl.getSex().equals("女")).toList().size();
|
||||
//数量加上自己如果大于配置的
|
||||
if (size + 1 > schoolEvent.getRestrictGirlNum()) {
|
||||
return Result.error("当前项目女性只能报名" + schoolEvent.getRestrictGirlNum() + "人!");
|
||||
}
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotEmpty(schoolEvent.getRestrictBoyNum()) && user.getSex().equals("男")) {
|
||||
if (schoolEvent.getRestrictBoyNum() == 0) {
|
||||
return Result.error("当前项目男性没有报名名额!");
|
||||
}
|
||||
//找出当前工会男性报名的数量
|
||||
int size = schoolApplyList.stream().filter(girl -> girl.getSex().equals("男")).toList().size();
|
||||
//数量加上自己如果大于配置的
|
||||
if (size + 1 > schoolEvent.getRestrictBoyNum()) {
|
||||
return Result.error("当前项目男性只能报名" + schoolEvent.getRestrictGirlNum() + "人!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (ObjectUtil.isNotEmpty(schoolEvent.getStartAgeDate()) && ObjectUtil.isNotEmpty(schoolEvent.getEndAgeDate())) {
|
||||
//如果年龄做了判断
|
||||
try {
|
||||
if (ObjectUtil.isEmpty(user.getBirthday())) {
|
||||
return Result.error("请先完善您的出生日期");
|
||||
}
|
||||
// 需要先将字符串转换为日期进行比较
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
Date startAgeDate = sdf.parse(schoolEvent.getStartAgeDate());
|
||||
Date endAgeDate = sdf.parse(schoolEvent.getEndAgeDate());
|
||||
if (user.getBirthday().getTime() < startAgeDate.getTime() || user.getBirthday().getTime() > endAgeDate.getTime()) {
|
||||
return Result.error("您年龄不在报名时间段内");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return Result.error("年龄格式解析错误");
|
||||
}
|
||||
}
|
||||
|
||||
ActivitySchoolApply schoolApply = new ActivitySchoolApply();
|
||||
schoolApply.setActivityId(activityId);
|
||||
schoolApply.setEventId(eventId);
|
||||
schoolApply.setUnionname(user.getUnionName());
|
||||
schoolApply.setAwardsMode(activityEvent.getProjectType());
|
||||
schoolApply.setUnitId(user.getUnitId());
|
||||
schoolApply.setUnionId(user.getUnionId());
|
||||
schoolApply.setActivityUnionId(basicUnion.getId());
|
||||
schoolApply.setActivityUnionName(basicUnion.getName());
|
||||
schoolApply.setUserId(SecurityUtil.getUserId());
|
||||
schoolApply.setApplyUser(SecurityUtil.getUserId());
|
||||
schoolApply.setBirthday(ObjectUtil.isNotEmpty(user.getBirthday()) ? String.valueOf(user.getBirthday()) : null);
|
||||
schoolApply.setApplyDate(DateUtil.now());
|
||||
schoolApply.setIdentity(List.of("1"));
|
||||
if (activitySchool.getApplyWay().size() == 2 && activitySchool.getApplyWay().contains(1)) {
|
||||
schoolApply.setStatus(0);
|
||||
} else if (activitySchool.getApplyWay().size() == 1 && activitySchool.getApplyWay().contains(1)) {
|
||||
schoolApply.setStatus(2);
|
||||
}
|
||||
schoolApply.setUnitname(user.getUnitName());
|
||||
schoolApply.setTeamId(schoolTeam.getId());
|
||||
schoolApply.setTeam(schoolTeam.getName());
|
||||
schoolApply.setLoginname(user.getLoginname());
|
||||
schoolApply.setUsername(user.getUsername());
|
||||
schoolApply.setMobile(user.getMobile());
|
||||
schoolApply.setSex(user.getSex());
|
||||
dao.insert(schoolApply);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("h5.activity.sports.applyUser")
|
||||
public Result cancelApply(@Valid String activityId, @Valid String eventId, @Valid String schoolEventId) {
|
||||
int count = dao.count(ActivitySchoolApply.class,
|
||||
Cnd.where(ActivitySchoolApply::getUserId, "=", SecurityUtil.getUserId())
|
||||
.and(ActivitySchoolApply::getActivityId, "=", activityId)
|
||||
.and(ActivitySchoolApply::getEventId, "=", eventId).and(ActivitySchoolApply::getStatus, "=", 2));
|
||||
if (count > 0) {
|
||||
return Result.error("您已报名成功无法取消,请联系管理员取消!");
|
||||
}
|
||||
|
||||
dao.clear(ActivitySchoolApply.class, Cnd.where(ActivitySchoolApply::getUserId, "=", SecurityUtil.getUserId())
|
||||
.and(ActivitySchoolApply::getActivityId, "=", activityId).and(ActivitySchoolApply::getEventId, "=", eventId));
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
|
||||
@At
|
||||
@SaCheckPermission("h5.activity.sports.applyUser")
|
||||
public Result listTeamList(@Valid String activityId, @Valid String eventId) {
|
||||
return Result.success(dao.query(ActivitySchoolTeam.class, Cnd.where(ActivitySchoolTeam::getActivityId, "=", activityId)
|
||||
.and(ActivitySchoolTeam::getEventId, "=", eventId).asc(ActivitySchoolTeam::getLocation)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.util.List;
|
||||
@Data
|
||||
@Comment("体育活动")
|
||||
@Table("activity_school")
|
||||
public class ActivitySchool extends BaseModel implements Serializable , SysHomeConvert {
|
||||
public class ActivitySchool extends BaseModel implements Serializable, SysHomeConvert {
|
||||
|
||||
@Column
|
||||
@Name
|
||||
@@ -171,7 +171,7 @@ public class ActivitySchool extends BaseModel implements Serializable , SysHomeC
|
||||
|
||||
@Column
|
||||
@Comment("小程序活动封面")
|
||||
@ColDefine(type = ColType.VARCHAR,width = 100)
|
||||
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||
private String image;
|
||||
|
||||
@Many(field = "activityId")
|
||||
@@ -205,7 +205,11 @@ public class ActivitySchool extends BaseModel implements Serializable , SysHomeC
|
||||
sysHomeActivity.setName(this.getName());
|
||||
sysHomeActivity.setCover(this.getImage());
|
||||
sysHomeActivity.setUrl("/platform/activity/apply");
|
||||
sysHomeActivity.setH5Url(null);
|
||||
if (this.applyWay.contains(2)) {
|
||||
sysHomeActivity.setH5Url("/platform/h5/activity/apply/applyUser?activityId=" + this.getId());
|
||||
} else {
|
||||
sysHomeActivity.setH5Url(null);
|
||||
}
|
||||
sysHomeActivity.setStartDate(DateUtil.parseDate(this.getApplyStartTime()));
|
||||
sysHomeActivity.setEndDate(DateUtil.parseDate(this.getApplyEndTime()));
|
||||
sysHomeActivity.setAllowUserGroupId(this.getActivityGroupId());
|
||||
|
||||
+11
-2
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.activity.sports.service.impl;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
@@ -53,6 +54,9 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
public String getUnionId() {
|
||||
ActivityBasicUnit basicUnit = dao().fetch(ActivityBasicUnit.class, Cnd.where("id", "=", SecurityUtil.getUnitId()));
|
||||
ActivityBasicUnion basicUnion = dao().fetch(ActivityBasicUnion.class, Cnd.where("id", "=", basicUnit.getUnionId()));
|
||||
if (Lang.isEmpty(basicUnion)) {
|
||||
throw new RuntimeException("请先设置活动工会");
|
||||
}
|
||||
|
||||
return StrUtil.isBlank(SecurityUtil.getUnitId()) ? "" : basicUnion.getId();
|
||||
}
|
||||
@@ -77,8 +81,10 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
eve.projectType eveProjectType,
|
||||
eve.isMenWomen,
|
||||
apply.`status`,
|
||||
apply2.`status` status2,
|
||||
IF (sum(apply.`status`=2) IS NULL, 0, sum(apply.`status`=2)) AS successUserApply,
|
||||
count(apply.id) userApply,
|
||||
count(apply2.id) userApply2,
|
||||
apply.applyUser,
|
||||
(SELECT ast.`name` FROM activity_school_apply app LEFT JOIN activity_school_team ast ON ast.id = app.teamId WHERE app.eventId = ase.eventId AND app.activityId = ase.activityId AND app.userId = @userId) activityTeamName,
|
||||
(select GROUP_CONCAT(username) FROM activity_school_apply WHERE status=2 and eventId = ase.eventId
|
||||
@@ -92,6 +98,7 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
LEFT JOIN activity_event eve ON ase.eventId=eve.id
|
||||
LEFT JOIN activity_basic_settings abs ON abs.id=eve.competitionCategory
|
||||
LEFT JOIN activity_school_apply apply ON apply.activityId=ase.activityId AND apply.eventId=ase.eventId AND (applyUser=@userId or userId=@userId)
|
||||
LEFT JOIN activity_school_apply apply2 ON apply2.activityId=ase.activityId AND apply2.eventId=ase.eventId AND apply2.userId=@userId
|
||||
$condition
|
||||
""").setParam("unionId", pageParam.getUnionId()).setParam("userId", SecurityUtil.getUserId());
|
||||
|
||||
@@ -179,7 +186,7 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
// cnd.and(new Static("JSON_CONTAINS(school.applyWay,JSON_ARRAY( 1))>0"));
|
||||
cnd.and(new Static("(SELECT COUNT(1) FROM activity_user_scope WHERE groupId=school.activityGroupId AND userId='%s') >0".formatted(SecurityUtil.getUserId())));
|
||||
}
|
||||
cnd.and("YEAR(school.applyStartTime)", "=", year);
|
||||
cnd.andEX("YEAR(school.applyStartTime)", "=", year);
|
||||
cnd.desc("school.applyStartTime");
|
||||
|
||||
sql.setCondition(cnd);
|
||||
@@ -339,7 +346,8 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
List<ActivitySchoolApply> awardsModeG = list.stream().filter(v -> v.getAwardsMode().equals("1")).collect(Collectors.toList());
|
||||
|
||||
list.forEach(v -> {
|
||||
if (Strings.isNotBlank(v.getBirthday())) {
|
||||
if (ObjectUtil.isNotEmpty(v.getBirthday())) {
|
||||
String birthday = v.getBirthday();
|
||||
v.setAge(cn.hutool.core.date.DateUtil.ageOfNow(v.getBirthday()));
|
||||
}
|
||||
});
|
||||
@@ -372,6 +380,7 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
|
||||
apply.setApplyUser(SecurityUtil.getUserId());
|
||||
apply.setStatus(pass ? 2 : 0);
|
||||
apply.setApplyDate(DateUtil.now());
|
||||
apply.setUnitId(basicUnit.getId());
|
||||
apply.setActivityUnionId(basicUnion.getId());
|
||||
apply.setActivityUnionName(basicUnion.getName());
|
||||
}
|
||||
|
||||
+13
-12
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.dayofficework.honor.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.zhgh.dayofficework.honor.constant.HonorTypeOrigin;
|
||||
import com.budwk.app.zhgh.dayofficework.honor.models.HonorBasicSettings;
|
||||
@@ -13,13 +14,12 @@ import org.nutz.dao.sql.Sql;
|
||||
import org.nutz.dao.util.Daos;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.lang.util.NutMap;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@IocBean
|
||||
@@ -43,7 +43,7 @@ public class HonorBoardController {
|
||||
@SaCheckPermission("honor.board")
|
||||
public Result getHonorTypeByYear() {
|
||||
Sql sqlYear = Sqls.create("""
|
||||
select YEAR(grantDate) AS `year` from honor where grantDate is not null GROUP BY grantDate
|
||||
select grantDate AS `year` from honor where grantDate is not null GROUP BY grantDate
|
||||
""");
|
||||
int[] yearList = (int[]) Daos.query(dao, sqlYear.toString(), Sqls.callback.ints());
|
||||
|
||||
@@ -54,15 +54,16 @@ public class HonorBoardController {
|
||||
}
|
||||
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT YEAR
|
||||
( h.grantDate ) as year,
|
||||
SELECT
|
||||
h.grantDate AS year,
|
||||
hbs.`name`
|
||||
FROM
|
||||
honor h
|
||||
left join honor_basic_settings hbs on hbs.id = h.honorType
|
||||
WHERE YEAR (h.grantDate) <= @currentYear
|
||||
where h.grantDate is not null and h.grantDate != ''
|
||||
""");
|
||||
sql.setParam("currentYear", Calendar.getInstance().get(Calendar.YEAR));
|
||||
// WHERE YEAR (h.grantDate) <= @currentYear
|
||||
// sql.setParam("currentYear", Calendar.getInstance().get(Calendar.YEAR));
|
||||
List<NutMap> list = honorCommonService.listMap(sql);
|
||||
|
||||
for (NutMap map : resultList) {
|
||||
@@ -82,13 +83,13 @@ public class HonorBoardController {
|
||||
SELECT
|
||||
hbs.`name`,
|
||||
count( 1 ) AS num,
|
||||
YEAR ( h.grantDate ) as year
|
||||
h.grantDate as year
|
||||
FROM
|
||||
honor h
|
||||
LEFT JOIN honor_basic_settings hbs ON hbs.id = h.prize
|
||||
WHERE
|
||||
h.honorType = @honorType
|
||||
AND YEAR (h.grantDate) <= @currentYear
|
||||
AND h.grantDate <= @currentYear
|
||||
GROUP BY
|
||||
h.prize
|
||||
""");
|
||||
@@ -106,14 +107,14 @@ public class HonorBoardController {
|
||||
SELECT
|
||||
hbs.`name`,
|
||||
count( 1 ) AS num,
|
||||
YEAR ( h.grantDate ) AS YEAR
|
||||
h.grantDate AS YEAR
|
||||
FROM
|
||||
honor h
|
||||
LEFT JOIN honor_basic_settings hbs ON hbs.id = h.honorLevel
|
||||
WHERE
|
||||
h.honorLevel IS NOT NULL
|
||||
AND h.honorType = @honorType
|
||||
AND YEAR ( h.grantDate ) <= @currentYear
|
||||
AND h.grantDate <= @currentYear
|
||||
GROUP BY
|
||||
h.honorLevel
|
||||
""");
|
||||
|
||||
+2
-1
@@ -49,10 +49,11 @@ public class RestActController {
|
||||
@ApiOperation("活动列表")
|
||||
public Result pageData(@Valid PageForm pageForm, Integer year) {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("year", "=", year);
|
||||
cnd.andEX("YEAR(startTime)", "=", year);
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.where().andLike(RestAct::getName, pageForm.getSearchKeyword());
|
||||
}
|
||||
cnd.desc("signUpStartTime");
|
||||
Pagination pagination = restActService.listPage(pageForm.getPageNumber(), pageForm.getPageSize(), cnd);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
+10
-1
@@ -1,6 +1,7 @@
|
||||
package com.budwk.app.zhgh.dayofficework.rest.controller;
|
||||
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
@@ -50,13 +51,21 @@ public class RestBranchSignUpController {
|
||||
@At
|
||||
@SaCheckPermission("rest.branchUnionSignUp")
|
||||
@ApiOperation("分页查询")
|
||||
public Result pageData(@Valid PageForm pageForm) {
|
||||
public Result pageData(@Valid PageForm pageForm, Integer year) {
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
r.*
|
||||
FROM
|
||||
rest r
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
cnd.andEX("YEAR(r.startTime)", "=", year);
|
||||
cnd.desc("r.signUpStartTime");
|
||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
cnd.where().andLike("r.name", pageForm.getSearchKeyword());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
Pagination pagination = restActService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
return Result.success(pagination);
|
||||
}
|
||||
|
||||
+30
-7
@@ -10,6 +10,7 @@ import com.budwk.app.bpm.service.BpmService;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.web.controllers.open.commons.service.CommonService;
|
||||
import com.budwk.app.zhgh.dayofficework.warmthCondolence.models.WarmthCondolence;
|
||||
import com.budwk.app.zhgh.dayofficework.warmthCondolence.models.WarmthCondolenceNotice;
|
||||
import com.budwk.app.zhgh.dayofficework.warmthCondolence.service.WarmthCondolenceService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@@ -18,6 +19,7 @@ import org.nutz.dao.Cnd;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
@@ -41,17 +43,28 @@ public class WarmthCondolenceApplyController {
|
||||
@At("")
|
||||
@Ok("beetl:/platform/zhgh/dayofficework/warmthCondolence/apply/index.html")
|
||||
@SaCheckPermission("warmthCondolence.apply")
|
||||
public void index(){}
|
||||
public void index() {
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("warmthCondolence.apply")
|
||||
@ApiOperation("保存")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(type = "warmthCondolenceApply", tag = "保存慰问申请", msg = "保存慰问申请")
|
||||
public Result save(@Param("warmthCondolence")WarmthCondolence warmthCondolence){
|
||||
public Result save(@Param("warmthCondolence") WarmthCondolence warmthCondolence) {
|
||||
WarmthCondolenceNotice notice = warmthCondolenceService.dao().fetch(WarmthCondolenceNotice.class, warmthCondolence.getNoticeId());
|
||||
if (Lang.isEmpty(notice)) {
|
||||
return Result.error("未找到申请事项");
|
||||
}
|
||||
if(notice.getStartTime().getTime() > System.currentTimeMillis()){
|
||||
return Result.error("申请事项未开始");
|
||||
}
|
||||
if(notice.getEndTime().getTime() < System.currentTimeMillis()){
|
||||
return Result.error("申请事项已结束");
|
||||
}
|
||||
warmthCondolence.setNo(warmthCondolenceService.createNo(warmthCondolence));
|
||||
warmthCondolenceService.insertOrUpdate(warmthCondolence);
|
||||
bpmService.startSaveProcessInstance(BpmProcessConstant.WARMTH_CONDOLENCE.name(), warmthCondolence.getUserName()+"的申请", warmthCondolence.getId(), null);
|
||||
bpmService.startSaveProcessInstance(BpmProcessConstant.WARMTH_CONDOLENCE.name(), warmthCondolence.getUserName() + "的申请", warmthCondolence.getId(), null);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -60,22 +73,32 @@ public class WarmthCondolenceApplyController {
|
||||
@ApiOperation("提交")
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@SLog(tag = "送温暖慰问申请", msg = "送温暖慰问申请")
|
||||
public Result submit(@Param("warmthCondolence")@Valid WarmthCondolence warmthCondolence){
|
||||
public Result submit(@Param("warmthCondolence") @Valid WarmthCondolence warmthCondolence) {
|
||||
WarmthCondolenceNotice notice = warmthCondolenceService.dao().fetch(WarmthCondolenceNotice.class, warmthCondolence.getNoticeId());
|
||||
if (Lang.isEmpty(notice)) {
|
||||
return Result.error("未找到申请事项");
|
||||
}
|
||||
if(notice.getStartTime().getTime() > System.currentTimeMillis()){
|
||||
return Result.error("申请事项未开始");
|
||||
}
|
||||
if(notice.getEndTime().getTime() < System.currentTimeMillis()){
|
||||
return Result.error("申请事项已结束");
|
||||
}
|
||||
warmthCondolence.setNo(warmthCondolenceService.createNo(warmthCondolence));
|
||||
warmthCondolenceService.insertOrUpdate(warmthCondolence);
|
||||
//查询分工会审批人工号
|
||||
String branchUnionApprovalLoginName = commonService.findUserLoginNameByRoleCode(RoleConstant.BRANCH_UNION_CHAIRMAN, Cnd.where(Sys_user_role::getUnionId, "=", warmthCondolence.getUnionId()));
|
||||
if(StrUtil.isBlank(branchUnionApprovalLoginName)){
|
||||
if (StrUtil.isBlank(branchUnionApprovalLoginName)) {
|
||||
return Result.error("分工会未配置审批人,请联系校工会!");
|
||||
}
|
||||
bpmService.startSubmitProcessInstance(BpmProcessConstant.WARMTH_CONDOLENCE.name(), warmthCondolence.getUserName()+"的申请", warmthCondolence.getId(), List.of(branchUnionApprovalLoginName),null);
|
||||
bpmService.startSubmitProcessInstance(BpmProcessConstant.WARMTH_CONDOLENCE.name(), warmthCondolence.getUserName() + "的申请", warmthCondolence.getId(), List.of(branchUnionApprovalLoginName), null);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@At
|
||||
@SaCheckPermission("warmthCondolence.apply")
|
||||
@ApiOperation("详情")
|
||||
public Result info(@Valid String id){
|
||||
public Result info(@Valid String id) {
|
||||
WarmthCondolence condolence = warmthCondolenceService.fetch(id);
|
||||
return Result.success(condolence);
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public class WarmthCondolenceCommonController {
|
||||
@SaCheckPermission("warmthCondolence")
|
||||
public Result listNotice(){
|
||||
List<WarmthCondolenceNotice> list = warmthCondolenceNoticeService.query(Cnd.where(WarmthCondolenceNotice::getEnable, "=", 1)
|
||||
.asc(WarmthCondolenceNotice::getStartTime));
|
||||
.desc(WarmthCondolenceNotice::getStartTime));
|
||||
return Result.success(list);
|
||||
}
|
||||
|
||||
|
||||
+41
@@ -1,6 +1,11 @@
|
||||
package com.budwk.app.zhgh.staffmanage.member.controller.branch;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.DesensitizedUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.RepeatSubmit;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
@@ -9,14 +14,17 @@ import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.exception.BaseException;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.bpm.service.BpmService;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.web.controllers.open.commons.service.CommonService;
|
||||
import com.budwk.app.zhgh.staffmanage.member.constant.MemberChangeOrigin;
|
||||
import com.budwk.app.zhgh.staffmanage.member.models.MemberApplyRecord;
|
||||
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberManagePageForm;
|
||||
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberStatisticsPageForm;
|
||||
import com.budwk.app.zhgh.staffmanage.member.service.MemberManageService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
@@ -28,7 +36,9 @@ import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -121,4 +131,35 @@ public class MemberBranchUnionManageController {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("member.branchUnion.manage.list")
|
||||
public void doExport(MemberManagePageForm pageForm, HttpServletResponse response){
|
||||
Sql sql = memberManageService.getSql(pageForm, "branchUnion");
|
||||
List<NutMap> list = memberManageService.listMap(sql);
|
||||
|
||||
List<ExcelExportEntity> exportEntities = new ArrayList<>();
|
||||
exportEntities.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||
exportEntities.add(new ExcelExportEntity("姓名", "username", 20));
|
||||
exportEntities.add(new ExcelExportEntity("性别", "sex", 20));
|
||||
exportEntities.add(new ExcelExportEntity("出生年月", "birthday", 20));
|
||||
exportEntities.add(new ExcelExportEntity("联系电话", "mobile", 20));
|
||||
exportEntities.add(new ExcelExportEntity("在职状态", "userState", 20));
|
||||
exportEntities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
|
||||
exportEntities.add(new ExcelExportEntity("人员类型", "personType", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所属工会", "unionName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所属单位", "unitName", 30));
|
||||
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
|
||||
try {
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
|
||||
CommonDownloadUtil.download("会员名单.xlsx", workbook, response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+39
@@ -1,5 +1,9 @@
|
||||
package com.budwk.app.zhgh.staffmanage.member.controller.school;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelExportUtil;
|
||||
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.budwk.app.base.annotation.RepeatSubmit;
|
||||
@@ -7,6 +11,7 @@ import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.BpmProcessConstant;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.result.Result;
|
||||
import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.bpm.enums.BpmTaskApprovalTypeEnum;
|
||||
import com.budwk.app.bpm.models.BpmProcessInstance;
|
||||
import com.budwk.app.bpm.models.BpmProcessTask;
|
||||
@@ -18,6 +23,7 @@ import com.budwk.app.zhgh.staffmanage.member.models.MemberApplyRecord;
|
||||
import com.budwk.app.zhgh.staffmanage.member.param.pageform.MemberManagePageForm;
|
||||
import com.budwk.app.zhgh.staffmanage.member.service.MemberManageService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
@@ -31,7 +37,9 @@ import org.nutz.mvc.annotation.At;
|
||||
import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -131,4 +139,35 @@ public class MemberSchoolUnionManageController {
|
||||
return Result.error(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@At
|
||||
@Ok("void")
|
||||
@SaCheckPermission("member.branchUnion.manage.list")
|
||||
public void doExport(MemberManagePageForm pageForm, HttpServletResponse response){
|
||||
Sql sql = memberManageService.getSql(pageForm, "schoolUnion");
|
||||
List<NutMap> list = memberManageService.listMap(sql);
|
||||
|
||||
List<ExcelExportEntity> exportEntities = new ArrayList<>();
|
||||
exportEntities.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||
exportEntities.add(new ExcelExportEntity("姓名", "username", 20));
|
||||
exportEntities.add(new ExcelExportEntity("性别", "sex", 20));
|
||||
exportEntities.add(new ExcelExportEntity("出生年月", "birthday", 20));
|
||||
exportEntities.add(new ExcelExportEntity("联系电话", "mobile", 20));
|
||||
exportEntities.add(new ExcelExportEntity("在职状态", "userState", 20));
|
||||
exportEntities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
|
||||
exportEntities.add(new ExcelExportEntity("人员类型", "personType", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所属工会", "unionName", 20));
|
||||
exportEntities.add(new ExcelExportEntity("所属单位", "unitName", 30));
|
||||
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
|
||||
try {
|
||||
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, exportEntities, list);
|
||||
CommonDownloadUtil.download("会员名单.xlsx", workbook, response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
@@ -99,6 +99,9 @@ public class MemberManageServiceImpl extends BaseServiceImpl<Sys_user> implement
|
||||
if ("branchUnion".equals(queryType)) {
|
||||
cnd.and("u.unionId", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
cnd.asc("u.unionId");
|
||||
cnd.asc("u.unitId");
|
||||
cnd.asc("u.id");
|
||||
sql.setCondition(cnd);
|
||||
return sql;
|
||||
}
|
||||
|
||||
@@ -170,3 +170,128 @@ body {
|
||||
margin-top: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
|
||||
/*************************覆盖vant默认CSS********************************/
|
||||
.van-dropdown-menu__bar{
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
|
||||
/*****************************申请表单CSS********************************/
|
||||
.form-container {
|
||||
padding-bottom: 80px;
|
||||
}
|
||||
|
||||
.form-container .form-group {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.form-container .form-actions {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
padding: 12px 16px;
|
||||
background-color: #ffffff;
|
||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.05);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.form-container .form-actions .van-button {
|
||||
flex: 1;
|
||||
margin: 0 8px;
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.form-container .van-cell-group {
|
||||
margin-bottom: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.form-container .van-cell-group__title {
|
||||
font-size: 15px;
|
||||
color: var(--color-black);
|
||||
font-weight: 600;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.form-container .van-cell-group__title::before{
|
||||
content: "";
|
||||
width: 5px;
|
||||
background: var(--color-primary);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.form-container .van-field__label {
|
||||
width: 90px;
|
||||
color: #323233;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.form-container .van-field__value {
|
||||
color: #323233;
|
||||
}
|
||||
|
||||
.form-container .van-cell {
|
||||
padding: 12px 16px;
|
||||
}
|
||||
|
||||
.form-container .van-cell:not(:last-child)::after {
|
||||
left: 16px;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
.form-container .direction-column-field .van-field__label {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.form-container .direction-column-field .van-field__body {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.form-container .direction-column-field .van-field__control {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
/***************************查看详情CSS********************************/
|
||||
.detail-container {
|
||||
background: #f9f9f9
|
||||
}
|
||||
|
||||
.detail-container .van-cell-group__title{
|
||||
font-size: 15px;
|
||||
color: var(--color-black);
|
||||
font-weight: 600;
|
||||
padding: 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.detail-container .van-cell-group__title::before{
|
||||
content: "";
|
||||
width: 5px;
|
||||
background: var(--color-primary);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.detail-container .direction-column-cell{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.detail-container .direction-column-cell .van-cell__value{
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -228,3 +228,15 @@ const commonUtil = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function GetQueryString(name) {
|
||||
return new URLSearchParams(window.location.search).get(name)
|
||||
}
|
||||
|
||||
function loc() {
|
||||
return location.href.replace(location.search, "").replace(location.hash, "")
|
||||
}
|
||||
|
||||
function clone(obj) {
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-13205
File diff suppressed because one or more lines are too long
+13205
File diff suppressed because it is too large
Load Diff
+112
@@ -0,0 +1,112 @@
|
||||
@charset "UTF-8";
|
||||
/* 数据量大与遮罩交互冲突优化 */
|
||||
.v-modal.v-modal-leave {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-corner {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius: 6px;
|
||||
border: 2px solid transparent;
|
||||
background-color: var(--scrollbar-background-color);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.el-dialog__header {
|
||||
padding: 15px 20px 15px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--border-color-lighter);
|
||||
}
|
||||
|
||||
.el-dialog__title {
|
||||
flex: 1;
|
||||
font-size: 16px;
|
||||
margin: 0;
|
||||
color: rgba(0, 0, 0, 0.88);
|
||||
font-weight: 600;
|
||||
line-height: 1.5;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.el-dialog__headerbtn{
|
||||
top: auto;
|
||||
right: auto;
|
||||
line-height: 1;
|
||||
font-size: 18px;
|
||||
position: static;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
padding-bottom: 12px;
|
||||
border-top: 1px solid var(--border-color-lighter);
|
||||
}
|
||||
|
||||
.el-table thead {
|
||||
color: var(--color-text-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.el-table td.el-table__cell div {
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
|
||||
.el-card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-card + .el-card {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.el-message:not(.ele-message-border){
|
||||
background: var(--popover-background-color);
|
||||
-webkit-box-shadow: var(--box-shadow-light);
|
||||
box-shadow: var(--box-shadow-light);
|
||||
border-radius: 2px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-message {
|
||||
min-width: auto;
|
||||
position: fixed;
|
||||
}
|
||||
|
||||
.el-message .el-message__icon {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.el-message .el-icon-success {
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.el-message:not(.ele-message-border) .el-message__content {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.el-message .el-message__content {
|
||||
line-height: 18px;
|
||||
}
|
||||
|
||||
.el-button{
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.el-descriptions .is-bordered{
|
||||
table-layout: fixed;!important;
|
||||
}
|
||||
|
||||
+1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,927 @@
|
||||
/*
|
||||
|
||||
PinchZoom.js
|
||||
Copyright (c) Manuel Stofer 2013 - today
|
||||
|
||||
Author: Manuel Stofer (mst@rtp.ch)
|
||||
Version: 2.3.5
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
// polyfills
|
||||
if (typeof Object.assign != 'function') {
|
||||
// Must be writable: true, enumerable: false, configurable: true
|
||||
Object.defineProperty(Object, "assign", {
|
||||
value: function assign(target, varArgs) { // .length of function is 2
|
||||
if (target == null) { // TypeError if undefined or null
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
}
|
||||
|
||||
var to = Object(target);
|
||||
|
||||
for (var index = 1; index < arguments.length; index++) {
|
||||
var nextSource = arguments[index];
|
||||
|
||||
if (nextSource != null) { // Skip over if undefined or null
|
||||
for (var nextKey in nextSource) {
|
||||
// Avoid bugs when hasOwnProperty is shadowed
|
||||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
},
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
if (typeof Array.from != 'function') {
|
||||
Array.from = function (object) {
|
||||
return [].slice.call(object);
|
||||
};
|
||||
}
|
||||
|
||||
// utils
|
||||
var buildElement = function(str) {
|
||||
// empty string as title argument required by IE and Edge
|
||||
var tmp = document.implementation.createHTMLDocument('');
|
||||
tmp.body.innerHTML = str;
|
||||
return Array.from(tmp.body.children)[0];
|
||||
};
|
||||
|
||||
var triggerEvent = function(el, name) {
|
||||
var event = document.createEvent('HTMLEvents');
|
||||
event.initEvent(name, true, false);
|
||||
el.dispatchEvent(event);
|
||||
};
|
||||
|
||||
var definePinchZoom = function () {
|
||||
|
||||
/**
|
||||
* Pinch zoom
|
||||
* @param el
|
||||
* @param options
|
||||
* @constructor
|
||||
*/
|
||||
var PinchZoom = function (el, options) {
|
||||
this.el = el;
|
||||
this.zoomFactor = 1;
|
||||
this.lastScale = 1;
|
||||
this.offset = {
|
||||
x: 0,
|
||||
y: 0
|
||||
};
|
||||
this.initialOffset = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
this.options = Object.assign({}, this.defaults, options);
|
||||
this.setupMarkup();
|
||||
this.bindEvents();
|
||||
this.update();
|
||||
|
||||
// The image may already be loaded when PinchZoom is initialized,
|
||||
// and then the load event (which trigger update) will never fire.
|
||||
if (this.isImageLoaded(this.el)) {
|
||||
this.updateAspectRatio();
|
||||
this.setupOffsets();
|
||||
}
|
||||
|
||||
this.enable();
|
||||
|
||||
},
|
||||
sum = function (a, b) {
|
||||
return a + b;
|
||||
},
|
||||
isCloseTo = function (value, expected) {
|
||||
return value > expected - 0.01 && value < expected + 0.01;
|
||||
};
|
||||
|
||||
PinchZoom.prototype = {
|
||||
|
||||
defaults: {
|
||||
tapZoomFactor: 2,
|
||||
zoomOutFactor: 1.3,
|
||||
animationDuration: 300,
|
||||
maxZoom: 4,
|
||||
minZoom: 0.5,
|
||||
draggableUnzoomed: true,
|
||||
lockDragAxis: false,
|
||||
setOffsetsOnce: false,
|
||||
use2d: true,
|
||||
zoomStartEventName: 'pz_zoomstart',
|
||||
zoomUpdateEventName: 'pz_zoomupdate',
|
||||
zoomEndEventName: 'pz_zoomend',
|
||||
dragStartEventName: 'pz_dragstart',
|
||||
dragUpdateEventName: 'pz_dragupdate',
|
||||
dragEndEventName: 'pz_dragend',
|
||||
doubleTapEventName: 'pz_doubletap',
|
||||
verticalPadding: 0,
|
||||
horizontalPadding: 0,
|
||||
onZoomStart: null,
|
||||
onZoomEnd: null,
|
||||
onZoomUpdate: null,
|
||||
onDragStart: null,
|
||||
onDragEnd: null,
|
||||
onDragUpdate: null,
|
||||
onDoubleTap: null
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for 'dragstart'
|
||||
* @param event
|
||||
*/
|
||||
handleDragStart: function (event) {
|
||||
triggerEvent(this.el, this.options.dragStartEventName);
|
||||
if(typeof this.options.onDragStart == "function"){
|
||||
this.options.onDragStart(this, event)
|
||||
}
|
||||
this.stopAnimation();
|
||||
this.lastDragPosition = false;
|
||||
this.hasInteraction = true;
|
||||
this.handleDrag(event);
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for 'drag'
|
||||
* @param event
|
||||
*/
|
||||
handleDrag: function (event) {
|
||||
var touch = this.getTouches(event)[0];
|
||||
this.drag(touch, this.lastDragPosition);
|
||||
this.offset = this.sanitizeOffset(this.offset);
|
||||
this.lastDragPosition = touch;
|
||||
},
|
||||
|
||||
handleDragEnd: function () {
|
||||
triggerEvent(this.el, this.options.dragEndEventName);
|
||||
if(typeof this.options.onDragEnd == "function"){
|
||||
this.options.onDragEnd(this, event)
|
||||
}
|
||||
this.end();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for 'zoomstart'
|
||||
* @param event
|
||||
*/
|
||||
handleZoomStart: function (event) {
|
||||
triggerEvent(this.el, this.options.zoomStartEventName);
|
||||
if(typeof this.options.onZoomStart == "function"){
|
||||
this.options.onZoomStart(this, event)
|
||||
}
|
||||
this.stopAnimation();
|
||||
this.lastScale = 1;
|
||||
this.nthZoom = 0;
|
||||
this.lastZoomCenter = false;
|
||||
this.hasInteraction = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for 'zoom'
|
||||
* @param event
|
||||
*/
|
||||
handleZoom: function (event, newScale) {
|
||||
// a relative scale factor is used
|
||||
var touchCenter = this.getTouchCenter(this.getTouches(event)),
|
||||
scale = newScale / this.lastScale;
|
||||
this.lastScale = newScale;
|
||||
|
||||
// the first touch events are thrown away since they are not precise
|
||||
this.nthZoom += 1;
|
||||
if (this.nthZoom > 3) {
|
||||
|
||||
this.scale(scale, touchCenter);
|
||||
this.drag(touchCenter, this.lastZoomCenter);
|
||||
}
|
||||
this.lastZoomCenter = touchCenter;
|
||||
},
|
||||
|
||||
handleZoomEnd: function () {
|
||||
triggerEvent(this.el, this.options.zoomEndEventName);
|
||||
if(typeof this.options.onZoomEnd == "function"){
|
||||
this.options.onZoomEnd(this, event)
|
||||
}
|
||||
this.end();
|
||||
},
|
||||
|
||||
/**
|
||||
* Event handler for 'doubletap'
|
||||
* @param event
|
||||
*/
|
||||
handleDoubleTap: function (event) {
|
||||
var center = this.getTouches(event)[0],
|
||||
zoomFactor = this.zoomFactor > 1 ? 1 : this.options.tapZoomFactor,
|
||||
startZoomFactor = this.zoomFactor,
|
||||
updateProgress = (function (progress) {
|
||||
this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center);
|
||||
}).bind(this);
|
||||
|
||||
if (this.hasInteraction) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isDoubleTap = true;
|
||||
|
||||
if (startZoomFactor > zoomFactor) {
|
||||
center = this.getCurrentZoomCenter();
|
||||
}
|
||||
|
||||
this.animate(this.options.animationDuration, updateProgress, this.swing);
|
||||
triggerEvent(this.el, this.options.doubleTapEventName);
|
||||
if(typeof this.options.onDoubleTap == "function"){
|
||||
this.options.onDoubleTap(this, event)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Compute the initial offset
|
||||
*
|
||||
* the element should be centered in the container upon initialization
|
||||
*/
|
||||
computeInitialOffset: function () {
|
||||
this.initialOffset = {
|
||||
x: -Math.abs(this.el.offsetWidth * this.getInitialZoomFactor() - this.container.offsetWidth) / 2,
|
||||
y: -Math.abs(this.el.offsetHeight * this.getInitialZoomFactor() - this.container.offsetHeight) / 2,
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset current image offset to that of the initial offset
|
||||
*/
|
||||
resetOffset: function() {
|
||||
this.offset.x = this.initialOffset.x;
|
||||
this.offset.y = this.initialOffset.y;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if image is loaded
|
||||
*/
|
||||
isImageLoaded: function (el) {
|
||||
if (el.nodeName === 'IMG') {
|
||||
return el.complete && el.naturalHeight !== 0;
|
||||
} else {
|
||||
return Array.from(el.querySelectorAll('img')).every(this.isImageLoaded);
|
||||
}
|
||||
},
|
||||
|
||||
setupOffsets: function() {
|
||||
if (this.options.setOffsetsOnce && this._isOffsetsSet) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isOffsetsSet = true;
|
||||
|
||||
this.computeInitialOffset();
|
||||
this.resetOffset();
|
||||
},
|
||||
|
||||
/**
|
||||
* Max / min values for the offset
|
||||
* @param offset
|
||||
* @return {Object} the sanitized offset
|
||||
*/
|
||||
sanitizeOffset: function (offset) {
|
||||
var elWidth = this.el.offsetWidth * this.getInitialZoomFactor() * this.zoomFactor;
|
||||
var elHeight = this.el.offsetHeight * this.getInitialZoomFactor() * this.zoomFactor;
|
||||
var maxX = elWidth - this.getContainerX() + this.options.horizontalPadding,
|
||||
maxY = elHeight - this.getContainerY() + this.options.verticalPadding,
|
||||
maxOffsetX = Math.max(maxX, 0),
|
||||
maxOffsetY = Math.max(maxY, 0),
|
||||
minOffsetX = Math.min(maxX, 0) - this.options.horizontalPadding,
|
||||
minOffsetY = Math.min(maxY, 0) - this.options.verticalPadding;
|
||||
|
||||
return {
|
||||
x: Math.min(Math.max(offset.x, minOffsetX), maxOffsetX),
|
||||
y: Math.min(Math.max(offset.y, minOffsetY), maxOffsetY)
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Scale to a specific zoom factor (not relative)
|
||||
* @param zoomFactor
|
||||
* @param center
|
||||
*/
|
||||
scaleTo: function (zoomFactor, center) {
|
||||
this.scale(zoomFactor / this.zoomFactor, center);
|
||||
},
|
||||
|
||||
/**
|
||||
* Scales the element from specified center
|
||||
* @param scale
|
||||
* @param center
|
||||
*/
|
||||
scale: function (scale, center) {
|
||||
scale = this.scaleZoomFactor(scale);
|
||||
this.addOffset({
|
||||
x: (scale - 1) * (center.x + this.offset.x),
|
||||
y: (scale - 1) * (center.y + this.offset.y)
|
||||
});
|
||||
triggerEvent(this.el, this.options.zoomUpdateEventName);
|
||||
if(typeof this.options.onZoomUpdate == "function"){
|
||||
this.options.onZoomUpdate(this, event)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Scales the zoom factor relative to current state
|
||||
* @param scale
|
||||
* @return the actual scale (can differ because of max min zoom factor)
|
||||
*/
|
||||
scaleZoomFactor: function (scale) {
|
||||
var originalZoomFactor = this.zoomFactor;
|
||||
this.zoomFactor *= scale;
|
||||
this.zoomFactor = Math.min(this.options.maxZoom, Math.max(this.zoomFactor, this.options.minZoom));
|
||||
return this.zoomFactor / originalZoomFactor;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if the image is in a draggable state
|
||||
*
|
||||
* When the image can be dragged, the drag event is acted upon and cancelled.
|
||||
* When not draggable, the drag event bubbles through this component.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
canDrag: function () {
|
||||
return this.options.draggableUnzoomed || !isCloseTo(this.zoomFactor, 1);
|
||||
},
|
||||
|
||||
/**
|
||||
* Drags the element
|
||||
* @param center
|
||||
* @param lastCenter
|
||||
*/
|
||||
drag: function (center, lastCenter) {
|
||||
if (lastCenter) {
|
||||
if(this.options.lockDragAxis) {
|
||||
// lock scroll to position that was changed the most
|
||||
if(Math.abs(center.x - lastCenter.x) > Math.abs(center.y - lastCenter.y)) {
|
||||
this.addOffset({
|
||||
x: -(center.x - lastCenter.x),
|
||||
y: 0
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.addOffset({
|
||||
y: -(center.y - lastCenter.y),
|
||||
x: 0
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.addOffset({
|
||||
y: -(center.y - lastCenter.y),
|
||||
x: -(center.x - lastCenter.x)
|
||||
});
|
||||
}
|
||||
triggerEvent(this.el, this.options.dragUpdateEventName);
|
||||
if(typeof this.options.onDragUpdate == "function"){
|
||||
this.options.onDragUpdate(this, event)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the touch center of multiple touches
|
||||
* @param touches
|
||||
* @return {Object}
|
||||
*/
|
||||
getTouchCenter: function (touches) {
|
||||
return this.getVectorAvg(touches);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the average of multiple vectors (x, y values)
|
||||
*/
|
||||
getVectorAvg: function (vectors) {
|
||||
return {
|
||||
x: vectors.map(function (v) { return v.x; }).reduce(sum) / vectors.length,
|
||||
y: vectors.map(function (v) { return v.y; }).reduce(sum) / vectors.length
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an offset
|
||||
* @param offset the offset to add
|
||||
* @return return true when the offset change was accepted
|
||||
*/
|
||||
addOffset: function (offset) {
|
||||
this.offset = {
|
||||
x: this.offset.x + offset.x,
|
||||
y: this.offset.y + offset.y
|
||||
};
|
||||
},
|
||||
|
||||
sanitize: function () {
|
||||
if (this.zoomFactor < this.options.zoomOutFactor) {
|
||||
this.zoomOutAnimation();
|
||||
} else if (this.isInsaneOffset(this.offset)) {
|
||||
this.sanitizeOffsetAnimation();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the offset is ok with the current zoom factor
|
||||
* @param offset
|
||||
* @return {Boolean}
|
||||
*/
|
||||
isInsaneOffset: function (offset) {
|
||||
var sanitizedOffset = this.sanitizeOffset(offset);
|
||||
return sanitizedOffset.x !== offset.x ||
|
||||
sanitizedOffset.y !== offset.y;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates an animation moving to a sane offset
|
||||
*/
|
||||
sanitizeOffsetAnimation: function () {
|
||||
var targetOffset = this.sanitizeOffset(this.offset),
|
||||
startOffset = {
|
||||
x: this.offset.x,
|
||||
y: this.offset.y
|
||||
},
|
||||
updateProgress = (function (progress) {
|
||||
this.offset.x = startOffset.x + progress * (targetOffset.x - startOffset.x);
|
||||
this.offset.y = startOffset.y + progress * (targetOffset.y - startOffset.y);
|
||||
this.update();
|
||||
}).bind(this);
|
||||
|
||||
this.animate(
|
||||
this.options.animationDuration,
|
||||
updateProgress,
|
||||
this.swing
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Zooms back to the original position,
|
||||
* (no offset and zoom factor 1)
|
||||
*/
|
||||
zoomOutAnimation: function () {
|
||||
if (this.zoomFactor === 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
var startZoomFactor = this.zoomFactor,
|
||||
zoomFactor = 1,
|
||||
center = this.getCurrentZoomCenter(),
|
||||
updateProgress = (function (progress) {
|
||||
this.scaleTo(startZoomFactor + progress * (zoomFactor - startZoomFactor), center);
|
||||
}).bind(this);
|
||||
|
||||
this.animate(
|
||||
this.options.animationDuration,
|
||||
updateProgress,
|
||||
this.swing
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the container aspect ratio
|
||||
*
|
||||
* Any previous container height must be cleared before re-measuring the
|
||||
* parent height, since it depends implicitly on the height of any of its children
|
||||
*/
|
||||
updateAspectRatio: function () {
|
||||
this.unsetContainerY();
|
||||
this.setContainerY(this.container.parentElement.offsetHeight);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the initial zoom factor (for the element to fit into the container)
|
||||
* @return {number} the initial zoom factor
|
||||
*/
|
||||
getInitialZoomFactor: function () {
|
||||
var xZoomFactor = this.container.offsetWidth / this.el.offsetWidth;
|
||||
var yZoomFactor = this.container.offsetHeight / this.el.offsetHeight;
|
||||
|
||||
return Math.min(xZoomFactor, yZoomFactor);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the aspect ratio of the element
|
||||
* @return the aspect ratio
|
||||
*/
|
||||
getAspectRatio: function () {
|
||||
return this.el.offsetWidth / this.el.offsetHeight;
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates the virtual zoom center for the current offset and zoom factor
|
||||
* (used for reverse zoom)
|
||||
* @return {Object} the current zoom center
|
||||
*/
|
||||
getCurrentZoomCenter: function () {
|
||||
var offsetLeft = this.offset.x - this.initialOffset.x;
|
||||
var centerX = -1 * this.offset.x - offsetLeft / (1 / this.zoomFactor - 1);
|
||||
|
||||
var offsetTop = this.offset.y - this.initialOffset.y;
|
||||
var centerY = -1 * this.offset.y - offsetTop / (1 / this.zoomFactor - 1);
|
||||
|
||||
return {
|
||||
x: centerX,
|
||||
y: centerY
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the touches of an event relative to the container offset
|
||||
* @param event
|
||||
* @return array touches
|
||||
*/
|
||||
getTouches: function (event) {
|
||||
var rect = this.container.getBoundingClientRect();
|
||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
var posTop = rect.top + scrollTop;
|
||||
var posLeft = rect.left + scrollLeft;
|
||||
|
||||
return Array.prototype.slice.call(event.touches).map(function (touch) {
|
||||
return {
|
||||
x: touch.pageX - posLeft,
|
||||
y: touch.pageY - posTop,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Animation loop
|
||||
* does not support simultaneous animations
|
||||
* @param duration
|
||||
* @param framefn
|
||||
* @param timefn
|
||||
* @param callback
|
||||
*/
|
||||
animate: function (duration, framefn, timefn, callback) {
|
||||
var startTime = new Date().getTime(),
|
||||
renderFrame = (function () {
|
||||
if (!this.inAnimation) { return; }
|
||||
var frameTime = new Date().getTime() - startTime,
|
||||
progress = frameTime / duration;
|
||||
if (frameTime >= duration) {
|
||||
framefn(1);
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
this.update();
|
||||
this.stopAnimation();
|
||||
this.update();
|
||||
} else {
|
||||
if (timefn) {
|
||||
progress = timefn(progress);
|
||||
}
|
||||
framefn(progress);
|
||||
this.update();
|
||||
requestAnimationFrame(renderFrame);
|
||||
}
|
||||
}).bind(this);
|
||||
this.inAnimation = true;
|
||||
requestAnimationFrame(renderFrame);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stops the animation
|
||||
*/
|
||||
stopAnimation: function () {
|
||||
this.inAnimation = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Swing timing function for animations
|
||||
* @param p
|
||||
* @return {Number}
|
||||
*/
|
||||
swing: function (p) {
|
||||
return -Math.cos(p * Math.PI) / 2 + 0.5;
|
||||
},
|
||||
|
||||
getContainerX: function () {
|
||||
return this.container.offsetWidth;
|
||||
},
|
||||
|
||||
getContainerY: function () {
|
||||
return this.container.offsetHeight;
|
||||
},
|
||||
|
||||
setContainerY: function (y) {
|
||||
return this.container.style.height = y + 'px';
|
||||
},
|
||||
|
||||
unsetContainerY: function () {
|
||||
this.container.style.height = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates the expected html structure
|
||||
*/
|
||||
setupMarkup: function () {
|
||||
this.container = buildElement('<div class="pinch-zoom-container"></div>');
|
||||
this.el.parentNode.insertBefore(this.container, this.el);
|
||||
this.container.appendChild(this.el);
|
||||
|
||||
this.container.style.overflow = 'hidden';
|
||||
this.container.style.position = 'relative';
|
||||
|
||||
this.el.style.webkitTransformOrigin = '0% 0%';
|
||||
this.el.style.mozTransformOrigin = '0% 0%';
|
||||
this.el.style.msTransformOrigin = '0% 0%';
|
||||
this.el.style.oTransformOrigin = '0% 0%';
|
||||
this.el.style.transformOrigin = '0% 0%';
|
||||
|
||||
this.el.style.position = 'absolute';
|
||||
},
|
||||
|
||||
end: function () {
|
||||
this.hasInteraction = false;
|
||||
this.sanitize();
|
||||
this.update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Binds all required event listeners
|
||||
*/
|
||||
bindEvents: function () {
|
||||
var self = this;
|
||||
detectGestures(this.container, this);
|
||||
|
||||
this.resizeHandler = this.update.bind(this)
|
||||
window.addEventListener('resize', this.resizeHandler);
|
||||
Array.from(this.el.querySelectorAll('img')).forEach(function(imgEl) {
|
||||
imgEl.addEventListener('load', self.update.bind(self));
|
||||
});
|
||||
|
||||
if (this.el.nodeName === 'IMG') {
|
||||
this.el.addEventListener('load', this.update.bind(this));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the css values according to the current zoom factor and offset
|
||||
*/
|
||||
update: function (event) {
|
||||
if (event && event.type === 'resize') {
|
||||
this.updateAspectRatio();
|
||||
this.setupOffsets();
|
||||
}
|
||||
|
||||
if (event && event.type === 'load') {
|
||||
this.updateAspectRatio();
|
||||
this.setupOffsets();
|
||||
}
|
||||
|
||||
if (this.updatePlanned) {
|
||||
return;
|
||||
}
|
||||
this.updatePlanned = true;
|
||||
|
||||
window.setTimeout((function () {
|
||||
this.updatePlanned = false;
|
||||
|
||||
var zoomFactor = this.getInitialZoomFactor() * this.zoomFactor,
|
||||
offsetX = -this.offset.x / zoomFactor,
|
||||
offsetY = -this.offset.y / zoomFactor,
|
||||
transform3d = 'scale3d(' + zoomFactor + ', ' + zoomFactor + ',1) ' +
|
||||
'translate3d(' + offsetX + 'px,' + offsetY + 'px,0px)',
|
||||
transform2d = 'scale(' + zoomFactor + ', ' + zoomFactor + ') ' +
|
||||
'translate(' + offsetX + 'px,' + offsetY + 'px)',
|
||||
removeClone = (function () {
|
||||
if (this.clone) {
|
||||
this.clone.parentNode.removeChild(this.clone);
|
||||
delete this.clone;
|
||||
}
|
||||
}).bind(this);
|
||||
|
||||
// Scale 3d and translate3d are faster (at least on ios)
|
||||
// but they also reduce the quality.
|
||||
// PinchZoom uses the 3d transformations during interactions
|
||||
// after interactions it falls back to 2d transformations
|
||||
if (!this.options.use2d || this.hasInteraction || this.inAnimation) {
|
||||
this.is3d = true;
|
||||
removeClone();
|
||||
|
||||
this.el.style.webkitTransform = transform3d;
|
||||
this.el.style.mozTransform = transform2d;
|
||||
this.el.style.msTransform = transform2d;
|
||||
this.el.style.oTransform = transform2d;
|
||||
this.el.style.transform = transform3d;
|
||||
} else {
|
||||
// When changing from 3d to 2d transform webkit has some glitches.
|
||||
// To avoid this, a copy of the 3d transformed element is displayed in the
|
||||
// foreground while the element is converted from 3d to 2d transform
|
||||
if (this.is3d) {
|
||||
this.clone = this.el.cloneNode(true);
|
||||
this.clone.style.pointerEvents = 'none';
|
||||
this.container.appendChild(this.clone);
|
||||
window.setTimeout(removeClone, 200);
|
||||
}
|
||||
|
||||
this.el.style.webkitTransform = transform2d;
|
||||
this.el.style.mozTransform = transform2d;
|
||||
this.el.style.msTransform = transform2d;
|
||||
this.el.style.oTransform = transform2d;
|
||||
this.el.style.transform = transform2d;
|
||||
|
||||
this.is3d = false;
|
||||
}
|
||||
}).bind(this), 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Enables event handling for gestures
|
||||
*/
|
||||
enable: function() {
|
||||
this.enabled = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Disables event handling for gestures
|
||||
*/
|
||||
disable: function() {
|
||||
this.enabled = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Unmounts the zooming container and global event listeners
|
||||
*/
|
||||
destroy: function () {
|
||||
window.removeEventListener('resize', this.resizeHandler);
|
||||
|
||||
if (this.container) {
|
||||
this.container.remove();
|
||||
this.container = null;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
var detectGestures = function (el, target) {
|
||||
var interaction = null,
|
||||
fingers = 0,
|
||||
lastTouchStart = null,
|
||||
startTouches = null,
|
||||
|
||||
setInteraction = function (newInteraction, event) {
|
||||
if (interaction !== newInteraction) {
|
||||
|
||||
if (interaction && !newInteraction) {
|
||||
switch (interaction) {
|
||||
case "zoom":
|
||||
target.handleZoomEnd(event);
|
||||
break;
|
||||
case 'drag':
|
||||
target.handleDragEnd(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (newInteraction) {
|
||||
case 'zoom':
|
||||
target.handleZoomStart(event);
|
||||
break;
|
||||
case 'drag':
|
||||
target.handleDragStart(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
interaction = newInteraction;
|
||||
},
|
||||
|
||||
updateInteraction = function (event) {
|
||||
if (fingers === 2) {
|
||||
setInteraction('zoom');
|
||||
} else if (fingers === 1 && target.canDrag()) {
|
||||
setInteraction('drag', event);
|
||||
} else {
|
||||
setInteraction(null, event);
|
||||
}
|
||||
},
|
||||
|
||||
targetTouches = function (touches) {
|
||||
return Array.from(touches).map(function (touch) {
|
||||
return {
|
||||
x: touch.pageX,
|
||||
y: touch.pageY
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
getDistance = function (a, b) {
|
||||
var x, y;
|
||||
x = a.x - b.x;
|
||||
y = a.y - b.y;
|
||||
return Math.sqrt(x * x + y * y);
|
||||
},
|
||||
|
||||
calculateScale = function (startTouches, endTouches) {
|
||||
var startDistance = getDistance(startTouches[0], startTouches[1]),
|
||||
endDistance = getDistance(endTouches[0], endTouches[1]);
|
||||
return endDistance / startDistance;
|
||||
},
|
||||
|
||||
cancelEvent = function (event) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
},
|
||||
|
||||
detectDoubleTap = function (event) {
|
||||
var time = (new Date()).getTime();
|
||||
|
||||
if (fingers > 1) {
|
||||
lastTouchStart = null;
|
||||
}
|
||||
|
||||
if (time - lastTouchStart < 300) {
|
||||
cancelEvent(event);
|
||||
|
||||
target.handleDoubleTap(event);
|
||||
switch (interaction) {
|
||||
case "zoom":
|
||||
target.handleZoomEnd(event);
|
||||
break;
|
||||
case 'drag':
|
||||
target.handleDragEnd(event);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
target.isDoubleTap = false;
|
||||
}
|
||||
|
||||
if (fingers === 1) {
|
||||
lastTouchStart = time;
|
||||
}
|
||||
},
|
||||
firstMove = true;
|
||||
|
||||
el.addEventListener('touchstart', function (event) {
|
||||
if(target.enabled) {
|
||||
firstMove = true;
|
||||
fingers = event.touches.length;
|
||||
detectDoubleTap(event);
|
||||
}
|
||||
}, { passive: false });
|
||||
|
||||
el.addEventListener('touchmove', function (event) {
|
||||
if(target.enabled && !target.isDoubleTap) {
|
||||
if (firstMove) {
|
||||
updateInteraction(event);
|
||||
if (interaction) {
|
||||
cancelEvent(event);
|
||||
}
|
||||
startTouches = targetTouches(event.touches);
|
||||
} else {
|
||||
switch (interaction) {
|
||||
case 'zoom':
|
||||
if (startTouches.length == 2 && event.touches.length == 2) {
|
||||
target.handleZoom(event, calculateScale(startTouches, targetTouches(event.touches)));
|
||||
}
|
||||
break;
|
||||
case 'drag':
|
||||
target.handleDrag(event);
|
||||
break;
|
||||
}
|
||||
if (interaction) {
|
||||
cancelEvent(event);
|
||||
target.update();
|
||||
}
|
||||
}
|
||||
|
||||
firstMove = false;
|
||||
}
|
||||
}, { passive: false });
|
||||
|
||||
el.addEventListener('touchend', function (event) {
|
||||
if(target.enabled) {
|
||||
fingers = event.touches.length;
|
||||
updateInteraction(event);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return PinchZoom;
|
||||
};
|
||||
|
||||
var PinchZoom = definePinchZoom();
|
||||
|
||||
export default PinchZoom;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -18,7 +18,7 @@
|
||||
<div :class="{ card_scroll: edit_scroll }">
|
||||
<slot name="edit"></slot>
|
||||
</div>
|
||||
<div style="border-top: 1px solid #ebeef5; padding-top: 10px">
|
||||
<div style="border-top: 1px solid #ebeef5; padding-top: 10px" v-if="$slots['edit-footer']">
|
||||
<slot name="edit-footer"></slot>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<script>
|
||||
module.exports = {
|
||||
name: "TableColumn",
|
||||
props: {
|
||||
label: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
required: false
|
||||
},
|
||||
label_suffix:{
|
||||
type: String,
|
||||
default: ":"
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="table-column">
|
||||
<!-- 左侧 Label -->
|
||||
<div class="label">
|
||||
<slot name="label">
|
||||
{{ label }}
|
||||
{{label_suffix}}
|
||||
</slot>
|
||||
</div>
|
||||
<!-- 右侧 Value -->
|
||||
<div class="value">
|
||||
<slot>{{ value }}</slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.table-column {
|
||||
display: flex;
|
||||
padding: 6px 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
flex-shrink: 0;
|
||||
max-width: 120px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #555;
|
||||
font-size: 14px;
|
||||
flex-grow: 1; /* 动态占据剩余部分 */
|
||||
white-space: nowrap; /* 防止换行 */
|
||||
overflow: hidden; /* 隐藏溢出的部分 */
|
||||
text-overflow: ellipsis; /* 省略号 */
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,278 @@
|
||||
<template>
|
||||
<van-pull-refresh v-model="tableRefreshing" @refresh="onRefresh">
|
||||
<div v-if="tableData.length === 0" class="empty-state">
|
||||
<van-empty description="暂无数据"></van-empty>
|
||||
</div>
|
||||
<van-list v-if="tableData && tableData.length>0"
|
||||
v-model="tableLoading"
|
||||
:finished="tableFinished"
|
||||
finished-text="没有更多了"
|
||||
@load="onLoad">
|
||||
<div class="table-list-container">
|
||||
<div v-for="(row, index) in tableData" :key="index" class="table-list-item">
|
||||
<slot name="header" :index="index" :row="row">
|
||||
<div class="item-header">
|
||||
<div class="item-title">{{ row[title] }}</div>
|
||||
<enum-tag :value="row.instanceState" name="ProcessInstanceStateEnum" label_key="message"
|
||||
size="small"></enum-tag>
|
||||
</div>
|
||||
</slot>
|
||||
|
||||
<div style="display: flex;column-gap: 10px"
|
||||
:style="{'max-height':img ? '100px':'unset', 'overflow': img ? 'hidden':'unset' }">
|
||||
<div class="img-container" v-if="img">
|
||||
<img :src="row[img]" alt="" style="object-fit: cover">
|
||||
</div>
|
||||
<div class="">
|
||||
<slot :index="index" :row="row"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
<slot name="actions" :index="index" :row="row"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-list>
|
||||
</van-pull-refresh>
|
||||
</template>
|
||||
<script>
|
||||
module.exports = {
|
||||
name: "TableList",
|
||||
props: {
|
||||
api: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
page_form: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => {
|
||||
return {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: ""
|
||||
}
|
||||
}
|
||||
},
|
||||
json: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
img: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
page_form: {
|
||||
handler(newVal, oldVal) {
|
||||
this.localPageForm = { ...newVal }
|
||||
},
|
||||
deep: true,
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: [],
|
||||
tableLoading: false,
|
||||
tableFinished: false,
|
||||
tableRefreshing: false,
|
||||
localPageForm: { ...this.page_form }
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onLoad() {
|
||||
if (this.tableFinished) return
|
||||
this.localPageForm.pageNumber++
|
||||
this.$emit("update:page_form", { ...this.localPageForm })
|
||||
this.pageData()
|
||||
},
|
||||
|
||||
pageData() {
|
||||
this.tableLoading = true
|
||||
|
||||
const loading = createListLoading()
|
||||
this.$axios.post(this.api, this.json ? ({ pageForm: JSON.stringify(this.localPageForm) }) : this.localPageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = this.tableData.concat(res.data.list)
|
||||
this.localPageForm.totalCount = res.data.totalCount
|
||||
if (this.tableData.length >= this.localPageForm.totalCount) {
|
||||
this.tableFinished = true
|
||||
}
|
||||
this.$emit("update:page_form", { ...this.localPageForm })
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.close()
|
||||
console.log(this.tableLoading)
|
||||
this.tableLoading = false
|
||||
console.log(this.tableLoading)
|
||||
this.tableRefreshing = false
|
||||
})
|
||||
},
|
||||
doSearch() {
|
||||
this.tableFinished = false
|
||||
this.tableData = []
|
||||
this.localPageForm.pageNumber = 1
|
||||
this.$emit("update:page_form", { ...this.localPageForm })
|
||||
this.pageData()
|
||||
},
|
||||
onRefresh() {
|
||||
this.localPageForm.pageNumber = 1
|
||||
this.$emit("update:page_form", { ...this.localPageForm })
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$emit("ready")
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.table-list-container {
|
||||
padding: 0;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item:last-child {
|
||||
border-bottom: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .item-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .item-title {
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
color: #1f2f3d;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .img-container {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .img-container img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
|
||||
.table-list-container .table-list-item .item-meta {
|
||||
display: flex;
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .meta-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .meta-item i {
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
width: 16px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .item-content {
|
||||
color: #606266;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .item-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-top: 12px;
|
||||
padding-top: 8px;
|
||||
border-top: 1px dashed #eaecef;
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .item-actions {
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
justify-content: end;
|
||||
margin-top: 15px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px solid #eaecef;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .action-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
font-size: 14px;
|
||||
color: var(--color-primary);
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .action-btn i {
|
||||
margin-right: 6px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .action-btn.delete {
|
||||
color: #ff0000;
|
||||
}
|
||||
|
||||
.table-list-container .table-list-item .action-btn.review {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.table-list-container .empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.table-list-container .empty-state i {
|
||||
font-size: 60px;
|
||||
margin-bottom: 16px;
|
||||
color: #dcdee0;
|
||||
}
|
||||
|
||||
.table-list-container .empty-state p {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-for="item in options">
|
||||
<component :key="item[value_key]" v-if="item[value_key] === value" v-bind="$attrs"
|
||||
:is="isMobile ? 'van-tag' : 'el-tag'" :type="item.type"
|
||||
>{{ item[label_key] }}
|
||||
</component>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 全局缓存和请求Promise缓存
|
||||
const enumCache = {}
|
||||
const requestPromises = {}
|
||||
|
||||
module.exports = {
|
||||
name: "DictTag",
|
||||
props: {
|
||||
value: { type: String | Number },
|
||||
name: { type: String },
|
||||
value_key: {
|
||||
type: String,
|
||||
default: "code"
|
||||
},
|
||||
label_key: {
|
||||
type: String,
|
||||
default: "name"
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: [],
|
||||
isMobile: true,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
code: {
|
||||
handler(val) {
|
||||
this.getEnumOptions()
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isMobileDevice() {
|
||||
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
||||
navigator.userAgent
|
||||
);
|
||||
},
|
||||
getEnumOptions() {
|
||||
// // 检查数据缓存
|
||||
// if (enumCache[this.name]) {
|
||||
// this.options = enumCache[this.name]
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // 检查是否已有相同请求在进行中
|
||||
// if (requestPromises[this.name]) {
|
||||
// requestPromises[this.name].then(data => {
|
||||
// this.options = data
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// 创建请求Promise并缓存
|
||||
requestPromises[this.name] = $.get("/open/common/dictEnumOptions", { name: this.name })
|
||||
.then(res => {
|
||||
if (res.code === 0) {
|
||||
// 存入数据缓存
|
||||
enumCache[this.name] = res.data
|
||||
// 清除请求Promise缓存
|
||||
delete requestPromises[this.name]
|
||||
return res.data
|
||||
}
|
||||
})
|
||||
|
||||
requestPromises[this.name].then(data => {
|
||||
this.options = data
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.isMobile = this.isMobileDevice()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.el-tag + .el-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.van-tag {
|
||||
height: 24px;
|
||||
padding: 0 8px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.van-tag--success {
|
||||
background-color: #f0f9eb;
|
||||
border-color: #e1f3d8;
|
||||
color: #67c23a;
|
||||
}
|
||||
.van-tag--primary {
|
||||
color: var(--color-primary);
|
||||
background-color: #ecf5ff;
|
||||
border-color: #d9ecff;
|
||||
}
|
||||
.van-tag--danger{
|
||||
background-color: #fef0f0;
|
||||
border-color: #fde2e2;
|
||||
color: #f56c6c;
|
||||
}
|
||||
.van-tag--warning{
|
||||
background-color: #fdf6ec;
|
||||
border-color: #faecd8;
|
||||
color: #e6a23c;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="pdf" id="pdf-container"></div>
|
||||
<div v-else v-html="content" class="content"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
name: "PdfIndex",
|
||||
props: {
|
||||
content: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 300,
|
||||
required: false
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pdf: true,
|
||||
pdfObj: null,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
try {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(this.content, 'text/html');
|
||||
const link = doc.querySelector('a');
|
||||
const href = link.getAttribute('href');
|
||||
if(!href) {
|
||||
this.pdf = false
|
||||
return
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.pdfObj = new Pdfh5('#pdf-container', {
|
||||
pdfurl: href,
|
||||
});
|
||||
this.pdfObj.on("complete", function () {
|
||||
const elements = document.querySelectorAll('[class*="canvasImg"]')
|
||||
let classArray = []
|
||||
elements.forEach(element => {
|
||||
classArray.push(element.getAttribute('src'))
|
||||
})
|
||||
elements.forEach((element,index) => {
|
||||
element.addEventListener('click', function() {
|
||||
vant.ImagePreview({
|
||||
images: classArray,
|
||||
startPosition: index,
|
||||
closeable: true,
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}catch (e) {
|
||||
this.pdf = false
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.content {
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="sign-container">
|
||||
<template v-if="Object.keys(res).length === 0">
|
||||
<div class="reader-container">
|
||||
<div id="reader"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="weui-msg">
|
||||
<div class="weui-msg__icon-area">
|
||||
<i v-if="res?.code !== 0" class="weui-icon-warn weui-icon_msg"></i>
|
||||
<i v-if="res?.code === 0" class="weui-icon-success weui-icon_msg"></i>
|
||||
</div>
|
||||
<div class="weui-msg__text-area">
|
||||
<div class="weui-msg__title">温馨提醒</div>
|
||||
<div v-html="res?.msg"></div>
|
||||
</div>
|
||||
<div class="weui-msg__opr-area">
|
||||
<p class="weui-btn-area">
|
||||
<a @click="res = {}; getCameras()"
|
||||
class="weui-btn weui-btn_primary">重新扫描</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
name: "scanCode",
|
||||
props: {
|
||||
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
html5QrCode: null,
|
||||
scanStatus: true,
|
||||
cameraId: '',
|
||||
res: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getCameras() {
|
||||
Html5Qrcode.getCameras()
|
||||
.then((devices) => {
|
||||
if (devices && devices.length) {
|
||||
// 如果有2个摄像头,1为前置的
|
||||
if (devices.length > 1) {
|
||||
this.cameraId = devices[1].id;
|
||||
} else {
|
||||
this.cameraId = devices[0].id;
|
||||
}
|
||||
let isHuawei = navigator.userAgent.toLowerCase().match(/huawei/i) === 'huawei';
|
||||
if(isHuawei) {
|
||||
const backCamera = devices.filter(o => o.label.includes('back'))
|
||||
this.cameraId = backCamera[0].id;
|
||||
}
|
||||
this.start();
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log(err)
|
||||
})
|
||||
},
|
||||
start() {
|
||||
this.html5QrCode = new Html5Qrcode("reader");
|
||||
this.html5QrCode.start(
|
||||
this.cameraId, // retreived in the previous step.
|
||||
{
|
||||
fps: 100, // sets the framerate to 10 frame per second,
|
||||
qrbox: {width: 1000, height: 1000}, // sets only 250 X 250 region of viewfinder to
|
||||
},
|
||||
async (decodedText, decodedResult) => {
|
||||
this.res = await this.$axios.post(decodedText)
|
||||
this.closeScan()
|
||||
},
|
||||
(errorMessage) => {
|
||||
console.log(errorMessage);
|
||||
}
|
||||
)
|
||||
.catch((err) => {
|
||||
alert(err)
|
||||
console.log(`Unable to start scanning, error: ` + err);
|
||||
});
|
||||
},
|
||||
closeScan() {
|
||||
this.html5QrCode.stop()
|
||||
.then((ignore) => {
|
||||
console.log("QR Code scanning stopped.");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Unable to stop scanning.");
|
||||
});
|
||||
},
|
||||
init() {
|
||||
this.getCameras()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sign-container{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.reader-container {
|
||||
padding-top: 50px;
|
||||
}
|
||||
#reader {
|
||||
width: 90%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
.weui-msg__icon-area {
|
||||
margin-top: 30px;
|
||||
}
|
||||
</style>
|
||||
@@ -8,6 +8,67 @@
|
||||
<script>
|
||||
const { $, BtnMenu, Panel, Tooltip } = wangEditor
|
||||
|
||||
class PDFMenu extends BtnMenu {
|
||||
constructor(editor) {
|
||||
const $elem = wangEditor.$(
|
||||
`<div class="w-e-menu" data-title="上传pdf">
|
||||
<i class="fa fa-file-pdf-o" aria-hidden="true" /></i>
|
||||
</div>`
|
||||
)
|
||||
super($elem, editor)
|
||||
}
|
||||
|
||||
clickHandler() {
|
||||
const _this = this
|
||||
const inputFileElement = document.querySelector('#'+this.editor.textElemId).parentElement.parentElement.nextElementSibling
|
||||
inputFileElement.click()
|
||||
inputFileElement.addEventListener('change', function () {
|
||||
const file = this.files[0];
|
||||
const fileName = file.name
|
||||
|
||||
if (!fileName.toLowerCase().endsWith('.pdf')) {
|
||||
alert('请上传pdf格式的文件')
|
||||
_this.clearInputFile()
|
||||
return
|
||||
}
|
||||
|
||||
const formData = new FormData()
|
||||
formData.append('file', file, file.name)
|
||||
/*axios.post("/platform/sys/file/uploadDynamicReturnUrl", formData, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
})*/
|
||||
axios.post("/platform/sys/file/uploadDynamicReturnUrl", formData, {}).then(response => {
|
||||
console.log(response.data)
|
||||
if (response.data.code === 0) {
|
||||
const html = `<a target="_blank" href="${window.location.origin}${response.data.data}">
|
||||
${file.name}
|
||||
</a>`
|
||||
_this.editor.txt.html(html)
|
||||
} else {
|
||||
alert(response.data.msg + ',上传pdf失败,请联系管理员!')
|
||||
_this.clearInputFile()
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log(error)
|
||||
_this.clearInputFile()
|
||||
alert('上传pdf失败,请联系管理员!')
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
clearInputFile() {
|
||||
const obj = document.getElementById('fileInput');
|
||||
obj.outerHTML = obj.outerHTML
|
||||
}
|
||||
|
||||
tryChangeActive() {
|
||||
this.active()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//注册上传word按钮
|
||||
class DocMenu extends BtnMenu {
|
||||
constructor(editor) {
|
||||
@@ -90,6 +151,7 @@ class DocMenu extends BtnMenu {
|
||||
}
|
||||
|
||||
wangEditor.registerMenu("docMenu", DocMenu)
|
||||
wangEditor.registerMenu('pdfMenuKey', PDFMenu)
|
||||
module.exports = {
|
||||
name: "textEditor",
|
||||
props: {
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/css/common.css" />
|
||||
<link rel="stylesheet" href="https://cdn.staticfile.net/animate.css/4.1.1/animate.css" />
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/fonts/font-awesome.min.css" />
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/css/pdf/pdfh5.css">
|
||||
<link rel="stylesheet" href="https://res.wx.qq.com/open/libs/weui/2.2.0/weui.min.css">
|
||||
|
||||
<script src="${base!}/assets/platform/plugins/vue/vue.js"></script>
|
||||
<script src="${base!}/assets/platform/plugins/vuex/vuex.js"></script>
|
||||
@@ -40,6 +42,18 @@
|
||||
<script src="${base!}/assets/platform/plugins/form-create/form-create.min.js?v=0.0.1"></script>
|
||||
<script src="${base!}/assets/platform/plugins/form-create/designer/index.umd.js"></script>
|
||||
|
||||
<!--图片预览-->
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/viewerjs/viewer.css" />
|
||||
<script src="${base!}/assets/platform/plugins/viewerjs/viewer.js"></script>
|
||||
|
||||
<!--pdf平铺展示-->
|
||||
<script src="${base!}/assets/platform/plugins/pdfJs/h5/pdf.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="${base!}/assets/platform/plugins/pdfJs/h5/pdf.worker.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="${base!}/assets/platform/plugins/pdfJs/h5/pdfh5.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!--h5扫码-->
|
||||
<script src="${base!}/assets/platform/plugins/html5-qrcode/html5-qrcode.min.js"></script>
|
||||
|
||||
<script src="${base!}/assets/platform/js/mixin/styleMixin.js"></script>
|
||||
<script src="${base!}/components/plugins/sysDict/DictData.js"></script>
|
||||
<script src="${base!}/assets/platform/js/util/commonUtil.js"></script>
|
||||
@@ -256,6 +270,9 @@
|
||||
Vue.component("svg-icon", httpVueLoader("/components/plugins/sysSvgIcon/index.vue?v=" + new Date().getTime()))
|
||||
Vue.component("year-van-dropdown-item", httpVueLoader("/components/plugins/vantMore/yearVanDropDownItem.vue?v=" + new Date().getTime()))
|
||||
Vue.component("van-text-dialog", httpVueLoader("/components/plugins/vantMore/vantTextDialog.vue?v=" + new Date().getTime()))
|
||||
Vue.component("enum-tag", httpVueLoader("/components/plugins/sysEnum/EnumTag.vue?v=" + new Date().getTime()))
|
||||
Vue.component("table-list", httpVueLoader("/components/plugins/h5/TableList.vue?v=" + new Date().getTime()))
|
||||
Vue.component("table-column", httpVueLoader("/components/plugins/h5/TableColumn.vue?v=" + new Date().getTime()))
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -47,12 +47,12 @@ layout("/layouts/platform.html"){
|
||||
<el-option v-for="item in userStateOptions" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="用人方式">
|
||||
<search-item label="聘用方式">
|
||||
<el-select v-model="pageForm.preparedBy" clearable filterable>
|
||||
<el-option v-for="item in preparedByOptions" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="教职工类别">
|
||||
<search-item label="人员类型">
|
||||
<el-select v-model="pageForm.personType" clearable filterable>
|
||||
<el-option v-for="item in personTypeOptions" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
@@ -76,9 +76,9 @@ layout("/layouts/platform.html"){
|
||||
<template slot-scope="{row}">{{$moment(row.birthday).format('YYYY-MM-DD')}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="userState" label="在职状态" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="preparedBy" label="人事编制" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="preparedBy" label="聘用方式" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="postDoctoralJoinDate" label="进站时间" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="personType" label="教职工类别" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="personType" label="人员类型" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="comeSchoolDate" label="来校年月" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="technicalTitle" label="技术职称" sortable width="120"></el-table-column>
|
||||
<el-table-column prop="position" label="干部职务" sortable width="120" show-overflow-tooltip></el-table-column>
|
||||
|
||||
@@ -85,6 +85,10 @@ layout("/layouts/platform.html"){
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<template #public>
|
||||
<member-audit-change-info ref="memberAuditChangeInfoRef" is_default_url></member-audit-change-info>
|
||||
</template>
|
||||
</guava>
|
||||
<el-dialog title="选择数据源" :visible.sync="updateDialog" width="70%">
|
||||
<el-timeline>
|
||||
@@ -125,10 +129,15 @@ layout("/layouts/platform.html"){
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include("../../../zhgh/staffmanage/member/common/audit/memberAuditChangeInfo.js"){}#-->
|
||||
|
||||
new Vue({
|
||||
el: "#app",
|
||||
dicts: ["MEMBER_CHANGE_TYPE"],
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"member-audit-change-info": MEMBER_AUDIT_CHANGE_INFO
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
updateDialog: false,
|
||||
@@ -167,8 +176,8 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
methods: {
|
||||
openCurrentUserChangeInfo(row) {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.memberAuditChangeInfoRef.onOpen({ userId: row.id, recordId: row.userHistoryId })
|
||||
this.$refs.guava.public(() => {
|
||||
this.$refs.memberAuditChangeInfoRef.onOpen({recordId: row.userHistoryId, userId: row.id})
|
||||
})
|
||||
},
|
||||
getChangeTypes(changeTypes) {
|
||||
|
||||
@@ -34,8 +34,8 @@ const ACTIVITY_CULTURE_APPLY_USER = {
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool label="活动列表">
|
||||
<el-radio-group v-model="pageForm.isEnrolled" @change="doSearch" size="mini" class="ml10">
|
||||
<el-radio-button :label="false">未报名</el-radio-button>
|
||||
<el-radio-button :label="true">已报名</el-radio-button>
|
||||
<el-radio-button :label="false">未报名</el-radio-button>
|
||||
</el-radio-group>
|
||||
</table-tool>
|
||||
|
||||
|
||||
@@ -210,8 +210,9 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
|
||||
}
|
||||
},
|
||||
openAudit(row) {
|
||||
this.$refs.guava.edit()
|
||||
this.$refs.editInfo.findOne(row.id)
|
||||
this.$refs.guava.edit(()=>{
|
||||
this.$refs.editInfo.findOne(row.id)
|
||||
})
|
||||
this.formData = {
|
||||
id: row.id,
|
||||
username: this.$store.state.user.username,
|
||||
@@ -220,8 +221,9 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
|
||||
},
|
||||
openView(row) {
|
||||
const { id } = row
|
||||
this.$refs.guava.view()
|
||||
this.$refs.infoActivity.findOne(id)
|
||||
this.$refs.guava.view(()=>{
|
||||
this.$refs.infoActivity.findOne(id)
|
||||
})
|
||||
},
|
||||
pageData() {
|
||||
this.tableLoading = true
|
||||
|
||||
@@ -42,8 +42,8 @@ const ACTIVITY_CULTURE_INFO_ACTIVITY = {
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="报名方式">
|
||||
<span v-if="viewData.signUpMethod===1">个人报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===2">分工会报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===3">组队报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===2">组队报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===3">分工会报名</span>
|
||||
<span v-else-if="!viewData.signUpMethod">无需报名</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="是否用于报名">
|
||||
|
||||
@@ -42,8 +42,8 @@ const singleSignUp = {
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="报名方式">
|
||||
<span v-if="viewData.signUpMethod===1">个人报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===2">分工会报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===3">组队报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===2">组队报名</span>
|
||||
<span v-else-if="viewData.signUpMethod===3">分工会报名</span>
|
||||
<span v-else-if="!viewData.signUpMethod">无需报名</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="是否用于报名">
|
||||
@@ -153,7 +153,47 @@ const singleSignUp = {
|
||||
</div>
|
||||
<!-- 分工会报名-->
|
||||
<div v-else-if="viewData.signUpMethod===3">
|
||||
<div class="process-title">选择报名人员
|
||||
<span v-if="viewData.userNumberLimit===2">
|
||||
,报名人数 <span style="color: red">
|
||||
{{viewData.unionTeamNum}}</span>人
|
||||
</span>
|
||||
</div>
|
||||
<el-select
|
||||
v-if="inApplyTime"
|
||||
v-model="searchTeammateUserId"
|
||||
filterable
|
||||
clearable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入关键词"
|
||||
:remote-method="queryTeammate">
|
||||
<el-option
|
||||
v-for="item in teammateOptions"
|
||||
:key="item.userId"
|
||||
:label="item.userName + '(' + item.loginName + ')'"
|
||||
:value="item.userId">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button v-if="inApplyTime" class="ml5" type="primary" icon="el-icon-plus"
|
||||
@click="addTeamUser">添加
|
||||
</el-button>
|
||||
|
||||
<el-table :data="teamUsers" class="mt10">
|
||||
<el-table-column label="序号" type="index" width="60px"></el-table-column>
|
||||
<el-table-column prop="userName" label="姓名"></el-table-column>
|
||||
<el-table-column prop="loginName" label="工号"></el-table-column>
|
||||
<el-table-column prop="sex" label="性别"></el-table-column>
|
||||
<el-table-column prop="unitName" label="单位"></el-table-column>
|
||||
<el-table-column prop="mobile" label="手机号"></el-table-column>
|
||||
<el-table-column label="操作" width="100px"
|
||||
v-if="inApplyTime">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" size="mini" @click="removeTeamUser(scope.$index)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<!-- 表单填写-->
|
||||
@@ -242,6 +282,17 @@ const singleSignUp = {
|
||||
}
|
||||
})
|
||||
},
|
||||
//查询报名人员
|
||||
listTeamUserUnion() {
|
||||
this.$axios.post("/platform/activity/culture/applyUser/listTeamUserUnion", {activityId: this.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.isSignUp = res.data.length > 0
|
||||
this.teamUsers = res.data
|
||||
this.defaultAddSelf()
|
||||
this.customFormInit()
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
//表单回显
|
||||
customFormInit() {
|
||||
@@ -300,14 +351,14 @@ const singleSignUp = {
|
||||
|
||||
//分工会
|
||||
if (this.viewData.signUpMethod === 3) {
|
||||
// if (this.teamUsers.length === 0) {
|
||||
// this.$message.warning("请添加报名人员后再提交!")
|
||||
// return
|
||||
// }
|
||||
// if (this.teamUsers.length > this.viewData.teamNum) {
|
||||
// this.$message.warning("您选择的人数大于" + this.viewData.teamNum + "人,请重新选择!")
|
||||
// return
|
||||
// }
|
||||
if (this.teamUsers.length === 0) {
|
||||
this.$message.warning("请添加报名人员后再提交!")
|
||||
return
|
||||
}
|
||||
if (this.viewData.teamNum && this.teamUsers.length > this.viewData.teamNum) {
|
||||
this.$message.warning("您选择的人数大于" + this.viewData.teamNum + "人,请重新选择!")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let formData = {
|
||||
@@ -368,7 +419,7 @@ const singleSignUp = {
|
||||
this.$message.warning("请添加报名人员后再提交!")
|
||||
return
|
||||
}
|
||||
if (this.teamUsers.length > this.viewData.teamNum) {
|
||||
if (this.viewData.teamNum && this.teamUsers.length > this.viewData.teamNum) {
|
||||
this.$message.warning("您选择的人数大于" + this.viewData.teamNum + "人,请重新选择!")
|
||||
return
|
||||
}
|
||||
@@ -420,7 +471,10 @@ const singleSignUp = {
|
||||
//查询队友信息
|
||||
queryTeammate(val) {
|
||||
if (val) {
|
||||
this.$axios.post("/platform/activity/culture/applyUser/queryTeammate", {keyword: val}).then((res) => {
|
||||
this.$axios.post("/platform/activity/culture/applyUser/queryTeammate", {
|
||||
keyword: val,
|
||||
signUpMethod: this.viewData.signUpMethod
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
res.data.map(v => v.applyUserId = this.$store.state.user.id)
|
||||
this.teammateOptions = res.data
|
||||
@@ -439,7 +493,7 @@ const singleSignUp = {
|
||||
this.$message.error("请勿重复添加")
|
||||
return
|
||||
}
|
||||
if (this.teamUsers.length >= this.viewData.teamNum) {
|
||||
if (this.viewData.teamNum && this.teamUsers.length >= this.viewData.teamNum) {
|
||||
this.$message.error("已满员")
|
||||
return
|
||||
}
|
||||
@@ -457,11 +511,22 @@ const singleSignUp = {
|
||||
this.$axios.post("/platform/activity/culture/infoManage/activityInfo", {id: this.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
//总人数限制
|
||||
if (this.viewData.userNumberLimit === 1) {
|
||||
} else if (this.viewData.userNumberLimit === 2) {
|
||||
//分工会人数限制
|
||||
const union = this.viewData.unionUserNumberLimit.find(v => v.id === this.$store.state.user.union.id)
|
||||
this.viewData.unionTeamNum = union.limitNum
|
||||
}
|
||||
if (this.viewData.signUpMethod === 3) {
|
||||
this.listTeamUserUnion()
|
||||
} else {
|
||||
this.listTeamUser()
|
||||
}
|
||||
if (this.viewData.formConfig) {
|
||||
this.formCreateRule = formCreate.parseJson(this.viewData.formConfig.rule)
|
||||
this.formCreateOption = formCreate.parseJson(this.viewData.formConfig.options)
|
||||
}
|
||||
this.listTeamUser()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -0,0 +1,341 @@
|
||||
<!--#include('signForm.js'){}#-->
|
||||
const courseList = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<!--<el-col :span="5">
|
||||
<div class="glow-box">
|
||||
<img :src="activity.cover"/>
|
||||
<div class="title">{{ activity.activityName }}</div>
|
||||
<div v-html="activity.introduce"></div>
|
||||
</div>
|
||||
</el-col>-->
|
||||
<el-col :span="24">
|
||||
<el-row class="query-row">
|
||||
<el-col class="query-title hidden-xs-only">类  型:</el-col>
|
||||
<el-col class="query-content">
|
||||
<el-select
|
||||
v-model="pageForm.courseTypeId"
|
||||
placeholder="请选择类型"
|
||||
filterable
|
||||
clearable
|
||||
style="width: 200px"
|
||||
@change="doSearch"
|
||||
>
|
||||
<el-option v-for="item in courseTypeList" :key="item.id" :label="item.typeName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="query-row" v-if="assortList && assortList.length > 0">
|
||||
<el-col class="query-title hidden-xs-only">分类标识:</el-col>
|
||||
<el-col class="query-content">
|
||||
<el-tag
|
||||
:effect="pageForm.assortTypes.includes(item) ? 'dark' : 'plain'"
|
||||
:key="item"
|
||||
:type="item"
|
||||
@click="tagClick('assortTypes', item)"
|
||||
style="margin-right: 10px; cursor: pointer"
|
||||
v-for="item in assortList"
|
||||
>
|
||||
{{ item }}
|
||||
</el-tag>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table :data="tableData" class="mt10">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:key="column.prop"
|
||||
:width="column.width"
|
||||
:sortable="column.sortable"
|
||||
align="center"
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
v-for="column in tableColumns"
|
||||
>
|
||||
<template v-slot="{row}" v-if="column.prop=='courseLocationCoordinates'">
|
||||
<el-button style="padding: 0" @click="openViewMap(row.courseLocationCoordinates)" type="text">
|
||||
{{row.courseLocation}}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template v-slot="{row}" v-else-if="column.prop=='courseTime'">
|
||||
<el-button style="padding: 0" @click="openViewCourseTime(row.id)" type="text">点击查看时间</el-button>
|
||||
</template>
|
||||
|
||||
<template v-slot="{row}" v-else-if="column.prop=='applyNum'">
|
||||
<span v-html="calcSignUpCount(row)"></span>
|
||||
</template>
|
||||
|
||||
<template v-slot="{row}" v-else-if="column.prop=='introduce'">
|
||||
<span v-if="!row.introduce?.trim()">暂无</span>
|
||||
<el-button v-else style="padding: 0" @click="onPreview(row.introduce)" type="text">点击查看</el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="{row}">
|
||||
<el-button v-if="!row.isSign" type="primary" size="mini" @click="onSign(row)">我要报名</el-button>
|
||||
<el-button v-else type="danger" size="mini" @click="onCancel(row)">取消报名</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-dialog :visible.sync="courseTimeListDialog" title="时间信息" width="60%" append-to-body>
|
||||
<el-table :data="courseTimeList">
|
||||
<el-table-column label="日期" prop="courseDate">
|
||||
<template v-slot="{row}">{{$moment(row.courseDate).format('YYYY-MM-DD')}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始时间" prop="courseStartTime">
|
||||
<template v-slot="{row}">{{$moment(row.courseStartTime).format('HH:mm')}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结束时间" prop="courseEndTime">
|
||||
<template v-slot="{row}">{{$moment(row.courseEndTime).format('HH:mm')}}</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="courseTimeListDialog = false">取 消</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="viewMapDialog" title="地点" width="60%" append-to-body>
|
||||
<div id="viewMap" style="width: 100%; height: 500px"></div>
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="viewMapDialog = false">取 消</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="infoVisible" title="详细信息" append-to-body>
|
||||
<div v-html="introduce"></div>
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="infoVisible = false">取 消</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
|
||||
<sign-form ref="signFormRef" @refresh="doSearch"></sign-form>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"sign-form": signForm,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
assortTypes: [],
|
||||
},
|
||||
assortList: [],
|
||||
courseTimeListDialog: false,
|
||||
viewMapDialog: false,
|
||||
courseTimeList: [],
|
||||
tableColumns: [
|
||||
{ prop: "courseName", label: "名称" },
|
||||
{ prop: "typeName", label: "类型", width: 130},
|
||||
{ prop: "campus", label: "校区", width: 160 },
|
||||
{ prop: "courseLocationCoordinates", label: "地点", width: 200 },
|
||||
{ prop: "courseInstructor", label: "联系人", width: 100 },
|
||||
{ prop: "courseTime", label: "时间", width: 160 },
|
||||
{ prop: "introduce", label: "详细信息", width: 100 },
|
||||
{ prop: "applyNum", label: "已报名人数", width: 200 }
|
||||
],
|
||||
activity: {},
|
||||
courseTypeList: [],
|
||||
|
||||
activityType: '',
|
||||
pdf: false,
|
||||
infoVisible: false,
|
||||
introduce: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onPreview(introduce) {
|
||||
try {
|
||||
const parser = new DOMParser();
|
||||
const doc = parser.parseFromString(introduce, 'text/html');
|
||||
const link = doc.querySelector('a');
|
||||
const href = link.getAttribute('href');
|
||||
|
||||
const id = href.substring(href.indexOf("=") + 1)
|
||||
const res = await this.$axios.post("/platform/sys/file/previewFileData", { ids: JSON.stringify([id]) })
|
||||
|
||||
this.pdf = true
|
||||
window.open("/assets/platform/plugins/pdfJs/web/viewer.html?file=" + encodeURIComponent(res.data[0].downloadPath), res.data[0].name)
|
||||
} catch (e) {
|
||||
this.introduce = introduce
|
||||
this.pdf = false
|
||||
this.infoVisible = true
|
||||
}
|
||||
},
|
||||
tagClick(key, val) {
|
||||
let idx = this.pageForm[key].indexOf(val)
|
||||
if (idx !== -1) {
|
||||
this.pageForm[key].splice(idx, 1)
|
||||
} else {
|
||||
this.pageForm[key].push(val)
|
||||
}
|
||||
this.doSearch()
|
||||
},
|
||||
async onOpen(row) {
|
||||
this.activity = row
|
||||
this.$set(this.pageForm, 'activityId', row.id)
|
||||
await this.pageData()
|
||||
await this.getCourseTypeList()
|
||||
this.queryCourseAssort()
|
||||
},
|
||||
onSign(row) {
|
||||
const courseType = this.courseTypeList.find((v) => v.id === row.courseType)
|
||||
this.$axios.post("/platform/family/apply/validateSignUp", {courseId: row.id})
|
||||
.then((res) => {
|
||||
if (res.code !== 0) {
|
||||
this.$alert(res.msg, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
} else {
|
||||
let lave = row.coursePeopleNumber - (row.hasRegisterNum + row.courseReservedNumber)
|
||||
if(row.reserveMode === 2 && lave <= 0) {
|
||||
this.$alert('您当前的报名为候补报名状态', "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
}
|
||||
this.$refs.signFormRef.onOpen(row, courseType, this.activity)
|
||||
}
|
||||
})
|
||||
},
|
||||
onCancel(row) {
|
||||
this.$confirm("您确定要取消吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "info"
|
||||
}).then(async () => {
|
||||
const resp = await this.$axios.post("/platform/family/apply/cancelSignUp", {
|
||||
activityId: row.activityId,
|
||||
courseId: row.id
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
await this.pageData()
|
||||
this.$message.success(resp.msg)
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
})
|
||||
},
|
||||
async getCourseTypeList() {
|
||||
const resp = await this.$axios.post("/platform/family/type/getAllType")
|
||||
if (resp.code === 0) {
|
||||
this.courseTypeList = resp.data
|
||||
}
|
||||
},
|
||||
async openViewCourseTime(id) {
|
||||
const resp = await this.$axios.post(loc() + "/getCourseTime", { id: id })
|
||||
this.courseTimeList = resp.data
|
||||
this.courseTimeListDialog = true
|
||||
},
|
||||
openViewMap(point) {
|
||||
if (!Array.isArray(point)) {
|
||||
this.$message.warning("没有设置点位,无法通过地图查看")
|
||||
return
|
||||
}
|
||||
this.viewMapDialog = true
|
||||
this.$nextTick(() => {
|
||||
const viewMap = new AMap.Map("viewMap", {
|
||||
resizeEnable: true,
|
||||
center: point,
|
||||
zoom: 16
|
||||
})
|
||||
if (viewMarker) {
|
||||
viewMap.remove(viewMarker)
|
||||
}
|
||||
viewMarker = new AMap.Marker({
|
||||
position: point,
|
||||
offset: new AMap.Pixel(-13, -30)
|
||||
})
|
||||
viewMap.add(viewMarker)
|
||||
viewMap.setFitView(null, false, [150, 60, 100, 60])
|
||||
})
|
||||
},
|
||||
calcSignUpCount(o) {
|
||||
let lave = o.coursePeopleNumber - (o.hasRegisterNum + o.courseReservedNumber)
|
||||
if(o.reserveMode === 2) {
|
||||
let lave2 = o.waitingNum - o.hasWaitingNum
|
||||
return "<span style='color: red'>余" + lave +"</span>/" + o.coursePeopleNumber + "人"
|
||||
+ ",<span style='color: red'>候补余" + lave2 + "</span>/" + o.waitingNum + "人"
|
||||
} else {
|
||||
return "<span style='color: red'>余" + lave +"</span>/" + o.coursePeopleNumber + "人"
|
||||
}
|
||||
},
|
||||
async pageData() {
|
||||
const pageForm = clone({...this.pageForm})
|
||||
pageForm.assortTypes = JSON.stringify(pageForm.assortTypes)
|
||||
const resp = await this.$axios.post(loc() + "/pageData", pageForm)
|
||||
if (resp.code === 0) {
|
||||
this.tableData = resp.data.list
|
||||
this.pageForm.totalCount = resp.data.totalCount
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
},
|
||||
queryCourseAssort() {
|
||||
this.$axios.post(loc() + "/queryCourseAssort", {activityId: this.activity.id})
|
||||
.then((resp) => {
|
||||
this.assortList = resp.data
|
||||
})
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.glow-box {
|
||||
min-height: calc(100vh - 56px - 40px - 50px - 80px);
|
||||
max-height: calc(100vh - 56px - 40px - 50px - 80px);
|
||||
overflow-y: auto;
|
||||
background: #F0F2F5;
|
||||
}
|
||||
img {
|
||||
width: 100%;
|
||||
height: 180px;
|
||||
}
|
||||
.title {
|
||||
background: white;
|
||||
height: 20px;
|
||||
}
|
||||
.query-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 6px 0;
|
||||
}
|
||||
.query-row:not(:last-child) {
|
||||
border-bottom: 1px dashed rgb(230, 230, 230);
|
||||
}
|
||||
.query-row > .query-title {
|
||||
width: 100px;
|
||||
max-width: 100px;
|
||||
min-width: 100px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.query-row > .query-content {
|
||||
min-width: 200px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.query-row > .query-content > .el-tag {
|
||||
margin-bottom: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
@media screen and (max-width: 992px) {
|
||||
.query-row:nth-child(4) .query-content .el-col:not(:last-child) {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.query-title {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.el-statistic {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: #000;
|
||||
font-variant: tabular-nums;
|
||||
list-style: none;
|
||||
font-feature-settings: "tnum";
|
||||
text-align: center;
|
||||
}
|
||||
.el-statistic .head {
|
||||
margin-bottom: 4px;
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
}
|
||||
.el-statistic .con {
|
||||
font-family: Sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #303133;
|
||||
}
|
||||
.el-statistic .con .number {
|
||||
font-size: 20px;
|
||||
padding: 0 4px;
|
||||
}
|
||||
.info-dialog .el-dialog__body {
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度:">
|
||||
<el-date-picker
|
||||
placeholder="选择年度"
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
v-model="pageForm.year"
|
||||
value-format="yyyy"
|
||||
@change="doSearch"
|
||||
></el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="活动状态:">
|
||||
<el-select v-model="pageForm.activityType" @change="doSearch" style="width: 100%"
|
||||
placeholder="请选择活动状态" filterable>
|
||||
<el-option :value="1" label="全部"></el-option>
|
||||
<el-option :value="4" label="即将开始"></el-option>
|
||||
<el-option :value="2" label="报名中"></el-option>
|
||||
<el-option :value="3" label="已结束"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool label="活动列表"></table-tool>
|
||||
<el-table :data="tableData" :size="tableSize">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:key="column.prop"
|
||||
:width="column.width"
|
||||
:sortable="column.sortable"
|
||||
align="center"
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
v-for="column in tableColumns"
|
||||
>
|
||||
<template v-slot="{row}" v-if="column.prop=='activitySignUpStartTime'">
|
||||
<span>{{$moment(row.activitySignUpStartTime).format('MM/DD HH:mm')}}</span>
|
||||
<span> 至 </span>
|
||||
<span>{{$moment(row.activitySignUpEndTime).format('MM/DD HH:mm')}}</span>
|
||||
</template>
|
||||
<template v-slot="{row}" v-else-if="column.prop=='activityStartTime'">
|
||||
<span>{{$moment(row.activityStartTime).format('MM/DD HH:mm')}}</span>
|
||||
<span> 至 </span>
|
||||
<span>{{$moment(row.activityEndTime).format('MM/DD HH:mm')}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="300">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="onView(row)" size="mini" type="primary">查看介绍</el-button>
|
||||
<el-button @click="onOpen(row)" size="mini" type="primary">去报名</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #view>
|
||||
<course-list ref="courseListRef"></course-list>
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
<el-dialog title="详细信息" :visible.sync="infoVisible" width="60%" class="info-dialog">
|
||||
|
||||
<activity-info ref="infoRef"></activity-info>
|
||||
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-statistic
|
||||
v-if="time < 0"
|
||||
format="DD 天 HH 时 mm 分钟 ss 秒"
|
||||
:value="new Date(infoRow.activitySignUpStartTime)"
|
||||
time-indices
|
||||
title="距离开始:"
|
||||
@finish="time = 0"
|
||||
>
|
||||
</el-statistic>
|
||||
<template v-else>
|
||||
<el-button @click="infoVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="onOpen(infoRow)" :disabled="time < 0">
|
||||
去报名
|
||||
</el-button>
|
||||
</template>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include('courseList.js'){}#-->
|
||||
<!--#include('../manage/info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"course-list": courseList,
|
||||
"activity-info": info,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
year: this.$moment().format("YYYY"),
|
||||
activityType: 4
|
||||
},
|
||||
tableColumns: [
|
||||
{ label: "活动名称", prop: "activityName", width: 600},
|
||||
{ label: "活动性质", prop: "trainType"},
|
||||
{ label: "报名时间", prop: "activitySignUpStartTime"},
|
||||
{ label: "活动时间", prop: "activityStartTime"},
|
||||
],
|
||||
time: 0,
|
||||
infoRow: {},
|
||||
infoVisible: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onView(row) {
|
||||
this.infoRow = row
|
||||
this.time = this.$moment().diff(this.$moment(row.activitySignUpStartTime), 'milliseconds')
|
||||
this.infoVisible = true
|
||||
this.$nextTick(() => {
|
||||
this.$refs.infoRef.initData(row.id)
|
||||
})
|
||||
},
|
||||
onOpen(row) {
|
||||
if(this.$moment().isBefore(this.$moment(row.activitySignUpStartTime))) {
|
||||
this.onView(row)
|
||||
return
|
||||
}
|
||||
this.infoVisible = false
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.courseListRef.onOpen(row)
|
||||
})
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.post("/platform/family/apply/activityPageData", this.pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data.list
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,420 @@
|
||||
const signForm = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-dialog :close-on-click-modal="false" :visible.sync="signDialog" title="信息填写" width="50%"
|
||||
append-to-body>
|
||||
<el-form :model="formData" ref="form" label-width="120px">
|
||||
<div class="left-span-label">个人信息</div>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="姓名" prop="username">
|
||||
<el-input readonly v-model="formData.username"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="工号" prop="loginname">
|
||||
<el-input readonly v-model="formData.loginname"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="所在单位" prop="unitName">
|
||||
<el-input readonly v-model="formData.unitName"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="所属工会" prop="unionName">
|
||||
<el-input readonly v-model="formData.unionName"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="性别" prop="sex">
|
||||
<el-input readonly v-model="formData.sex"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item label="联系方式" prop="mobile">
|
||||
<el-input v-model="formData.mobile"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-if="courseRow.courseIsLimitApply">
|
||||
<el-col :span="24">
|
||||
<el-form-item label="报名时段" prop="activityCourseId"
|
||||
:rules="{ required: true, message: '请选择报名时段', trigger: 'blur'}">
|
||||
<el-select style="width: 100%" v-model="formData.activityCourseId"
|
||||
placeholder="请选择报名时段">
|
||||
<el-option v-for="item in courseTimeSelectList"
|
||||
:label="item.text.substring(0, 12)"
|
||||
:value="item.value"
|
||||
:key="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div class="left-span-label"
|
||||
style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>家属信息</div>
|
||||
<div>
|
||||
<el-button type="danger" size="mini" @click="delFamily">
|
||||
删除家属
|
||||
</el-button>
|
||||
<el-button type="primary" size="mini" @click="addFamily">
|
||||
添加家属
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="formData.mobileColumnsValue && formData.mobileColumnsValue.length > 0">
|
||||
<el-tabs v-model="active" type="card">
|
||||
<el-tab-pane v-for="(item, index) in formData.mobileColumnsValue"
|
||||
:name="index + ''"
|
||||
:label="'家属' + (index + 1)"
|
||||
:key="index">
|
||||
<el-row class="mt20">
|
||||
<el-col :span="24">
|
||||
<el-form-item
|
||||
v-for="(column, index) in item"
|
||||
:label="column.columnName"
|
||||
:key="column.columnCode"
|
||||
:rules="{ required: column.isRequired,
|
||||
message: (['SELECT', 'FILE'].includes(column.columnFormType) ? '请选择' : '请填写') + column.columnName,
|
||||
trigger: 'blur'}"
|
||||
>
|
||||
<!--文本框-->
|
||||
<template
|
||||
v-if="!['SELECT'].includes(column.columnFormType) && ['VARCHAR','TEXT','INT'].includes(column.columnType)">
|
||||
<el-input
|
||||
v-model="column.columnValue"
|
||||
:placeholder="'请填写' + column.columnName"
|
||||
:type="['INT'].includes(column.columnType) ? 'number' : ''"
|
||||
></el-input>
|
||||
</template>
|
||||
<!--选择框-->
|
||||
<template
|
||||
v-else-if="['SELECT'].includes(column.columnFormType) && ['VARCHAR','TEXT','INT'].includes(column.columnType)">
|
||||
<el-select v-model="column.columnValue"
|
||||
:placeholder="'请选择' + column.columnName"
|
||||
style="width: 100%">
|
||||
<el-option v-for="item in column.selectValues" :key="item"
|
||||
:label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
<!--时间框-->
|
||||
<template v-else-if="['DATE', 'DATETIME'].includes(column.columnType)">
|
||||
<el-date-picker
|
||||
style="width: 100%"
|
||||
v-model="column.columnValue"
|
||||
:type="column.columnType === 'DATE' ? 'date' : 'datetime'"
|
||||
:placeholder="'请选择' + column.columnName"
|
||||
:value-format="column.columnType === 'DATE' ? 'yyyy-MM-dd' : 'yyyy-MM-dd HH:mm:ss'"
|
||||
></el-date-picker>
|
||||
</template>
|
||||
<!--文件-->
|
||||
<template v-else-if="['JSON'].includes(column.columnType)">
|
||||
<file-upload :upload_number="column.fileNumber" :value.sync="column.columnValue"
|
||||
:accept="column.fileType ? column.fileType.join(',') : ''"
|
||||
upload_result_type="url"
|
||||
complete_result upload_mode="drag"
|
||||
upload_result_category="array"></file-upload>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div v-if="formData.mobileColumnsValue.length === 0" style="text-align: center">
|
||||
<span style="font-size: 15px;color: grey">如有家属,请添加家属</span>
|
||||
</div>
|
||||
|
||||
</el-form>
|
||||
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="signDialog = false">取 消</el-button>
|
||||
<el-button @click="onSubmit" type="primary">提 交</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
store,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
signDialog: false,
|
||||
formData: {
|
||||
mobileColumnsValue: [],
|
||||
},
|
||||
courseRow: {},
|
||||
courseTypeRow: {},
|
||||
courseTimeSelectList: [],
|
||||
active: '',
|
||||
|
||||
activity: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addFamily() {
|
||||
if(this.formData.mobileColumnsValue.length >= this.activity.familyMaxCount) {
|
||||
this.$message.warning('家属最多人数为' + this.activity.familyMaxCount)
|
||||
return
|
||||
}
|
||||
const list = clone(this.courseTypeRow.familyMobileSignColumnList)
|
||||
this.formData.mobileColumnsValue.push(list)
|
||||
},
|
||||
delFamily() {
|
||||
this.formData.mobileColumnsValue.splice(this.active, 1)
|
||||
const ac = (Number(this.active) - 1)
|
||||
this.active = '' + (ac >= 0 ? ac : 0)
|
||||
},
|
||||
async validSignUp() {
|
||||
//获取家属是多少人
|
||||
const res = await this.$axios.post("/platform/family/apply/validateSignUp", {
|
||||
courseId: this.formData.courseId,
|
||||
currentFamilyNumber: this.formData.mobileColumnsValue.length || 0
|
||||
})
|
||||
if (res.code !== 0) {
|
||||
this.$alert(res.msg, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
async validateSourceSignUp() {
|
||||
if (this.courseRow.courseIsLimitApply) {
|
||||
const resp = await $.post('/platform/family/apply/validateSourceSignUp', {
|
||||
activityCourseId: this.formData.activityCourseId,
|
||||
courseId: this.courseRow.id
|
||||
})
|
||||
if (resp.code !== 0) {
|
||||
this.$alert(resp.msg, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
},
|
||||
async getCourseTimeSelectList(o) {
|
||||
const resp = await $.post('/platform/family/apply/getCourseTimeSelectList', {courseId: o.id})
|
||||
if (resp.code === 0) {
|
||||
this.courseTimeSelectList = resp.data
|
||||
} else {
|
||||
this.$message.warning('获取时段信息失败,请联系管理员')
|
||||
}
|
||||
},
|
||||
async onOpen(row, courseType, activity) {
|
||||
this.initData(row, courseType, activity)
|
||||
if (row.courseIsLimitApply) {
|
||||
await this.getCourseTimeSelectList(row)
|
||||
}
|
||||
if (courseType && courseType.familyMobileSignColumnList.length > 0) {
|
||||
courseType.familyMobileSignColumnList.forEach(item => {
|
||||
item.columnValue = ''
|
||||
})
|
||||
}
|
||||
this.courseRow = row
|
||||
this.courseTypeRow = courseType
|
||||
this.signDialog = true
|
||||
},
|
||||
validateIdCard(idCard) {
|
||||
if (!idCard) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 18位身份证号码校验
|
||||
if (idCard.length === 18) {
|
||||
const idCardRegex = /^[1-9]\d{5}(18|19|20)?\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}(\d|[Xx])$/
|
||||
if (!idCardRegex.test(idCard)) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 校验码计算
|
||||
const weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
|
||||
const checksums = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]
|
||||
let sum = 0
|
||||
for (let i = 0; i < 17; i++) {
|
||||
sum += idCard[i] * weights[i]
|
||||
}
|
||||
const checksum = checksums[sum % 11]
|
||||
return checksum === idCard[17].toUpperCase()
|
||||
}
|
||||
|
||||
// 15位身份证号码校验
|
||||
else if (idCard.length === 15) {
|
||||
const idCardRegex = /^[1-9]\d{5}\d{2}((0[1-9])|(10|11|12))(([0|1|2][0-9])|10|20|30|31)\d{3}$/
|
||||
return idCardRegex.test(idCard)
|
||||
}
|
||||
|
||||
// 外国人或其他情况
|
||||
else {
|
||||
return false
|
||||
}
|
||||
},
|
||||
validFamilyForm() {
|
||||
// 校验规则映射
|
||||
const validators = {
|
||||
idCard: (value) => this.validateIdCard(value),
|
||||
mobile: (value) => /^1[3-9]\d{9}$/.test(value),
|
||||
email: (value) => /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)
|
||||
};
|
||||
// 显示提示弹窗(直接传完整的 message)
|
||||
const showAlert = (message) => {
|
||||
this.$alert(message, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
};
|
||||
const { mobileColumnsValue } = this.formData;
|
||||
for (let i = 0; i < mobileColumnsValue.length; i++) {
|
||||
const family = mobileColumnsValue[i];
|
||||
for (const col of family) {
|
||||
const value = col.columnValue?.trim(); // 安全处理空值和空格
|
||||
// 必填校验
|
||||
if (col.isRequired && !value) {
|
||||
const message = this.activity.keyWord + (i + 1) + '的' + col.columnName + '不能为空';
|
||||
showAlert(message);
|
||||
return false;
|
||||
}
|
||||
// 格式校验
|
||||
if (col.validRule && value) {
|
||||
const validator = validators[col.validRule];
|
||||
if (validator && !validator(value)) {
|
||||
const message = this.activity.keyWord + (i + 1) + '的' + col.columnName + '格式不正确';
|
||||
showAlert(message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(col.validRule === 'idCard' && this.courseRow.familyAgeLimit) {
|
||||
const parseCard = this.parseIdCard(value)
|
||||
if(this.courseRow.minAge && parseCard.age < this.courseRow.minAge) {
|
||||
const message = '限制报名最小年龄为' + this.courseRow.minAge;
|
||||
showAlert(message);
|
||||
return false;
|
||||
|
||||
}
|
||||
if(this.courseRow.maxAge && parseCard.age > this.courseRow.maxAge) {
|
||||
const message = '限制报名最大年龄为' + this.courseRow.maxAge;
|
||||
showAlert(message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if(col.validRule === 'idCard' && this.courseRow.familySexLimit) {
|
||||
const parseCard = this.parseIdCard(value)
|
||||
if(this.courseRow.familySex && parseCard.sex !== this.courseRow.familySex) {
|
||||
const message = '限制报名性别为' + this.courseRow.familySex;
|
||||
showAlert(message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
parseIdCard(idCard) {
|
||||
if (!idCard || (idCard.length !== 18 && idCard.length !== 15)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let birthStr = '';
|
||||
let sexCode = '';
|
||||
|
||||
if (idCard.length === 15) {
|
||||
birthStr = '19' + idCard.substring(6, 12);
|
||||
sexCode = idCard.substring(14, 15); // 15位:第15位是性别
|
||||
} else {
|
||||
birthStr = idCard.substring(6, 14);
|
||||
sexCode = idCard.substring(16, 17); // 18位:第17位是性别
|
||||
}
|
||||
|
||||
const birthYear = parseInt(birthStr.substring(0, 4), 10);
|
||||
const birthMonth = parseInt(birthStr.substring(4, 6), 10) - 1;
|
||||
const birthDay = parseInt(birthStr.substring(6, 8), 10);
|
||||
|
||||
const birthDate = new Date(birthYear, birthMonth, birthDay);
|
||||
const today = new Date();
|
||||
|
||||
let age = today.getFullYear() - birthDate.getFullYear();
|
||||
const monthDiff = today.getMonth() - birthDate.getMonth();
|
||||
const dayDiff = today.getDate() - birthDate.getDate();
|
||||
|
||||
if (monthDiff < 0 || (monthDiff === 0 && dayDiff < 0)) {
|
||||
age--;
|
||||
}
|
||||
|
||||
const sex = parseInt(sexCode, 10) % 2 === 1 ? '男' : '女';
|
||||
|
||||
return { age, sex, };
|
||||
},
|
||||
async onSubmit() {
|
||||
//验证家属表单
|
||||
if (!this.validFamilyForm()) return
|
||||
if (!await this.validSignUp()) return
|
||||
if (!await this.validateSourceSignUp()) return
|
||||
this.$refs["form"].validate((valid) => {
|
||||
if (valid) {
|
||||
this.$confirm("您确定要提交吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(async () => {
|
||||
let array = []
|
||||
this.formData.mobileColumnsValue.forEach(item => {
|
||||
const o = item.map((v) => {
|
||||
return {
|
||||
columnName: v.columnName,
|
||||
columnValue: v.columnValue,
|
||||
columnCode: v.columnCode,
|
||||
columnFormType: v.columnFormType
|
||||
}
|
||||
})
|
||||
array.push(o)
|
||||
})
|
||||
this.formData.mobileColumnsValue = JSON.stringify(clone(array))
|
||||
const resp = await this.$axios.post("/platform/family/apply/doSignUp", this.formData)
|
||||
if (resp.code === 0) {
|
||||
this.$alert(resp.msg, "提示", {
|
||||
confirmButtonText: "确定",
|
||||
type: "warning"
|
||||
})
|
||||
this.signDialog = false
|
||||
this.$emit('refresh')
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
initData(row, courseType, activity) {
|
||||
this.activity = activity
|
||||
this.formData = {
|
||||
activityId: row.activityId,
|
||||
courseId: row.id,
|
||||
username: this.$store.state.user.username,
|
||||
loginname: this.$store.state.user.loginname,
|
||||
unionName: this.$store.state.user.union.name,
|
||||
unitName: this.$store.state.user.unit.name,
|
||||
sex: this.$store.state.user.sex,
|
||||
mobile: this.$store.state.user.mobile,
|
||||
mobileColumnsValue: [],
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.$refs.form.clearValidate()
|
||||
})
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
::v-deep .el-tabs__header {
|
||||
margin: 0 0 15px !important;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,651 @@
|
||||
<!--#include('courseTime.js'){}#-->
|
||||
<!--#include('customForm.js'){}#-->
|
||||
const basicForm = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-form :model="formData" label-width="110px" ref="form">
|
||||
<div v-show="step === 1">
|
||||
<el-row :gutter="20" type="flex" v-if="!formData.id">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="沿用活动" prop="useHistory">
|
||||
<el-radio-group v-model="formData.useHistory" size="small">
|
||||
<el-radio :label="true" border>沿用之前活动</el-radio>
|
||||
<el-radio :label="false" border>不沿用之前活动</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="formData.useHistory">
|
||||
<el-form-item label="往期活动" prop="historicalAct">
|
||||
<el-select v-model="formData.historicalAct" placeholder="请选择往期活动" style="width: 100%" @change="historicalActChange">
|
||||
<el-option v-for="item in historicalActList" :key="item.id" :label="item.activityName" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col :span="12">
|
||||
<el-form-item :rules="{required:true,message: '请输入活动名称', trigger: 'blur'}" label="活动名称" prop="activityName">
|
||||
<el-input maxlength="50" v-model="formData.activityName" placeholder="请输入活动名称"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item :label="activityType + '通知'" prop="notice">
|
||||
<el-radio-group v-model="formData.notice" size="small">
|
||||
<el-radio :label="true" border>通知</el-radio>
|
||||
<el-radio :label="false" border>不通知</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col :span="12">
|
||||
<el-form-item :rules="{required:true,message: '请选择活动时间', trigger: 'blur'}" label="活动时间" prop="activityTime">
|
||||
<el-date-picker
|
||||
:picker-options="pickerOptions"
|
||||
end-placeholder="请选择活动结束日期"
|
||||
range-separator="至"
|
||||
start-placeholder="请选择活动开始日期"
|
||||
style="width: 100%"
|
||||
type="datetimerange"
|
||||
v-model="formData.activityTime"
|
||||
value-format="yyyy-MM-dd HH:mm"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item :rules="{required:true,message: '请选择报名时间', trigger: 'blur'}" label="报名时间" prop="activitySignTime">
|
||||
<el-date-picker
|
||||
:disabled="false"
|
||||
end-placeholder="请选择报名结束日期"
|
||||
range-separator="至"
|
||||
start-placeholder="请选择报名开始日期"
|
||||
style="width: 100%"
|
||||
type="datetimerange"
|
||||
v-model="formData.activitySignTime"
|
||||
value-format="yyyy-MM-dd HH:mm"
|
||||
></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="面向对象" prop="joinCnd">
|
||||
<div style="display: flex; justify-content: space-between">
|
||||
<div style="width: 99%">
|
||||
<el-select
|
||||
@change="changeActivity"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择可报名人员范围"
|
||||
style="width: 99%"
|
||||
v-model="formData.activityGroupId"
|
||||
>
|
||||
<el-option
|
||||
:key="item.groupId"
|
||||
:label="item.groupName"
|
||||
:value="item.groupId"
|
||||
v-for="item in activityGroupList"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<div>
|
||||
<el-button @click="$refs.drawerUserScope.userScopeDialog = true" type="primary">设置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="活动类型" prop="trainType" :rules="{required:true,message: '请选择活动类型', trigger: 'blur'}">
|
||||
<el-select @change="typeChange" filterable placeholder="请选择活动类型" style="width: 100%" v-model="formData.trainType">
|
||||
<el-option :label="item.name" :value="item.code" :key="item.code" v-for="item in dict.type.FAMILY_SIGNUP_TYPE"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20" type="flex">
|
||||
<el-col :span="12">
|
||||
<el-form-item :rules="{required:true,message: '请输入关键词', trigger: 'blur'}" label="关键词" prop="keyWord">
|
||||
<el-input maxlength="50" v-model="formData.keyWord" placeholder="请输入关键词"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item :rules="{required:true,message: '请输入家属最多数', trigger: 'blur'}" label="家属最多数" prop="familyMaxCount">
|
||||
<el-input maxlength="50" v-model="formData.familyMaxCount" placeholder="请输入家属最多数" type="number"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item :rules="{required:true,message: '请输入活动介绍', trigger: 'blur'}" label="活动介绍" prop="introduce">
|
||||
<text-editor v-model="formData.introduce"></text-editor>
|
||||
</el-form-item>
|
||||
<el-form-item label="封面图片" prop="cover" :rules="{required:true,message: '请上传活动移动端封面图片', trigger: 'blur'}">
|
||||
<el-col :span="12">
|
||||
<file-upload
|
||||
:upload_number="1"
|
||||
:value.sync="formData.cover"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
complete_result
|
||||
upload_mode="image"
|
||||
upload_result_category="interval"
|
||||
></file-upload>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="微信群二维码" prop="wechat">
|
||||
<file-upload
|
||||
:upload_number="1"
|
||||
:value.sync="formData.wechat"
|
||||
accept=".jpg,.jpeg,.png"
|
||||
complete_result
|
||||
upload_mode="image"
|
||||
upload_result_category="interval"
|
||||
></file-upload>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div v-show="step === 2">
|
||||
<div class="left-span-label" style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>{{activityType + '信息(温馨提示:如不需要人数限制,下方人数框填写0或者不填)'}}</div>
|
||||
<div>
|
||||
<el-button @click="addCourse" size="mini" type="primary">添加{{ activityType }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="formData.courseList">
|
||||
<el-table-column label="序号" prop="orderNum" width="100px">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number
|
||||
v-model="row.orderNum"
|
||||
@change="courseOrderNumChange"
|
||||
:min="1"
|
||||
:max="formData.courseList.length"
|
||||
:step="1"
|
||||
step-strictly
|
||||
:precision="0"
|
||||
controls-position="right"
|
||||
style="width: 76px"
|
||||
size="small"
|
||||
label="序号"
|
||||
></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="activityType + '名称'" prop="courseName">
|
||||
<template v-slot="{row}">
|
||||
<el-input size="small" v-model="row.courseName" :placeholder="'请输入' + activityType + '名称'"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="类型" prop="courseType" sortable>
|
||||
<template v-slot="{row}">
|
||||
<el-select size="small" v-model="row.courseType" @change="(val) => {courseTypeChange(val, row)}">
|
||||
<el-option :label="c.typeName" :value="c.id" :key="c.id" v-for="c in courseTypeList"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="activityType + '人数'" prop="coursePeopleNumber" width="110px">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
:max="9999"
|
||||
size="small"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
step-strictly
|
||||
style="max-width: 80px"
|
||||
@change="(c, o) => validNumber(row, null)"
|
||||
v-model="row.coursePeopleNumber"
|
||||
placeholder="请输入人数"
|
||||
></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预留名额" prop="courseReservedNumber" width="110px">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number
|
||||
:controls="false"
|
||||
:max="1000"
|
||||
:min="0"
|
||||
size="small"
|
||||
:precision="0"
|
||||
step-strictly
|
||||
style="max-width: 80px"
|
||||
@change="(c, o) => validNumber(row, o)"
|
||||
v-model="row.courseReservedNumber"
|
||||
placeholder="请输入预留名额"
|
||||
></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="校区" prop="campus">
|
||||
<template v-slot="{row}">
|
||||
<el-select size="small" v-model="row.campus" style="width: 100%">
|
||||
<el-option :label="item.name" :value="item.name" :key="item.code" v-for="item in dict.type.CAMPUS"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="activityType + '地点'" prop="courseLocation">
|
||||
<template v-slot="{row}">
|
||||
<el-input size="small" v-model="row.courseLocation" :placeholder="'请输入' + activityType + '地点'"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="activityType + '负责人'" prop="courseInstructor">
|
||||
<template v-slot="{row}">
|
||||
<el-input size="small" v-model="row.courseInstructor" :placeholder="'请输入' + activityType + '负责人'"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="分类标识" prop="assort">
|
||||
<template v-slot="{row}">
|
||||
<el-input size="small" v-model="row.assort" placeholder="请输入分类标识"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column :label="activityType + '时间'">
|
||||
<template v-slot="scope">
|
||||
<el-button @click="openSetUpCourseTime(scope.$index)" type="text">设置{{ activityType }}时间</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="scope">
|
||||
<el-button @click="openMoreInfo(scope, scope.$index)" size="mini" type="primary">自定义设置</el-button>
|
||||
<el-button @click="removeTableCourse(scope.$index)" size="mini" type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="left-span-label" style="margin-top: 20px">个人报名数量限制</div>
|
||||
<el-form-item label="报名数量限制" prop="cover">
|
||||
<el-radio-group v-model="formData.restrictLimit" size="small">
|
||||
<el-radio border :label="1">无限制</el-radio>
|
||||
<el-radio border :label="2">按类型限制</el-radio>
|
||||
<el-radio border :label="3">按活动限制</el-radio>
|
||||
</el-radio-group>
|
||||
<div calss="limit_div">
|
||||
<div v-if="formData.restrictLimit === 1" style="color: #c64120; font-size: 12px">注:无限制指对报名的个数不做任何限制</div>
|
||||
<div v-if="formData.restrictLimit === 2" style="color: #c64120; font-size: 12px">
|
||||
<div>
|
||||
<el-button @click="setSignUpCondition" size="mini" type="primary">设置报名限制</el-button>
|
||||
<span style="color: #c64120; font-size: 12px">注:按类型限制指对每个类型下的个数进行限制</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="formData.restrictLimit === 3">
|
||||
<div>
|
||||
<el-input-number v-model="formData.limitNum" :min="1" :max="100" size="mini" label="限制报名个数"></el-input-number>
|
||||
<span style="color: #c64120; font-size: 12px">注:按活动限制指只能报{{formData.limitNum}}个,不与类型关联</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<div class="left-span-label" style="margin-top: 20px">判断家属数量唯一标识</div>
|
||||
<el-form-item label="唯一标识" prop="onlyKey">
|
||||
<el-select @focus="keyFocus" v-model="formData.onlyKey" placeholder="请选择唯一标识">
|
||||
<el-option v-for="item in typeArray" :key="item.columnCode" :label="item.columnName" :value="item.columnCode"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
<div style="float: right; margin: 20px 0">
|
||||
<el-button @click="$emit('back')">取消</el-button>
|
||||
<el-button v-if="step === 2" type="primary" @click="step = 1">上一步</el-button>
|
||||
<el-button v-if="step === 1" type="primary" @click="step = 2">下一步</el-button>
|
||||
<el-button type="primary" @click="onSave">保存</el-button>
|
||||
<el-button type="primary" @click="onSubmit">提交</el-button>
|
||||
</div>
|
||||
|
||||
<el-dialog :close-on-click-modal="false" :visible.sync="signUpDialog" title="设置报名限制" append-to-body>
|
||||
<el-table :data="formData.typeLimits">
|
||||
<el-table-column prop="code" label="类型编码"></el-table-column>
|
||||
<el-table-column prop="typeName" label="类型名称"></el-table-column>
|
||||
<el-table-column label="限制个数" width="500">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number size="small" v-model="row.limitNum" :min="0"></el-input-number>
|
||||
<span style="color: #c64120; font-size: 12px">注:值为空或者为0则表示此类型不限制报名个数</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="signUpDialog = false">取消</el-button>
|
||||
<el-button @click="doLimitNum" type="primary">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
|
||||
<drawer-user-scope
|
||||
@group_change="getActivityGroup"
|
||||
ref="drawerUserScope"
|
||||
:group_id.sync="formData.activityGroupId">
|
||||
</drawer-user-scope>
|
||||
|
||||
<course-time ref="courseTimeRef"></course-time>
|
||||
<custom-form ref="customFormRef"></custom-form>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["CAMPUS", "FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
signUpDialog: false,
|
||||
step: 1,
|
||||
formData: {
|
||||
notice: false,
|
||||
courseList: [
|
||||
{
|
||||
orderNum: 1,
|
||||
courseName: "",
|
||||
courseTimeList: [],
|
||||
isMobileSign: false,
|
||||
isReceiveGift: false,
|
||||
reserveMode: 1,
|
||||
courseIsLimitApply: false,
|
||||
familyAgeLimit: false,
|
||||
familySexLimit: false,
|
||||
},
|
||||
],
|
||||
conditionStructure: {
|
||||
method: "AND",
|
||||
conditions: [{}]
|
||||
},
|
||||
restrictLimit: 1,
|
||||
limitNum: 1,
|
||||
typeLimits: [],
|
||||
keyWord: '家属'
|
||||
},
|
||||
historicalActList: [],
|
||||
trainTypeList: [],
|
||||
activityType: "子活动",
|
||||
activityGroupList: [],
|
||||
pickerOptions: {
|
||||
disabledDate(time) {
|
||||
return time.getTime() < Date.now() - 24 * 60 * 60 * 1000
|
||||
}
|
||||
},
|
||||
campusList: [],
|
||||
courseTypeList: [],
|
||||
|
||||
typeArray: [],
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"drawer-user-scope": httpVueLoader("/components/module/activity/DrawerUserScope.vue"),
|
||||
"course-time": courseTime,
|
||||
"custom-form": customForm,
|
||||
},
|
||||
methods: {
|
||||
keyFocus() {
|
||||
const types = this.formData.courseList.filter(o => o.courseType !== undefined).map(o => o.courseType)
|
||||
if(types.length === 0) {
|
||||
this.$message.warning('请先设置' + this.activityType + '类型')
|
||||
return
|
||||
}
|
||||
const typeList = this.courseTypeList.filter(o => types.includes(o.id))
|
||||
let array = []
|
||||
typeList.forEach(item => {
|
||||
array = array.concat(item.familyMobileSignColumnList)
|
||||
})
|
||||
this.typeArray = array
|
||||
},
|
||||
async validNumber(row, old) {
|
||||
if (GetQueryString("id") === "") {
|
||||
if (row.courseReservedNumber > row.coursePeopleNumber && row.reserveMode === 1) {
|
||||
this.$alert("预留人数不能大于" + this.activityType + "人数!", "提示", {
|
||||
confirmButtonText: "确定"
|
||||
})
|
||||
row.courseReservedNumber = 0
|
||||
}
|
||||
} else {
|
||||
const registerUserCount = await this.getRegisterUserCount(row.id)
|
||||
if (row.courseReservedNumber + registerUserCount > row.coursePeopleNumber) {
|
||||
if (row.reserveMode === 1) {
|
||||
let num = row.coursePeopleNumber - registerUserCount
|
||||
let str =
|
||||
"您设置的" +
|
||||
this.activityType +
|
||||
"人数为" +
|
||||
row.coursePeopleNumber +
|
||||
"人,当前报名人数为" +
|
||||
registerUserCount +
|
||||
"人,预留名额上限为" +
|
||||
num +
|
||||
"人!"
|
||||
this.$alert(str, "提示", {
|
||||
confirmButtonText: "确定"
|
||||
})
|
||||
row.courseReservedNumber = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
async getRegisterUserCount(courseId) {
|
||||
const resp = await this.$axios.post("/platform/family/manage/getRegisterUserCount", { courseId })
|
||||
return resp.code === 0 ? resp.data : 0
|
||||
},
|
||||
courseTypeChange(val, row) {
|
||||
row.reserveMode = 1
|
||||
},
|
||||
setSignUpCondition() {
|
||||
if (this.formData.courseList !== undefined && this.formData.courseList.length > 0) {
|
||||
const courseValid = this.formData.courseList.some((item, index) => {
|
||||
if (item.courseType === undefined) {
|
||||
this.$message.warning("请在" + (index + 1) + "行" + this.activityType + "信息中选择类型!")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
if (courseValid) {
|
||||
return
|
||||
}
|
||||
const array = [...new Set(this.formData.courseList.map((o) => o.courseType))]
|
||||
const typeArray = clone([...this.courseTypeList].filter((x) => array.some((y) => x.id === y)))
|
||||
const arr = []
|
||||
typeArray.forEach((item) => {
|
||||
const t = this.formData.typeLimits.find(o => o.typeId === item.id)
|
||||
if (t) {
|
||||
const type = this.courseTypeList.find(o => o.id === t.typeId)
|
||||
t.code = type.code
|
||||
t.typeName = type.typeName
|
||||
arr.push(t)
|
||||
} else {
|
||||
arr.push({
|
||||
code: item.code,
|
||||
typeName: item.typeName,
|
||||
typeId: item.id,
|
||||
limitNum: 0
|
||||
})
|
||||
}
|
||||
})
|
||||
this.formData.typeLimits = arr
|
||||
this.signUpDialog = true
|
||||
} else {
|
||||
this.$message.warning("请在" + this.activityType + "信息中选择类型!")
|
||||
}
|
||||
},
|
||||
doLimitNum() {
|
||||
this.signUpDialog = false
|
||||
},
|
||||
openMoreInfo(row, index) {
|
||||
this.$refs.customFormRef.onOpen(this.formData, row, index)
|
||||
},
|
||||
async removeTableCourse(index) {
|
||||
const confirm = await this.$confirm(
|
||||
"请确认是否删除此" + this.activityType + "?如果该" + this.activityType + "已有报名人员,会随之一起删除!确定吗?",
|
||||
"提示",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}
|
||||
)
|
||||
if (confirm) {
|
||||
this.formData.courseList.splice(index, 1)
|
||||
}
|
||||
},
|
||||
openSetUpCourseTime(index) {
|
||||
this.$refs.courseTimeRef.onOpen(this.formData, index)
|
||||
},
|
||||
courseOrderNumChange() {
|
||||
this.formData.courseList = this.formData.courseList.sort((a, b) => a.orderNum - b.orderNum)
|
||||
},
|
||||
addCourse() {
|
||||
this.formData.courseList.push({ courseTimeList: [], isMobileSign: false, isReceiveGift: false, reserveMode: 1, courseIsLimitApply: false })
|
||||
},
|
||||
async historicalActChange(val) {
|
||||
const resp = await this.$axios.post("/platform/family/manage/findOne", {id: val})
|
||||
if (resp.code === 0) {
|
||||
this.formData = resp.data
|
||||
this.typeChange(this.formData.trainType)
|
||||
this.formData.id = ""
|
||||
}
|
||||
},
|
||||
typeChange(val) {
|
||||
const type = this.dict.type.FAMILY_SIGNUP_TYPE.find(o => o.code === val)
|
||||
this.activityType = type?.name || "子活动"
|
||||
},
|
||||
changeActivity(val) {
|
||||
if (val) {
|
||||
const group = this.activityGroupList.find(v => v.groupId === val)
|
||||
this.$set(this.formData, "activityGroupName", group.groupName)
|
||||
} else {
|
||||
this.$set(this.formData, "activityGroupName", "全部教职工")
|
||||
}
|
||||
},
|
||||
async getActivityGroup() {
|
||||
const { data } = await this.$axios.post("/platform/activity/basic/scope/getActivityUserScopeGroup")
|
||||
return data
|
||||
},
|
||||
async getHistoricalActList() {
|
||||
const resp = await this.$axios.post("/platform/family/manage/getHistoricalActList", {})
|
||||
return resp.data
|
||||
},
|
||||
async onSave() {
|
||||
let valid = false
|
||||
this.$refs.form.validateField("activityName", (errMsg) => {
|
||||
valid = errMsg === ""
|
||||
})
|
||||
if (!valid) {
|
||||
this.$message.warning("请输入活动名称")
|
||||
return
|
||||
}
|
||||
await this.doHandle('保存')
|
||||
},
|
||||
onSubmit() {
|
||||
this.$refs["form"].validate(async (valid, errMsg) => {
|
||||
if (valid) {
|
||||
const courseValid = this.formData.courseList.some((v, i) => {
|
||||
const basicValid = v.courseName && v.coursePeopleNumber && v.courseLocation && v.courseInstructor && v.courseType
|
||||
const timeValid =
|
||||
v.courseTimeList.length > 0 &&
|
||||
v.courseTimeList.every((x) => {
|
||||
return x.courseStartTime && x.courseEndTime && x.courseStartTime < x.courseEndTime
|
||||
})
|
||||
if (!timeValid) {
|
||||
this.$message.warning("第" + (i + 1) + "行时间填写有误,请核查")
|
||||
return true
|
||||
}
|
||||
if (!basicValid) {
|
||||
this.$message.warning("第" + (i + 1) + "行信息填写有误,请核查")
|
||||
return true
|
||||
}
|
||||
if (v.isMobileSign === true && v.signType === 3 && (v.courseLocationCoordinates === undefined || v.courseLocationCoordinates.length < 2)) {
|
||||
this.$message.warning("第" + (i + 1) + "行地点坐标填写有误,请核查")
|
||||
return true
|
||||
}
|
||||
if (v.isMobileSign === true && v.signType === 3 && (v.signType === "" || v.signType === undefined)) {
|
||||
this.$message.warning("第" + (i + 1) + "行签到方式填写有误,请核查")
|
||||
return true
|
||||
}
|
||||
if(v.familyAgeLimit === true && !v.minAge) {
|
||||
this.$message.warning("第" + (i + 1) + "行最小年龄不能为空,请核查")
|
||||
return true
|
||||
}
|
||||
if(v.familyAgeLimit === true && !v.maxAge) {
|
||||
this.$message.warning("第" + (i + 1) + "行最大年龄不能为空,请核查")
|
||||
return true
|
||||
}
|
||||
if(v.familySexLimit === true && !v.familySex) {
|
||||
this.$message.warning("第" + (i + 1) + "行性别不能为空,请核查")
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
if (courseValid) return
|
||||
if (this.formData.restrictLimit === 2 && this.formData.typeLimits.length === 0) {
|
||||
this.$message.warning("请设置报名限制")
|
||||
return
|
||||
}
|
||||
this.formData.isDisabled = false
|
||||
await this.doHandle('提交')
|
||||
} else {
|
||||
if(Object.keys(errMsg).length > 0) {
|
||||
this.$message.warning(errMsg[Object.keys(errMsg)[0]][0].message)
|
||||
return
|
||||
}
|
||||
this.$message.warning("存在必填项未填写")
|
||||
}
|
||||
})
|
||||
},
|
||||
async doHandle(type) {
|
||||
const cloneData = clone(this.formData)
|
||||
cloneData.activitySignUpStartTime = cloneData.activitySignTime !== undefined ? cloneData.activitySignTime[0] : null
|
||||
cloneData.activitySignUpEndTime = cloneData.activitySignTime !== undefined ? cloneData.activitySignTime[1] : null
|
||||
cloneData.activityStartTime = cloneData.activityTime !== undefined ? cloneData.activityTime[0] : null
|
||||
cloneData.activityEndTime = cloneData.activityTime !== undefined ? cloneData.activityTime[1] : null
|
||||
if (cloneData.activityStartTime !== undefined && cloneData.activityStartTime !== null) {
|
||||
cloneData.year = new Date(cloneData.activityStartTime).getFullYear()
|
||||
}
|
||||
cloneData.typeLimits = JSON.stringify(this.formData.typeLimits)
|
||||
cloneData.courseList = JSON.stringify(cloneData.courseList)
|
||||
const confirm = await this.$confirm("您确定要" + type + "吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
if (confirm !== "confirm") return
|
||||
const resp = await this.$axios.post("/platform/family/manage/doHandle", cloneData)
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.step = 1
|
||||
this.$emit('refresh')
|
||||
this.$emit('back')
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
},
|
||||
async getAllType() {
|
||||
const resp = await this.$axios.post("/platform/family/type/getAllType", {})
|
||||
return resp.data
|
||||
},
|
||||
async init(row) {
|
||||
if (row && row.id) {
|
||||
const resp = await this.$axios.post("/platform/family/manage/findOne", {id: row.id})
|
||||
if (resp.code === 0) {
|
||||
this.formData = resp.data
|
||||
this.typeChange(this.formData.trainType)
|
||||
if(this.formData.onlyKey) this.keyFocus()
|
||||
}
|
||||
}
|
||||
},
|
||||
async initData(row) {
|
||||
this.activityGroupList = await this.getActivityGroup()
|
||||
this.historicalActList = await this.getHistoricalActList()
|
||||
this.courseTypeList = await this.getAllType()
|
||||
await this.init(row)
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
'formData.restrictLimit'(val) {
|
||||
if (!this.formData.id) {
|
||||
this.formData.limitNum = val === 3 ? 1 : ''
|
||||
}
|
||||
},
|
||||
'formData.activityGroupId': {
|
||||
async handler(newVal, oldVal) {
|
||||
this.activityGroupList = await this.getActivityGroup()
|
||||
this.userScopeDialog = false
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
const courseTime = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-dialog :close-on-click-modal="false" :visible.sync="setUpCourseDialog" title="设置时间" width="60%" append-to-body>
|
||||
<div style="color: red; margin-bottom: 10px">温馨提示:有人员报名后,禁止修改下列时间,如有修改,请联系管理员</div>
|
||||
<div class="left-span-label">选择日期</div>
|
||||
<el-date-picker
|
||||
v-if="formData.courseList && formData.courseList[courseIndex]"
|
||||
:picker-options="setUpCoursePickerOptions"
|
||||
@change="setUpCourseDataChange"
|
||||
placeholder="选择一个或多个日期"
|
||||
style="width: 100%"
|
||||
type="dates"
|
||||
v-model="formData.courseList[courseIndex].setUpCourseData"
|
||||
value-format="yyyy-MM-dd"
|
||||
></el-date-picker>
|
||||
<div class="left-span-label">设置时间</div>
|
||||
<el-row style="margin-bottom: 10px">
|
||||
<el-time-select
|
||||
:picker-options="{
|
||||
start: '08:30',
|
||||
step: '00:05',
|
||||
end: '23:30'
|
||||
}"
|
||||
placeholder="开始时间"
|
||||
size="mini"
|
||||
v-model="courseTimeOneKeySet.startTime"
|
||||
></el-time-select>
|
||||
<el-time-select
|
||||
:picker-options="{
|
||||
start: '08:30',
|
||||
step: '00:05',
|
||||
end: '23:30'
|
||||
}"
|
||||
placeholder="结束时间"
|
||||
size="mini"
|
||||
v-model="courseTimeOneKeySet.endTime"
|
||||
></el-time-select>
|
||||
<el-button @click="oneKeySetStartEndTime" size="mini" type="primary">一键设置开始/结束时间</el-button>
|
||||
<span style="color: #ac3111">报名人数是否限制:</span>
|
||||
<el-radio-group size="mini" v-model="formData.courseList[courseIndex].courseIsLimitApply">
|
||||
<el-radio-button :label="true">是</el-radio-button>
|
||||
<el-radio-button :label="false">否</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-row>
|
||||
|
||||
<el-table v-if="formData.courseList && formData.courseList[courseIndex]"
|
||||
:data="formData.courseList[courseIndex].courseTimeList">
|
||||
<el-table-column label="日期">
|
||||
<template v-slot="{row}">
|
||||
<i class="el-icon-time"></i>
|
||||
{{$moment(row.courseDate).format('YYYY-MM-DD')}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始时间">
|
||||
<template v-slot="{row}">
|
||||
<el-time-select
|
||||
:picker-options="{
|
||||
start: '08:30',
|
||||
step: '00:05',
|
||||
end: '23:30'
|
||||
}"
|
||||
placeholder="开始时间"
|
||||
style="width: 100%"
|
||||
v-model="row.courseStartTime"
|
||||
></el-time-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="结束时间">
|
||||
<template v-slot="{row}">
|
||||
<el-time-select
|
||||
:picker-options="{
|
||||
start: '08:30',
|
||||
step: '00:05',
|
||||
end: '23:30'
|
||||
}"
|
||||
placeholder="结束时间"
|
||||
style="width: 100%"
|
||||
v-model="row.courseEndTime"
|
||||
></el-time-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<template v-if="formData.courseList[courseIndex].courseIsLimitApply">
|
||||
<el-table-column label="人数限制">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number v-model="row.courseLimitNum" :min="1" :max="1000"
|
||||
style="width: 100%"
|
||||
placeholder="限制报名个数"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="{row,$index}">
|
||||
<el-button
|
||||
@click="formData.courseList[courseIndex].courseTimeList.splice($index,0,{courseDate:row.courseDate,courseStartTime:'',courseEndTime:''})"
|
||||
size="small"
|
||||
>
|
||||
新增同天时段
|
||||
</el-button>
|
||||
<el-button @click="removeSetUpTableCourseRow(row,$index)" size="small" type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<el-button @click="doConfirmSetUpCourse" type="primary">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
const that = this
|
||||
return {
|
||||
setUpCourseDialog: false,
|
||||
courseIndex: 0,
|
||||
formData: {},
|
||||
courseTimeOneKeySet: {
|
||||
startTime: "",
|
||||
endTime: ""
|
||||
},
|
||||
setUpCoursePickerOptions: {
|
||||
disabledDate(time) {
|
||||
return (
|
||||
time.getTime() < Date.parse(that.$moment(that.formData.activityTime[0]).format("YYYY-MM-DD") + " 00:00:00") ||
|
||||
time.getTime() > Date.parse(that.$moment(that.formData.activityTime[1]).format("YYYY-MM-DD") + " 00:00:00")
|
||||
)
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
removeSetUpTableCourseRow(row, index) {
|
||||
this.formData.courseList[this.courseIndex].courseTimeList.splice(index, 1)
|
||||
//培训时间列表日期数组
|
||||
const courseDateArray = this.formData.courseList[this.courseIndex].courseTimeList.map((v) =>
|
||||
this.$moment(v.courseDate).format("YYYY-MM-DD")
|
||||
)
|
||||
//选择课程日期数组
|
||||
const scdList = this.formData.courseList[this.courseIndex].setUpCourseData
|
||||
|
||||
this.formData.courseList[this.courseIndex].setUpCourseData = scdList.filter((v) => {
|
||||
return courseDateArray.includes(this.$moment(v).format("YYYY-MM-DD"))
|
||||
})
|
||||
},
|
||||
oneKeySetStartEndTime() {
|
||||
const { startTime, endTime } = this.courseTimeOneKeySet
|
||||
this.formData.courseList[this.courseIndex].courseTimeList.forEach((v) => {
|
||||
this.$set(v, "courseStartTime", startTime)
|
||||
this.$set(v, "courseEndTime", endTime)
|
||||
})
|
||||
this.$forceUpdate()
|
||||
},
|
||||
setUpCourseDataChange(val) {
|
||||
if (!val) {
|
||||
this.formData.courseList[this.courseIndex].courseTimeList = []
|
||||
return
|
||||
}
|
||||
//培训时间日期Set
|
||||
if (this.formData.courseList[this.courseIndex].courseTimeList === undefined) {
|
||||
this.$set(this.formData.courseList[this.courseIndex], "courseTimeList", [])
|
||||
}
|
||||
const ctList = new Set(
|
||||
this.formData.courseList[this.courseIndex].courseTimeList.map((v) => this.$moment(v.courseDate).format("YYYY-MM-DD"))
|
||||
)
|
||||
val.forEach((v) => {
|
||||
if (!ctList.has(v)) {
|
||||
this.formData.courseList[this.courseIndex].courseTimeList.push({
|
||||
courseDate: v,
|
||||
courseTime: null
|
||||
})
|
||||
}
|
||||
})
|
||||
this.formData.courseList[this.courseIndex].courseTimeList = this.formData.courseList[this.courseIndex].courseTimeList.filter((v) => {
|
||||
return val.includes(this.$moment(v.courseDate).format("YYYY-MM-DD"))
|
||||
})
|
||||
this.formData.courseList[this.courseIndex].courseTimeList.sort((a, b) => {
|
||||
return Date.parse(a["courseDate"]) - Date.parse(b["courseDate"])
|
||||
})
|
||||
},
|
||||
//设置课程时间确定
|
||||
doConfirmSetUpCourse() {
|
||||
const courseTableData = this.formData.courseList[this.courseIndex].courseTimeList
|
||||
if (courseTableData.length === 0) {
|
||||
this.$message.warning("请填写时间!")
|
||||
return
|
||||
}
|
||||
if (courseTableData && courseTableData.length > 0) {
|
||||
const valid = courseTableData.every((v) => v.courseStartTime && v.courseEndTime && v.courseStartTime < v.courseEndTime)
|
||||
if (!valid) {
|
||||
this.$message.warning("时间填写不完整或者有误!")
|
||||
return
|
||||
}
|
||||
this.setUpCourseDialog = false
|
||||
}
|
||||
},
|
||||
onOpen(formData, index) {
|
||||
this.formData = formData
|
||||
this.courseIndex = index
|
||||
if (!this.formData.activityTime || this.formData.activityTime.length === 0) {
|
||||
this.$message.warning("请先设置活动起止时间")
|
||||
return
|
||||
}
|
||||
this.courseIndex = index
|
||||
this.setUpCourseDialog = true
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if(!this.formData.courseList) {
|
||||
this.formData = {courseList: [{unionLimit: []}]}
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
<!--#include('unionForm.js'){}#-->
|
||||
const customForm = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-drawer title="自定义设置" size="50%" class="my-drawer" :visible.sync="moreInfoDrawer" append-to-body>
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>分工会人数限制</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-button @click="openSetUpUnionLimit(moreInfoIndex)" type="primary" size="small">
|
||||
设置分工会人数限制
|
||||
</el-button>
|
||||
<span
|
||||
v-if="formData.courseList[moreInfoIndex].unionLimit && formData.courseList[moreInfoIndex].unionLimit.length > 0"
|
||||
class="text-success"
|
||||
>
|
||||
已设置
|
||||
</span>
|
||||
<span v-else class="text-danger">未设置</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>承办工会</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-select v-model="formData.courseList[moreInfoIndex].hostUnionId" placeholder="请选择承办工会"
|
||||
style="width: 100%" clearable>
|
||||
<el-option :label="item.name" :value="item.id" :key="item.id"
|
||||
v-for="item in unionList"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>对内报名时间</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-date-picker
|
||||
placeholder="请选择对内报名时间"
|
||||
style="width: 100%"
|
||||
type="datetime"
|
||||
v-model="formData.courseList[moreInfoIndex].interTime"
|
||||
format="yyyy-MM-dd HH:mm"
|
||||
value-format="yyyy-MM-dd HH:mm"
|
||||
></el-date-picker>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>是否限制年龄</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-radio-group v-model="formData.courseList[moreInfoIndex].familyAgeLimit" size="small">
|
||||
<el-radio border :label="true">限制</el-radio>
|
||||
<el-radio border :label="false">不限制</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="50" type="flex" v-if="formData.courseList[moreInfoIndex].familyAgeLimit === true">
|
||||
<el-col :span="4">
|
||||
<span>最小年龄</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-input-number :controls="false" style="width: 100%"
|
||||
:max="100"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
step-strictly
|
||||
placeholder="请输入最小年龄"
|
||||
v-model="formData.courseList[moreInfoIndex].minAge"></el-input-number>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="50" type="flex" v-if="formData.courseList[moreInfoIndex].familyAgeLimit === true">
|
||||
<el-col :span="4">
|
||||
<span>最大年龄</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-input-number :controls="false" style="width: 100%"
|
||||
:max="100"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
step-strictly
|
||||
placeholder="请输入最大年龄"
|
||||
v-model="formData.courseList[moreInfoIndex].maxAge"></el-input-number>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>是否限制性别</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-radio-group v-model="formData.courseList[moreInfoIndex].familySexLimit" size="small">
|
||||
<el-radio border :label="true">限制</el-radio>
|
||||
<el-radio border :label="false">不限制</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="50" type="flex" v-if="formData.courseList[moreInfoIndex].familySexLimit === true">
|
||||
<el-col :span="4">
|
||||
<span>限制性别</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-select v-model="formData.courseList[moreInfoIndex].familySex" placeholder="请选择性别"
|
||||
style="width: 100%" clearable>
|
||||
<el-option label="男" value="男"></el-option>
|
||||
<el-option label="女" value="女"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>是否签到</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-radio-group v-model="formData.courseList[moreInfoIndex].isMobileSign" size="small">
|
||||
<el-radio border :label="true">签到</el-radio>
|
||||
<el-radio border :label="false">不签到</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-if="formData.courseList[moreInfoIndex].isMobileSign === true" :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>签到方式</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-radio-group v-model="formData.courseList[moreInfoIndex].signType" size="small">
|
||||
<el-radio border :label="1">扫描二维码</el-radio>
|
||||
<el-radio border :label="2">被扫</el-radio>
|
||||
<el-radio border :label="3">GPS定位签到</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row
|
||||
v-if="formData.courseList[moreInfoIndex].isMobileSign === true
|
||||
&& formData.courseList[moreInfoIndex].signType == 3"
|
||||
:gutter="50"
|
||||
type="flex"
|
||||
>
|
||||
<el-col :span="4">
|
||||
<span>地点坐标</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-button @click="openMap(moreInfoIndex)" type="primary" size="small">设置签到点</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>是否领取礼品</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-radio-group v-model="formData.courseList[moreInfoIndex].isReceiveGift" size="small">
|
||||
<el-radio border :label="true">领取</el-radio>
|
||||
<el-radio border :label="false">不领取</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row v-if="formData.courseList[moreInfoIndex].isReceiveGift === true" :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>领取方式</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-radio-group v-model="formData.courseList[moreInfoIndex].giftType" size="small">
|
||||
<el-radio border :label="1">扫描二维码</el-radio>
|
||||
<el-radio border :label="2">面对面确认</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>报名方式</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-radio-group
|
||||
v-model="formData.courseList[moreInfoIndex].reserveMode"
|
||||
size="small"
|
||||
>
|
||||
<el-radio border :label="1">报名人员减少模式</el-radio>
|
||||
<el-radio border :label="2">候补模式</el-radio>
|
||||
</el-radio-group>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="50" type="flex" v-if="formData.courseList[moreInfoIndex].reserveMode === 2">
|
||||
<el-col :span="4">
|
||||
<span>候补数量</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<el-input-number :controls="false" style="width: 100%"
|
||||
:max="100"
|
||||
:min="0"
|
||||
:precision="0"
|
||||
step-strictly
|
||||
v-model="formData.courseList[moreInfoIndex].waitingNum"></el-input-number>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="50" type="flex">
|
||||
<el-col :span="4">
|
||||
<span>详细信息</span>
|
||||
</el-col>
|
||||
<el-col :span="20">
|
||||
<text-editor v-model="formData.courseList[moreInfoIndex].introduce"></text-editor>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div style="text-align: right">
|
||||
<el-button @click="moreInfoDrawer = false">取 消</el-button>
|
||||
<el-button type="primary" @click="moreInfoDrawer = false">保 存</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
<el-dialog :close-on-click-modal="false" :visible.sync="mapDialog" title="位置信息" :append-to-body="true">
|
||||
<map-container v-if="mapDialog" :position.sync="formData.courseList[mapIndex].courseLocationCoordinates"></map-container>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="mapDialog = false">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<union-form ref="unionFormRef"></union-form>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
moreInfoDrawer: false,
|
||||
unionList: [],
|
||||
formData: {},
|
||||
moreInfoRow: {},
|
||||
moreInfoIndex: 0,
|
||||
|
||||
mapDialog: false,
|
||||
mapIndex: 0,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
"union-form": unionForm,
|
||||
"map-container": httpVueLoader("/components/plugins/mapContainer/MapContainer.vue?v=1.0.1")
|
||||
},
|
||||
methods: {
|
||||
openMap(index) {
|
||||
this.mapIndex = index
|
||||
this.mapDialog = true
|
||||
},
|
||||
openSetUpUnionLimit(index) {
|
||||
this.$refs.unionFormRef.onOpen(this.formData, index)
|
||||
},
|
||||
async onOpen(formData, chooseRow, index) {
|
||||
this.formData = formData
|
||||
this.moreInfoRow = chooseRow
|
||||
this.moreInfoIndex = index
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.moreInfoDrawer = true
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if(!this.formData.courseList) {
|
||||
this.formData = {courseList: [{unionLimit: []}]}
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.my-drawer .el-col-4 {
|
||||
text-align: right;
|
||||
}
|
||||
.my-drawer .el-row {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.el-drawer__body {
|
||||
padding: 20px;
|
||||
}
|
||||
.el-row--flex {
|
||||
align-items: center;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度:">
|
||||
<el-date-picker
|
||||
@change="doSearch"
|
||||
placeholder="请选择年度"
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
v-model="pageForm.year"
|
||||
value-format="yyyy"
|
||||
></el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="活动名称:">
|
||||
<el-input
|
||||
@keyup.enter.native="doSearch"
|
||||
clearable
|
||||
placeholder="请输入活动名称"
|
||||
clearable
|
||||
style="width: 100%"
|
||||
v-model="pageForm.activityName"
|
||||
></el-input>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool label="活动列表">
|
||||
<el-button @click="openAdd" size="small" type="primary">
|
||||
<i class="ti-plus"></i>新建活动
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:width="column.width"
|
||||
:sortable="column.sortable"
|
||||
show-overflow-tooltip
|
||||
v-for="(column, index) in tableColumns"
|
||||
:key="index"
|
||||
>
|
||||
<template v-slot="{ row }" v-if="column.prop === 'isDisabled'">
|
||||
<el-switch
|
||||
:active-value="false"
|
||||
:inactive-value="true"
|
||||
@change="(val) => { activityStatusChange(row.notice, val,row.id) }"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
v-model="row.isDisabled"
|
||||
></el-switch>
|
||||
</template>
|
||||
<template v-slot="{ row: { createdAt } }" v-else-if="column.prop === 'createdAt'">
|
||||
{{ $moment(createdAt).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</template>
|
||||
<template v-slot="{ row }" v-else-if="column.prop === 'activityTime'">
|
||||
<span>{{ $moment(row.activityStartTime).format('YYYY/MM/DD') }}</span>
|
||||
<span> 至 </span>
|
||||
<span>{{ $moment(row.activityEndTime).format('YYYY/MM/DD') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150px">
|
||||
<template v-slot="{ row }">
|
||||
<el-dropdown>
|
||||
<el-button plain size="mini">
|
||||
<i class="ti-settings"></i>
|
||||
<span class="ti-angle-down"></span>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="openActivityCode(row.id)">活动二维码</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="makeCode(row)">签到二维码</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="onView(row)">查看</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="openEdit(row)">编辑</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="onDelete(row)">删除</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #edit>
|
||||
<basic-form ref="formRef" @back="back" @refresh="doSearch"></basic-form>
|
||||
</template>
|
||||
|
||||
<template #view>
|
||||
<info ref="infoRef"></info>
|
||||
</template>
|
||||
|
||||
<make-qrcode ref="codeRef"></make-qrcode>
|
||||
|
||||
<el-dialog
|
||||
title="活动二维码"
|
||||
:visible.sync="codeDialogVisible"
|
||||
:close-on-click-modal="false"
|
||||
width="30%">
|
||||
<div style=" display: flex;justify-content: center;">
|
||||
<qrcode :options="{ width: 400 }" :value="activityUrl" ></qrcode>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="codeDialogVisible = false" type="primary">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include('info.js'){}#-->
|
||||
<!--#include('basicForm.js'){}#-->
|
||||
<!--#include('makeQrcode.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
store,
|
||||
dicts: ["CAMPUS", "FAMILY_SIGNUP_TYPE"],
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"info": info,
|
||||
"basic-form": basicForm,
|
||||
"make-qrcode": makeQrcode,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageForm: {
|
||||
year: new Date().getFullYear() + ''
|
||||
},
|
||||
tableColumns: [
|
||||
{ label: "活动名称", prop: "activityName", width: 600 },
|
||||
{ label: "活动时间", prop: "activityTime" },
|
||||
{ label: "是否开启", prop: "isDisabled", width: 100 },
|
||||
{ label: "创建时间", prop: "createdAt" }
|
||||
],
|
||||
codeDialogVisible: false,
|
||||
activityUrl: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
this.$refs.guava.index()
|
||||
},
|
||||
openAdd() {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.formRef.initData()
|
||||
})
|
||||
},
|
||||
openEdit(row) {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.formRef.initData(row)
|
||||
})
|
||||
},
|
||||
onView(row) {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.infoRef.initData(row.id)
|
||||
})
|
||||
},
|
||||
openActivityCode(id) {
|
||||
this.activityUrl = location.origin + "/platform/family/apply/h5?id=" + id
|
||||
this.codeDialogVisible = true
|
||||
},
|
||||
makeCode(row) {
|
||||
this.$refs.codeRef.initData(row)
|
||||
},
|
||||
async activityStatusChange(notice, val, id) {
|
||||
const resp = await this.$axios.post(loc() + "/activityStatusChange", { notice: notice, isDisabled: val, id })
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
},
|
||||
async onDelete(row) {
|
||||
this.$confirm("此操作将永久删除, 是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(async () => {
|
||||
const resp = await this.$axios.post(loc() + "/onDelete", { id: row.id })
|
||||
this.$message.success(resp.msg)
|
||||
this.doSearch()
|
||||
}).catch(() => {})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,114 @@
|
||||
const info = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-tabs>
|
||||
<el-tab-pane label="基础信息">
|
||||
<el-descriptions :column="2" border class="table_fixed mt20">
|
||||
<el-descriptions-item :span="2" label="活动名称">{{viewData.activityName}}</el-descriptions-item>
|
||||
<el-descriptions-item label="年度">{{viewData.year}}</el-descriptions-item>
|
||||
<el-descriptions-item label="创建时间">{{$moment(viewData.createdAt).format('YYYY-MM-DD HH:mm:ss')}}</el-descriptions-item>
|
||||
<el-descriptions-item label="活动开始时间">{{viewData.activityStartTime}}</el-descriptions-item>
|
||||
<el-descriptions-item label="活动结束时间">{{viewData.activityEndTime}}</el-descriptions-item>
|
||||
<el-descriptions-item label="报名开始时间">{{viewData.activitySignUpStartTime}}</el-descriptions-item>
|
||||
<el-descriptions-item label="报名结束时间">{{viewData.activitySignUpEndTime}}</el-descriptions-item>
|
||||
<el-descriptions-item label="详细信息" :span="2">
|
||||
<div v-html="viewData.introduce"></div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="activityType + '信息'">
|
||||
<el-table :data="viewData.courseList" class="mt20">
|
||||
<el-table-column :label="activityType + '名称'" prop="courseName"></el-table-column>
|
||||
<el-table-column label="类型" prop="courseTypeName"></el-table-column>
|
||||
<el-table-column label="人数" prop="coursePeopleNumber"></el-table-column>
|
||||
<el-table-column label="预留名额" prop="courseReservedNumber"></el-table-column>
|
||||
<el-table-column label="地点" prop="courseLocation">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="openViewMap(row.courseLocationCoordinates)" type="text">{{row.courseLocation}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="校区" prop="campus"></el-table-column>
|
||||
<el-table-column label="负责人" prop="courseInstructor"></el-table-column>
|
||||
<el-table-column label="上课时间" prop="courseTimeList" width="200px">
|
||||
<template v-slot="{ row }">
|
||||
<el-button @click="openViewCourseTime(row.courseTimeList)" type="text">点击查看课程时间</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-dialog :visible.sync="courseTimeListDialog" :title="activityType + '时间'" width="60%" append-to-body>
|
||||
<el-table :data="courseTimeList">
|
||||
<el-table-column label="日期" prop="courseDate">
|
||||
<template v-slot="{row}">{{$moment(row.courseDate).format('YYYY-MM-DD')}}</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="开始时间" prop="courseStartTime"></el-table-column>
|
||||
<el-table-column label="结束时间" prop="courseEndTime"></el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="courseTimeListDialog = false" type="primary">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="viewMapDialog" title="地点" width="60%">
|
||||
<div id="viewMap" style="width: 100%; height: 500px"></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
activityType: '',
|
||||
viewData: {},
|
||||
courseTimeListDialog: false,
|
||||
courseTimeList: [],
|
||||
|
||||
viewMapDialog: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initData(id) {
|
||||
this.$axios.post("/platform/family/manage/findOne", { id: id })
|
||||
.then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.viewData = resp.data
|
||||
const type = this.dict.type.FAMILY_SIGNUP_TYPE.find((o) => o.code === resp.data.trainType)
|
||||
this.activityType = type?.name || "子活动"
|
||||
}
|
||||
})
|
||||
},
|
||||
openViewCourseTime(courseTimeList) {
|
||||
this.courseTimeList = courseTimeList
|
||||
this.courseTimeListDialog = true
|
||||
},
|
||||
openViewMap(point) {
|
||||
if (!Array.isArray(point)) {
|
||||
this.$message.warning("没有设置点位,无法通过地图查看")
|
||||
return
|
||||
}
|
||||
this.viewMapDialog = true
|
||||
this.$nextTick(() => {
|
||||
viewMap = new AMap.Map("viewMap", {
|
||||
resizeEnable: true,
|
||||
center: point,
|
||||
zoom: 16
|
||||
})
|
||||
if (viewMarker) {
|
||||
viewMap.remove(viewMarker)
|
||||
}
|
||||
viewMarker = new AMap.Marker({
|
||||
position: point,
|
||||
offset: new AMap.Pixel(-13, -30)
|
||||
})
|
||||
viewMap.add(viewMarker)
|
||||
viewMap.setFitView(null, false, [150, 60, 100, 60])
|
||||
})
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.el-button--text {
|
||||
padding: 0;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
const makeQrcode = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-dialog :close-on-click-modal="false" :visible.sync="courseDialog"
|
||||
append-to-body :title="activityType + '列表'" width="60%">
|
||||
<el-table :data="courseList">
|
||||
<el-table-column :label="activityType + '名称'" prop="courseName"></el-table-column>
|
||||
<el-table-column label="校区" prop="campus"></el-table-column>
|
||||
<el-table-column label="是否签到" prop="isMobileSign">
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.isMobileSign === true">签到</span>
|
||||
<span v-else>不签到</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签到方式" prop="signType">
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.signType === 1">扫描二维码</span>
|
||||
<span v-else-if="row.signType === 2">被扫</span>
|
||||
<span v-else-if="row.signType === 3">GPS定位签到</span>
|
||||
<span v-else>暂无签到方式</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="是否领取礼品" prop="isReceiveGift">
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.isReceiveGift === true">领取</span>
|
||||
<span v-else>不领取</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="领取方式" prop="giftType">
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.giftType === 1">扫描二维码</span>
|
||||
<span v-else-if="row.giftType === 2">面对面确认</span>
|
||||
<span v-else>暂无领取方式</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="260">
|
||||
<template v-slot="{row}">
|
||||
<el-button v-if="row.signType === 1"
|
||||
@click="makeCourseCode(row)"
|
||||
size="mini" type="primary">
|
||||
生成二维码
|
||||
</el-button>
|
||||
<el-button v-else size="mini" type="text">该{{activityType}}的签到方式不支持生成二维码</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="courseDialog = false" type="primary">关 闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
courseDialog: false,
|
||||
activityType: "",
|
||||
courseList: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initData(row) {
|
||||
this.courseList = row.courseList
|
||||
const type = this.dict.type.FAMILY_SIGNUP_TYPE.find((o) => o.code === row.trainType)
|
||||
this.activityType = type?.name || "子活动"
|
||||
this.courseDialog = true
|
||||
},
|
||||
makeCourseCode(row) {
|
||||
const url = '/platform/family/mine/drivingScan'
|
||||
const data = url + '?courseId=' + row.id
|
||||
console.log(data)
|
||||
const content = jrQrcode.getQrBase64(data)
|
||||
let image = new Image()
|
||||
image.src = content
|
||||
let viewer = new Viewer(image, {
|
||||
zIndex: 99999999,
|
||||
})
|
||||
viewer.show()
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
const unionForm = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-dialog :close-on-click-modal="false" :visible.sync="setUpUnionLimitDialog" title="分工会人数限制" top="50px" append-to-body>
|
||||
<div class="left-span-label" style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>分段设置</div>
|
||||
<div>
|
||||
<el-button size="small" type="primary" @click="unionLimitQuickSetting">应用分段设置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-row v-for="(item,index) in unionUserNumCalc" :key="index" :gutter="20" class="mb5">
|
||||
<el-col :span="7">
|
||||
<el-input-number
|
||||
v-model="item.startNum"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
placeholder="请输入最小人数"
|
||||
style="width: 100%"
|
||||
></el-input-number>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-input-number
|
||||
v-model="item.endNum"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
placeholder="请输入最大人数"
|
||||
style="width: 100%"
|
||||
></el-input-number>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-input-number
|
||||
v-model="item.resultNum"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="1"
|
||||
placeholder="请输入限制人数"
|
||||
style="width: 100%"
|
||||
></el-input-number>
|
||||
</el-col>
|
||||
<el-col :span="4" class="text-right">
|
||||
<el-button icon="el-icon-plus" @click="unionUserNumCalc.push({})"></el-button>
|
||||
<el-button icon="el-icon-minus" @click="unionUserNumCalc.splice(index,1)" :disabled="unionUserNumCalc.length===1"></el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="mt10">
|
||||
<div v-for="(item,index) in unionUserNumCalcTips" class="text-danger">
|
||||
<span class="mr10">({{index+1}}).</span>
|
||||
{{item}}
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<div class="left-span-label" style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>比例设置</div>
|
||||
<div>
|
||||
一键比例:
|
||||
<el-input-number
|
||||
v-model="unionUserNumOneKeyRatio"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="0"
|
||||
placeholder="请输入一键比例"
|
||||
size="small"
|
||||
:max="100"
|
||||
></el-input-number>
|
||||
<el-button size="small" type="primary" @click="applyScaleSettings" class="ml5">应用比例设置</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="formData.courseList[unionLimitIndex].unionLimit" max-height="500px">
|
||||
<el-table-column prop="name" label="分工会"></el-table-column>
|
||||
<el-table-column prop="teacherCount" label="人数"></el-table-column>
|
||||
<el-table-column prop="ratio" label="比例(%)">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number v-model="row.ratio" :precision="0" :step="1" :min="0" :max="100"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="limitCount" label="限制人数">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number
|
||||
v-model="row.limitCount"
|
||||
:precision="0"
|
||||
:step="1"
|
||||
:min="0"
|
||||
:max="row.teacherCount"
|
||||
@change="calSummaryCount"
|
||||
></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-row class="mt20" justify="end" type="flex">
|
||||
<div class="text-danger" style="width: 100%; font-size: 18px; display: flex; align-items: center; font-weight: bold">
|
||||
限制总人数:{{summaryCount}}人
|
||||
</div>
|
||||
<el-button @click="clearUnionLimit" type="danger">清空分工会人数限制</el-button>
|
||||
<el-button @click="setUpUnionLimitDialog=false">取消</el-button>
|
||||
<el-button @click="doConfirmSetUpUnionLimit" type="primary">确定</el-button>
|
||||
</el-row>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
formData: {},
|
||||
unionLimitIndex: 0,
|
||||
setUpUnionLimitDialog: false,
|
||||
unionList: [],
|
||||
unionUserNumCalc: [{}],
|
||||
unionUserNumOneKeyRatio: null,
|
||||
summaryCount: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
unionUserNumCalcTips() {
|
||||
return this.unionUserNumCalc.map((v) => {
|
||||
return (
|
||||
(v.startNum ? v.startNum : "?") +
|
||||
"-" +
|
||||
(v.endNum ? v.endNum : "?") +
|
||||
"人的分工会,限报" +
|
||||
(v.resultNum ? v.resultNum : "?") +
|
||||
"人"
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
calSummaryCount() {
|
||||
const array = this.formData.courseList[this.unionLimitIndex].unionLimit
|
||||
if (array) {
|
||||
this.summaryCount = array.reduce((prev, curr) => {
|
||||
const value = Number(curr.limitCount)
|
||||
if (!isNaN(value)) {
|
||||
return prev + curr.limitCount
|
||||
} else {
|
||||
return prev
|
||||
}
|
||||
}, 0)
|
||||
}
|
||||
},
|
||||
async onOpen(formData, index) {
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.formData = formData
|
||||
this.unionLimitIndex = index
|
||||
this.setUpUnionLimitDialog = true
|
||||
if (
|
||||
!this.formData.courseList[this.unionLimitIndex].unionLimit ||
|
||||
this.formData.courseList[this.unionLimitIndex].unionLimit.length === 0
|
||||
) {
|
||||
const resp = await this.$axios.get("/platform/family/manage/getUnionLimit", {
|
||||
activityScopeId: this.formData.activityGroupId
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
this.$set(this.formData.courseList[this.unionLimitIndex], "unionLimit", resp.data)
|
||||
}
|
||||
}
|
||||
this.summaryCount = this.formData.courseList[this.unionLimitIndex].unionLimit.reduce((prev, curr) => {
|
||||
const value = Number(curr.limitCount)
|
||||
if (!isNaN(value)) {
|
||||
return prev + curr.limitCount
|
||||
} else {
|
||||
return prev
|
||||
}
|
||||
}, 0)
|
||||
},
|
||||
unionLimitQuickSetting() {
|
||||
this.unionUserNumCalc.forEach((v, i) => {
|
||||
const startNum = v.startNum
|
||||
const endNum = v.endNum
|
||||
const resultNum = v.resultNum
|
||||
if (startNum > endNum) {
|
||||
this.$message.warning("第" + (i + 1) + "行设置错误")
|
||||
} else {
|
||||
this.formData.courseList[this.unionLimitIndex].unionLimit.forEach((x) => {
|
||||
if (x.teacherCount >= startNum && x.teacherCount <= endNum) {
|
||||
x.limitCount = resultNum
|
||||
}
|
||||
})
|
||||
this.calSummaryCount()
|
||||
}
|
||||
})
|
||||
},
|
||||
doConfirmSetUpUnionLimit() {
|
||||
this.setUpUnionLimitDialog = false
|
||||
},
|
||||
//应用比例设置
|
||||
applyScaleSettings() {
|
||||
this.formData.courseList[this.unionLimitIndex].unionLimit.forEach((v) => {
|
||||
v.limitCount = parseFloat(((v.teacherCount * this.unionUserNumOneKeyRatio) / 100).toFixed(0))
|
||||
if (v.ratio) {
|
||||
v.limitCount = parseFloat(((v.teacherCount * v.ratio) / 100).toFixed(0))
|
||||
}
|
||||
})
|
||||
this.calSummaryCount()
|
||||
},
|
||||
async clearUnionLimit() {
|
||||
const confirm = await this.$confirm("确定要清空分工会人数限制吗, 是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
if ("confirm" === confirm) {
|
||||
this.formData.courseList[this.unionLimitIndex].unionLimit = []
|
||||
this.unionUserNumOneKeyRatio = null
|
||||
this.unionUserNumCalc = [{}]
|
||||
this.setUpUnionLimitDialog = false
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if(!this.formData.courseList) {
|
||||
this.formData = {courseList: [{unionLimit: []}]}
|
||||
}
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.el-icon-arrow-left,
|
||||
.el-icon-arrow-right {
|
||||
font-size: 28px;
|
||||
font-weight: bolder;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度:">
|
||||
<el-date-picker
|
||||
placeholder="请选择年度"
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
@change="yearChange"
|
||||
v-model="pageForm.year"
|
||||
value-format="yyyy"
|
||||
></el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="活动名称:">
|
||||
<el-select @change="activityChange" style="width: 100%" v-model="pageForm.activityId">
|
||||
<el-option :label="item.activityName" :value="item.id" v-for="item in activityList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool :label="activityType">
|
||||
<el-button type="primary" size="small" @click="exportSignUser" :disabled="!pageForm.activityId">导出报名人员</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column :label="activityType" prop="courseName" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="类型" prop="courseType" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="activityType + '地点'" prop="courseLocation" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="负责人" prop="courseInstructor" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="最多报名人数" prop="coursePeopleNumber" sortable align="center" header-align="center" show-overflow-tooltip>
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.reserveMode === 1">
|
||||
{{row.coursePeopleNumber}}
|
||||
</span>
|
||||
<span v-if="row.reserveMode === 2">
|
||||
{{(row.coursePeopleNumber + row.waitingNum) + '(候补占' + row.waitingNum + ')'}}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预留人数" prop="courseReservedNumber" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="已报名人数" prop="registerNum" sortable show-overflow-tooltip>
|
||||
<template v-slot="{row}">
|
||||
<el-link @click="openView(row)" type="primary">
|
||||
{{row.registerNum}}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200px">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
|
||||
<el-button @click="openSign(row)" size="mini" v-if="row.interTime" :type="row.openOtherUnion === true ? 'danger' : 'primary'">
|
||||
{{row.openOtherUnion === true ? '关闭报名' : '开放报名'}}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #view>
|
||||
<info ref="infoRef"></info>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include('info.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"info": info,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activityList: [],
|
||||
pageForm: {
|
||||
year: new Date().getFullYear().toString(),
|
||||
activityId: null
|
||||
},
|
||||
tableColumns: [
|
||||
{ label: "名称", prop: "courseName" },
|
||||
{ label: "类型", prop: "courseType", sortable: true },
|
||||
{ label: "地点", prop: "courseLocation" },
|
||||
{ label: "教师", prop: "courseInstructor", sortable: true },
|
||||
{ label: "最多报名人数", prop: "coursePeopleNumber", sortable: true },
|
||||
{ label: "已报名人数", prop: "registerNum", sortable: true }
|
||||
],
|
||||
activityType: "子活动",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async openSign(row) {
|
||||
const resp = await this.$axios.post(loc() + "/signChange", { courseId: row.id, openOtherUnion: !row.openOtherUnion })
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
},
|
||||
activityChange(val) {
|
||||
const activity = this.activityList.find((o) => o.id === val)
|
||||
const type = this.dict.type.FAMILY_SIGNUP_TYPE.find(o => o.code === activity.activityType)
|
||||
this.activityType = type?.name || "子活动"
|
||||
},
|
||||
exportSignUser() {
|
||||
this.$downLoad(loc() + "/exportSignUser", { activityId: this.pageForm.activityId })
|
||||
},
|
||||
async yearChange() {
|
||||
this.pageForm.activityId = null
|
||||
await this.getActivityList()
|
||||
await this.doSearch()
|
||||
},
|
||||
async getActivityList() {
|
||||
const resp = await this.$axios.post(loc() + "/activityList", { year: this.pageForm.year })
|
||||
this.activityList = resp.data
|
||||
if (this.activityList && this.activityList.length > 0) {
|
||||
this.pageForm.activityId = this.activityList[0].id
|
||||
this.activityChange(this.activityList[0].id)
|
||||
}
|
||||
},
|
||||
async initData() {
|
||||
await this.getActivityList()
|
||||
},
|
||||
async openView(row) {
|
||||
this.$refs.guava.view(() => {
|
||||
this.$refs.infoRef.onOpen(row)
|
||||
})
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
await this.initData()
|
||||
await this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,123 @@
|
||||
const info = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-tabs>
|
||||
<el-tab-pane label="报名人员">
|
||||
<el-table :data="registerUserTableData" class="mt20">
|
||||
<el-table-column
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
align="center"
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
v-for="(column, index) in registerUserTableColumns"
|
||||
:key="index"
|
||||
>
|
||||
<template v-slot="{ row }" v-if="column.prop === 'state'">
|
||||
<span class="text-success" v-if="row.state === 1">正常报名</span>
|
||||
<span class="text-warning" v-else-if="row.state === 2">候补报名</span>
|
||||
<span class="text-success" v-else-if="row.state === 3">正常报名(候补)</span>
|
||||
<span class="text-info" v-else-if="row.state === 4">无效报名(缺席)</span>
|
||||
</template>
|
||||
<template v-slot="{ row }" v-else-if="column.prop === 'familyCount'">
|
||||
<el-link @click="viewFamily(row)" type="primary">
|
||||
{{row.familyCount}}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100">
|
||||
<template v-slot="{ row }">
|
||||
<el-button size="mini" type="primary" @click="viewFamily(row)">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="签到情况" v-if="clickRow.isMobileSign === true && Object.keys(userSignInfo).length > 0">
|
||||
<el-tabs style="height: 600px" tab-position="left" class="mt20">
|
||||
<el-tab-pane v-for="(item, key) in userSignInfo" :key="key">
|
||||
<span slot="label">
|
||||
<i class="el-icon-date"></i>
|
||||
{{key}}
|
||||
</span>
|
||||
<el-table :data="item" style="max-height: 600px; overflow-y: auto">
|
||||
<el-table-column label="姓名" prop="username"></el-table-column>
|
||||
<el-table-column label="工号" prop="loginname"></el-table-column>
|
||||
<el-table-column label="是否签到" prop="isAttend">
|
||||
<template v-slot="{row}">
|
||||
<template v-if="Date.now() < Date.parse(row.courseStartTime)">
|
||||
<span class="text-default">未开始</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="text-success" v-if="row.isAttend">已签到</span>
|
||||
<span class="text-warning" v-else>未签到</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="签到时间" prop="attendTime"></el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-dialog title="家属信息" append-to-body :close-on-click-modal="false" :visible.sync="familyVisible" width="50%">
|
||||
<template v-for="(item,index) in familyRow.mobileColumnsValue" :key="index">
|
||||
<div class="left-span-label">家属{{ index + 1 }}</div>
|
||||
<el-descriptions border class="descriptions-form">
|
||||
<el-descriptions-item v-for="(column, i) in item" :label="column.columnName" :key="i">
|
||||
<div v-if="column.columnFormType !== 'FILE'">{{ column.columnValue }}</div>
|
||||
<div v-else>
|
||||
<file-preview complete_result :files="column.columnValue"></file-preview>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="familyVisible = false">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
registerUserTableData: [],
|
||||
registerUserTableColumns: [
|
||||
{ label: "姓名", prop: "username" },
|
||||
{ label: "工号", prop: "loginname" },
|
||||
{ label: "单位", prop: "unitName" },
|
||||
{ label: "分工会", prop: "unionName" },
|
||||
{ label: "联系方式", prop: "mobile" },
|
||||
{ label: "报名时间", prop: "signUpTime" },
|
||||
{ label: "报名状态", prop: "state" },
|
||||
{ label: "家属人数", prop: "familyCount" },
|
||||
],
|
||||
userSignInfo: {},
|
||||
clickRow: {},
|
||||
familyRow: {},
|
||||
familyVisible: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onOpen(row) {
|
||||
this.clickRow = row
|
||||
const resp_register = await this.$axios.post(loc() + "/registerUserList", {courseId: row.id})
|
||||
this.registerUserTableData = resp_register.data
|
||||
const resp_signInfo = await this.$axios.post(loc() + "/getSignInfo", {courseId: row.id})
|
||||
this.userSignInfo = resp_signInfo.data
|
||||
/*const resp_columnInfo = await $.get(loc() + '/getTaleColumnInfo', {courseId: row.id})
|
||||
if (resp_columnInfo.data) {
|
||||
this.registerUserTableColumns = []
|
||||
this.registerUserTableColumns = this.cloneTableColumns.concat(resp_columnInfo.data)
|
||||
}*/
|
||||
},
|
||||
viewFamily(row) {
|
||||
this.familyRow = row
|
||||
this.familyVisible = true
|
||||
},
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,364 @@
|
||||
const basicForm = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-form label-width="120px" :model="formData" ref="addForm" :rules="rules">
|
||||
<el-form-item prop="code" label="类型编码">
|
||||
<el-input v-model="formData.code" placeholder="请输入类型编码"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="typeName" label="类型名称">
|
||||
<el-input v-model="formData.typeName" placeholder="请输入类型名称"></el-input>
|
||||
</el-form-item>
|
||||
<!--<el-form-item prop="isBringFamily" label="是否携带家属">
|
||||
<el-radio-group v-model="formData.isBringFamily" @input="isBringFamilyInput">
|
||||
<el-radio :label="true" border>携带</el-radio>
|
||||
<el-radio :label="false" border>不携带</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>-->
|
||||
<el-form-item v-if="formData.isBringFamily === true" prop="familyMaxCount" label="家属最多数">
|
||||
<el-input v-model="formData.familyMaxCount" placeholder="请输入家属最多数" type="number"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formData.isBringFamily === true" prop="isAddFamily" label="家属纳入总人数">
|
||||
<el-radio-group v-model="formData.isAddFamily">
|
||||
<el-radio :label="true" border>纳入</el-radio>
|
||||
<el-radio :label="false" border>不纳入</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="formData.isBringFamily === true" prop="selfAddFamily" label="本人纳入总人数">
|
||||
<el-radio-group v-model="formData.selfAddFamily">
|
||||
<el-radio :label="true" border>纳入</el-radio>
|
||||
<el-radio :label="false" border>不纳入</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div class="left-span-label" style="display: flex; justify-content: space-between; align-items: center">
|
||||
<div>
|
||||
报名填写字段
|
||||
<span style="color: #c64120; margin-left: 10px">
|
||||
注:移动端报名时字段的显示顺序会按照下面表格中的序号进行排列、字段编码不能重复
|
||||
</span>
|
||||
</div>
|
||||
<div>
|
||||
<el-button
|
||||
@click="formData.familyMobileSignColumnList.push({isRequired: false})"
|
||||
size="small"
|
||||
type="primary"
|
||||
style="margin-left: 10px"
|
||||
>
|
||||
<i class="ti-plus"></i>
|
||||
添加
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="formData.familyMobileSignColumnList">
|
||||
<el-table-column label="序号" prop="columnIndex">
|
||||
<template v-slot="{row}">
|
||||
<el-input-number v-model="row.columnIndex" placeholder="请输入序号"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="字段名称" prop="columnName">
|
||||
<template v-slot="{row}">
|
||||
<el-input v-model="row.columnName" placeholder="请输入字段名称"></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="字段编码" prop="columnCode">
|
||||
<template v-slot="{row}">
|
||||
<el-input
|
||||
v-model="row.columnCode"
|
||||
placeholder="请输入字段编码"
|
||||
:disabled="formData.isBringFamily === true && row.columnCode === 'xdqsrs'"
|
||||
></el-input>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="验证规则" prop="validRule">
|
||||
<template v-slot="{row}">
|
||||
<el-select v-model="row.validRule" style="width: 100%" filterable placeholder="请选择验证规则" clearable>
|
||||
<el-option label="身份证" value="idCard"></el-option>
|
||||
<el-option label="手机号" value="mobile"></el-option>
|
||||
<el-option label="邮箱" value="email"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="控件类型" prop="columnFormType">
|
||||
<template v-slot="{row, $index}">
|
||||
<el-select
|
||||
filterable
|
||||
v-model="row.columnFormType"
|
||||
@change="(val) => {columnFormTypeChange(val, $index)}"
|
||||
placeholder="请选择控件类型"
|
||||
>
|
||||
<el-option v-for="item in columnFormTypeList" :label="item.description" :value="item.code" :key="item.code"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="字段类型" prop="columnType">
|
||||
<template v-slot="{row}">
|
||||
<el-select
|
||||
filterable
|
||||
placeholder="请选择字段类型"
|
||||
v-model="row.columnType"
|
||||
>
|
||||
<el-option v-for="item in columnTypeOptions" :label="item" :value="item" :key="item"></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="是否必填" prop="isRequired" sortable>
|
||||
<template v-slot="{row}">
|
||||
<el-switch
|
||||
v-model="row.isRequired"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949"
|
||||
:active-value="true"
|
||||
:inactive-value="false"
|
||||
active-text="是"
|
||||
inactive-text="否"
|
||||
></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作">
|
||||
<template v-slot="{row, $index}">
|
||||
<el-button
|
||||
@click="openDetailedParams(row, $index)"
|
||||
:disabled="!['SELECT', 'RADIO', 'FILE'].includes(row.columnFormType)"
|
||||
size="mini"
|
||||
type="primary"
|
||||
>
|
||||
设置详细参数
|
||||
</el-button>
|
||||
<el-button
|
||||
@click="formData.familyMobileSignColumnList.splice($index, 1)"
|
||||
:disabled="formData.isBringFamily === true && row.columnCode === 'xdqsrs'"
|
||||
size="mini"
|
||||
type="danger"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div style="float: right; margin: 20px 0">
|
||||
<el-button @click="$emit('refresh')">取 消</el-button>
|
||||
<el-button type="primary" @click="doHandle">确 定</el-button>
|
||||
</div>
|
||||
|
||||
<el-drawer append-to-body :visible.sync="detailedParamsVisible" size="40%">
|
||||
<template #title>
|
||||
<div class="left-span-label">设置详细参数</div>
|
||||
</template>
|
||||
<el-form class="mt20" ref="paramForm" :rules="paramFormRules" :model="clickRow" label-width="80px">
|
||||
<template v-if="['SELECT'].includes(clickRow.columnFormType)">
|
||||
<el-form-item label="选项列表" prop="selectValues">
|
||||
<el-select
|
||||
v-model="clickRow.selectValues"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请选择选项列表(如无数据时,需手动输入选项进行添加)"
|
||||
>
|
||||
<el-option v-for="item in clickRow.columnOptions" :label="item" :value="item" :key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-if="['RADIO'].includes(clickRow.columnFormType)">
|
||||
<el-form-item label="选项列表" prop="selectValues">
|
||||
<el-select
|
||||
v-model="clickRow.selectValues"
|
||||
multiple
|
||||
style="width: 100%"
|
||||
filterable
|
||||
allow-create
|
||||
default-first-option
|
||||
placeholder="请选择选项列表(如无数据时,需手动输入选项进行添加)"
|
||||
>
|
||||
<el-option v-for="item in clickRow.columnOptions" :label="item" :value="item" :key="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-if="['FILE'].includes(clickRow.columnFormType)">
|
||||
<el-form-item label="文件类型" prop="fileType">
|
||||
<el-select v-model="clickRow.fileType" multiple style="width: 100%" filterable placeholder="请选择文件类型">
|
||||
<el-option label="jpg" value=".jpg"></el-option>
|
||||
<el-option label="png" value=".png"></el-option>
|
||||
<el-option label="jpeg" value=".jpeg"></el-option>
|
||||
<el-option label="doc" value=".doc"></el-option>
|
||||
<el-option label="docx" value=".docx"></el-option>
|
||||
<el-option label="xlsx" value=".xlsx"></el-option>
|
||||
<el-option label="pdf" value=".pdf"></el-option>
|
||||
<el-option label="mp3" value=".mp3"></el-option>
|
||||
<el-option label="mp4" value=".mp4"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="文件个数" prop="fileNumber">
|
||||
<el-input-number v-model="clickRow.fileNumber" :min="1" :max="10" placeholder="请输入文件个数" style="width: 100%"></el-input-number>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
|
||||
<div style="float: right; margin: 20px 0">
|
||||
<el-button @click="detailedParamsVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="doDetailParams">确 定</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
familyMobileSignColumnList: [{ isRequired: false }],
|
||||
isBringFamily: true,
|
||||
isAddFamily: true,
|
||||
selfAddFamily: true,
|
||||
},
|
||||
rules: {
|
||||
typeName: [{ required: true, message: "请输入类型名称", trigger: ["change", "blur"] }],
|
||||
code: [{ required: true, message: "请输入类型编码", trigger: ["change", "blur"] }],
|
||||
isBringFamily: [{ required: true, message: "请选择是否携带家属", trigger: ["blur", "change"] }],
|
||||
isAddFamily: [{ required: true, message: "请选择家属是否纳入总人数", trigger: ["blur", "change"] }],
|
||||
familyMaxCount: [{ required: true, message: "请输入家属最多数", trigger: ["blur", "change"] }],
|
||||
},
|
||||
columnTypeOptions: [],
|
||||
columnFormTypeList: [],
|
||||
clickRow: {},
|
||||
paramFormRules: {
|
||||
selectValues: [{ required: true, message: "请选择选项列表", trigger: ["blur"] }],
|
||||
fileType: [{ required: true, message: "请选择文件类型", trigger: ["blur"] }],
|
||||
fileNumber: [{ required: true, message: "请输入文件个数", trigger: ["blur", "change"] }]
|
||||
},
|
||||
detailedParamsVisible: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
isBringFamilyInput(o) {
|
||||
this.$set(this.formData, "isAddFamily", o === true ? false : null)
|
||||
if (o === true) {
|
||||
this.formData.familyMobileSignColumnList.unshift({
|
||||
columnName: "携带亲属人数",
|
||||
columnCode: "xdqsrs",
|
||||
columnFormType: "INPUT",
|
||||
columnType: "INT",
|
||||
isRequired: true
|
||||
})
|
||||
} else {
|
||||
this.formData.familyMobileSignColumnList.forEach((item, index) => {
|
||||
if (item.columnCode === "xdqsrs" && this.formData.isBringFamily === false) {
|
||||
this.formData.familyMobileSignColumnList.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
columnFormTypeChange(val, index) {
|
||||
if (val === "FILE") {
|
||||
this.formData.familyMobileSignColumnList[index].columnType = "JSON"
|
||||
this.formData.familyMobileSignColumnList[index].isDisabled = true
|
||||
} else {
|
||||
this.formData.familyMobileSignColumnList[index].columnType = ""
|
||||
this.formData.familyMobileSignColumnList[index].isDisabled = false
|
||||
}
|
||||
},
|
||||
doHandle() {
|
||||
if (this.formData.id) {
|
||||
this.doEdit()
|
||||
} else {
|
||||
this.doAdd()
|
||||
}
|
||||
},
|
||||
async doDetailParams() {
|
||||
const isValid = await this.$refs["paramForm"].validate()
|
||||
if (isValid) {
|
||||
this.detailedParamsVisible = false
|
||||
}
|
||||
},
|
||||
openDetailedParams(row, index) {
|
||||
this.clickRow = row
|
||||
this.detailedParamsVisible = true
|
||||
if (this.$refs["paramForm"]) this.$refs["paramForm"].clearValidate()
|
||||
},
|
||||
doAdd() {
|
||||
this.$refs["addForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
const newListLength = new Set(this.formData.familyMobileSignColumnList.map((item) => item.columnCode)).size
|
||||
const listLength = this.formData.familyMobileSignColumnList.length
|
||||
if (listLength > newListLength) {
|
||||
this.$message.warning('字段编码不能重复')
|
||||
return
|
||||
}
|
||||
const cloneData = clone(this.formData)
|
||||
this.$axios.post(loc() + "/doAdd", { data: JSON.stringify(cloneData) }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.$emit('refresh')
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
doEdit() {
|
||||
this.$refs["addForm"].validate((valid) => {
|
||||
if (valid) {
|
||||
const newListLength = new Set(this.formData.familyMobileSignColumnList.map((item) => item.columnCode)).size
|
||||
const listLength = this.formData.familyMobileSignColumnList.length
|
||||
if (listLength > newListLength) {
|
||||
this.$message.warning('字段编码不能重复')
|
||||
return
|
||||
}
|
||||
const cloneData = clone(this.formData)
|
||||
cloneData.familyMobileSignColumnList = JSON.stringify(cloneData.familyMobileSignColumnList)
|
||||
this.$axios.post(loc() + "/doEdit", cloneData).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.$emit('refresh')
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
async getColTypeOptions() {
|
||||
const resp = await this.$axios.get(loc() + "/getColumnType")
|
||||
this.columnTypeOptions = resp.data
|
||||
},
|
||||
async getEnumOptions() {
|
||||
const resp = await this.$axios.post("/open/common/dictEnumOptions", { name: "ColumnFormTypeEnum" })
|
||||
return resp.data
|
||||
},
|
||||
initData(row) {
|
||||
if(row && row.id) {
|
||||
this.formData = JSON.parse(JSON.stringify(row))
|
||||
this.formData.familyMobileSignColumnList.forEach((item) => {
|
||||
item.isDisabled = item.columnFormType === "FILE"
|
||||
})
|
||||
} else {
|
||||
this.formData = {
|
||||
familyMobileSignColumnList: [{ isRequired: false }],
|
||||
isBringFamily: true,
|
||||
isAddFamily: true,
|
||||
selfAddFamily: true,
|
||||
}
|
||||
if (this.$refs["addForm"]) this.$refs["addForm"].resetFields()
|
||||
}
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
await this.getColTypeOptions()
|
||||
this.columnFormTypeList = await this.getEnumOptions()
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
.el-row--flex.is-justify-space-between {
|
||||
justify-content: left;
|
||||
}
|
||||
.el-drawer__body {
|
||||
padding: 0 30px 0 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="类型名称:">
|
||||
<el-input clearable placeholder="请输入类型名称" v-model="pageForm.typeName"></el-input>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt20">
|
||||
<table-tool label="申请列表">
|
||||
<el-button type="primary" size="small" @click="openAdd">
|
||||
<i class="ti-plus"></i>
|
||||
新增类型
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" @sort-change="pageOrder" :size="tableSize">
|
||||
<el-table-column label="序号" width="70" type="index">
|
||||
<template v-slot="scope">
|
||||
<span>{{scope.$index+(pageForm.pageNumber - 1) * pageForm.pageSize + 1}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="类型编码" prop="code" sortable></el-table-column>
|
||||
<el-table-column label="类型名称" prop="typeName"></el-table-column>
|
||||
<el-table-column label="操作" width="300px">
|
||||
<template v-slot="{ row }">
|
||||
<el-button v-if="row.xh!==1" size="mini" type="primary" @click="rowChange(row, false)">上移</el-button>
|
||||
<el-button v-if="row.xh!==pageForm.totalCount" size="mini" type="primary" @click="rowChange(row, true)">下移</el-button>
|
||||
<el-button type="primary" size="mini" @click="openEdit(row)">编辑</el-button>
|
||||
<el-button type="danger" size="mini" @click="doDelete(row.id)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<template #edit>
|
||||
<basic-form ref="basicFormRef" @refresh="doSearch();$refs.guava.index()"></basic-form>
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
</div>
|
||||
<script>
|
||||
<!--#include('basicForm.js'){}#-->
|
||||
const vue = new Vue({
|
||||
el: "#app",
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"basic-form": basicForm,
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
async rowChange(row, toDown) {
|
||||
await this.$axios.post(loc() + "/xhChange", { id: row.id, xh: row.xh, toDown }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
},
|
||||
openAdd() {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.basicFormRef.initData()
|
||||
})
|
||||
},
|
||||
pageData() {
|
||||
this.$axios.post(loc() + "/pageData", this.pageForm).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data.list
|
||||
this.pageForm.totalCount = res.data.totalCount
|
||||
}
|
||||
})
|
||||
},
|
||||
openEdit(obj) {
|
||||
this.$refs.guava.edit(() => {
|
||||
this.$refs.basicFormRef.initData(obj)
|
||||
})
|
||||
},
|
||||
doDelete(id) {
|
||||
this.$confirm("您确定要删除吗, 是否继续?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post(loc() + "/doDelete", { id: id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.doSearch()
|
||||
this.$message.success(res.msg)
|
||||
}
|
||||
})
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,144 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度:">
|
||||
<el-date-picker
|
||||
placeholder="请选择年度"
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
@change="yearChange"
|
||||
v-model="pageForm.year"
|
||||
value-format="yyyy"
|
||||
></el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="活动名称:">
|
||||
<el-select @change="activityChange" style="width: 100%" v-model="pageForm.activityId">
|
||||
<el-option :label="item.activityName" :value="item.id" v-for="item in activityList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool label="人员调整"></table-tool>
|
||||
<el-table :data="tableData" :size="tableSize">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column :label="activityType" prop="courseName" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="类型" prop="courseType" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column :label="activityType + '地点'" prop="courseLocation" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column
|
||||
label="负责人"
|
||||
prop="courseInstructor"
|
||||
sortable
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column label="最多报名人数" prop="coursePeopleNumber" sortable show-overflow-tooltip>
|
||||
<template v-slot="{row}">
|
||||
<span v-if="row.reserveMode === 1">
|
||||
{{row.coursePeopleNumber}}
|
||||
</span>
|
||||
<span v-if="row.reserveMode === 2">
|
||||
{{(row.coursePeopleNumber + row.waitingNum) + '(候补占' + row.waitingNum + ')'}}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="预留人数" prop="courseReservedNumber" sortable show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="已报名人数" prop="registerNum" sortable show-overflow-tooltip>
|
||||
<template v-slot="{row}">
|
||||
<el-link @click="openView(row)" type="primary">
|
||||
{{row.registerNum}}
|
||||
</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" width="150px">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="openView(row)" size="mini" type="primary">调整</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
|
||||
<template #view>
|
||||
<user-info ref="userInfoRef" @refresh="doSearch"></user-info>
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<!--#include('userInfo.js'){}#-->
|
||||
new Vue({
|
||||
el: "#app",
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
mixins: [initTableMixins],
|
||||
components: {
|
||||
"user-info": userInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activityType: "子活动",
|
||||
activityList: [],
|
||||
pageForm: {
|
||||
year: new Date().getFullYear().toString(),
|
||||
activityId: null
|
||||
},
|
||||
tableColumns: [
|
||||
{ label: "名称", prop: "courseName" },
|
||||
{ label: "类型", prop: "courseType", sortable: true },
|
||||
{ label: "地点", prop: "courseLocation" },
|
||||
{ label: "教师", prop: "courseInstructor", sortable: true },
|
||||
{ label: "最多报名人数", prop: "coursePeopleNumber", sortable: true },
|
||||
{ label: "已报名人数", prop: "registerNum", sortable: true }
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
activityChange(val) {
|
||||
const activity = this.activityList.find((o) => o.id === val)
|
||||
const type = this.dict.type.FAMILY_SIGNUP_TYPE.find(o => o.code === activity.activityType)
|
||||
this.activityType = type?.name || "子活动"
|
||||
},
|
||||
async yearChange() {
|
||||
this.pageForm.activityId = null
|
||||
await this.getActivityList()
|
||||
await this.doSearch()
|
||||
},
|
||||
async getActivityList() {
|
||||
const resp = await this.$axios.post(loc() + "/activityList", { year: this.pageForm.year })
|
||||
this.activityList = resp.data
|
||||
if (this.activityList && this.activityList.length > 0) {
|
||||
this.pageForm.activityId = this.activityList[0].id
|
||||
this.activityChange(this.activityList[0].id)
|
||||
}
|
||||
},
|
||||
async initData() {
|
||||
await this.getActivityList()
|
||||
},
|
||||
async openView(o) {
|
||||
this.$refs.guava.view(() => {
|
||||
const activity = this.activityList.find((o) => o.id === this.pageForm.activityId)
|
||||
this.$refs.userInfoRef.onOpen(o, activity)
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
await this.initData()
|
||||
await this.pageData()
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -0,0 +1,224 @@
|
||||
const userInfo = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<div class="left-span-label">{{ registerCourse.courseName + '报名人员' }}</div>
|
||||
<div>
|
||||
<search @search="registerSearch">
|
||||
<search-item label="姓名/工号:">
|
||||
<el-input v-model="registerForm.searchKeyword" placeholder="请输入内容"></el-input>
|
||||
</search-item>
|
||||
<search-item label="所属工会:">
|
||||
<el-select v-model="registerForm.unionId" clearable filterable placeholder="请选择院级工会" @change="getUnitList()">
|
||||
<el-option v-for="item in unionList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="所属单位:">
|
||||
<el-select v-model="registerForm.unitId" clearable filterable placeholder="请选择单位">
|
||||
<el-option v-for="item in unitList" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
</search>
|
||||
</div>
|
||||
<el-table :data="registerUserTableData" class="mt15">
|
||||
<el-table-column
|
||||
:label="column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
align="center"
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
v-for="(column, index) in registerUserTableColumns"
|
||||
:key="index"
|
||||
>
|
||||
<template v-slot="{row}" v-if="column.prop === 'state'">
|
||||
<span class="text-success" v-if="row.state === 1">正常报名</span>
|
||||
<span class="text-warning" v-else-if="row.state === 2">候补报名</span>
|
||||
<span class="text-success" v-else-if="row.state === 3">正常报名(候补)</span>
|
||||
<span class="text-info" v-else-if="row.state === 4">无效报名(缺席)</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150px">
|
||||
<template v-slot="{row}">
|
||||
<el-button v-if="row.state === 1 || row.state === 3" @click="adjust(row)" size="mini" type="primary">修改</el-button>
|
||||
<el-button @click="deleteSignUser(row)" size="mini" type="danger">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog title="人员调整" append-to-body class="adjustDialog" :close-on-click-modal="false" :visible.sync="adjustDialogVisible" width="50%">
|
||||
<span style="color: #c33714">注:如单选为灰色选择不了,则表示对应的{{ activityType }}人数已满!候补报名不做调整。</span>
|
||||
<el-table :data="courseList" class="mt20">
|
||||
<el-table-column label="单选" width="160">
|
||||
<template v-slot="{row}">
|
||||
<el-radio
|
||||
:label="row.id"
|
||||
@change.native="getCurrentRow(row)"
|
||||
:disabled="(row.courseReservedNumber + row.registerNum) >= row.coursePeopleNumber"
|
||||
v-model="afterAdjustCourse"
|
||||
></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="activityType + '列表'"
|
||||
prop="courseName"
|
||||
align="center"
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column label="最多报名人数" prop="coursePeopleNumber" align="center" header-align="center">
|
||||
</el-table-column>
|
||||
<el-table-column label="预留名额" prop="courseReservedNumber" align="center" header-align="center"></el-table-column>
|
||||
<el-table-column label="已报名人数" prop="registerNum" align="center" header-align="center"></el-table-column>
|
||||
<el-table-column label="候补人数" prop="hasWaitingNum" align="center" header-align="center"></el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="adjustDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="doAdjust">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
data() {
|
||||
return {
|
||||
afterAdjustCourse: "",
|
||||
adjustDialogVisible: false,
|
||||
unionList: [],
|
||||
unitList: [],
|
||||
registerForm: {
|
||||
unionId: "",
|
||||
unitId: ""
|
||||
},
|
||||
registerCourse: {},
|
||||
courseList: [],
|
||||
userInfo: {},
|
||||
chooseRow: {},
|
||||
registerUserTableData: [],
|
||||
registerUserTableColumns: [
|
||||
{ label: "姓名", prop: "username" },
|
||||
{ label: "工号", prop: "loginname" },
|
||||
{ label: "单位", prop: "unitName" },
|
||||
{ label: "分工会", prop: "unionName" },
|
||||
{ label: "联系方式", prop: "mobile" },
|
||||
{ label: "报名时间", prop: "signUpTime" },
|
||||
{ label: "报名状态", prop: "state" }
|
||||
],
|
||||
activityType: '',
|
||||
activity: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onOpen(row, activity) {
|
||||
this.registerCourse = row
|
||||
this.registerForm.courseId = row.id
|
||||
this.activity = activity
|
||||
const resp_register = await this.$axios.post(loc() + "/registerUserList", this.registerForm)
|
||||
this.registerUserTableData = resp_register.data
|
||||
|
||||
const type = this.dict.type.FAMILY_SIGNUP_TYPE.find(o => o.code === activity.activityType)
|
||||
this.activityType = type?.name || "子活动"
|
||||
},
|
||||
getCurrentRow(row) {
|
||||
this.chooseRow = row
|
||||
},
|
||||
async doAdjust() {
|
||||
if (!this.afterAdjustCourse) {
|
||||
this.$message.warning("请选择要调整的" + this.activityType + "!")
|
||||
return
|
||||
}
|
||||
this.$confirm(
|
||||
"您确定要将" +
|
||||
"<span style='color: red'>" +
|
||||
this.userInfo.username +
|
||||
"</span>" +
|
||||
"的报名信息调整到" +
|
||||
"<span style='color: red'>" +
|
||||
this.chooseRow.courseName +
|
||||
"</span>" +
|
||||
"中吗?",
|
||||
"提示",
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
dangerouslyUseHTMLString: true
|
||||
}
|
||||
)
|
||||
.then(async () => {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: "努力调整中,感谢您的耐心等待。。。",
|
||||
spinner: "el-icon-loading",
|
||||
background: "rgba(0, 0, 0, 0.7)"
|
||||
})
|
||||
const resp = await this.$axios.post(loc() + "/adjust", {
|
||||
activityId: this.activity.id,
|
||||
oldCourseId: this.registerCourse.id,
|
||||
newCourseId: this.afterAdjustCourse,
|
||||
userId: this.userInfo.userId
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.adjustDialogVisible = false
|
||||
await this.registerSearch()
|
||||
this.$emit("refresh", null)
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
loading.close()
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
async adjust(o) {
|
||||
this.userInfo = o
|
||||
this.afterAdjustCourse = ""
|
||||
await this.getCourse(this.activity.id)
|
||||
this.adjustDialogVisible = true
|
||||
},
|
||||
deleteSignUser(o) {
|
||||
this.$confirm("您确定要删除" + "<span style='color: red'>" + o.username + "</span>" + "的报名信息吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
dangerouslyUseHTMLString: true
|
||||
})
|
||||
.then(async () => {
|
||||
const resp = await this.$axios.post(loc() + "/deleteSignUser", {
|
||||
activityId: this.activity.id,
|
||||
courseId: this.registerCourse.id,
|
||||
userId: o.userId
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
await this.registerSearch()
|
||||
this.doSearch()
|
||||
} else {
|
||||
this.$message.warning(resp.msg)
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
async registerSearch() {
|
||||
this.registerForm.courseId = this.registerCourse.id
|
||||
const resp_register = await $.get(loc() + "/registerUserList", this.registerForm)
|
||||
this.registerUserTableData = resp_register.data
|
||||
},
|
||||
async getCourse(val) {
|
||||
const {data} = await this.$axios.post(loc() + "/getCourse", {activityId: val})
|
||||
this.courseList = data
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
this.unionList = await this.$businessTool.listUnion()
|
||||
this.unitList = await this.$businessTool.listUnit(this.registerForm.unionId)
|
||||
},
|
||||
style: /*language=CSS*/ `
|
||||
.adjustDialog .el-radio__label {
|
||||
display: none;
|
||||
}
|
||||
.adjustDialog .el-dialog__body {
|
||||
max-height: 600px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
`
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度:">
|
||||
<el-date-picker
|
||||
placeholder="选择年度"
|
||||
type="year"
|
||||
style="width: 100%"
|
||||
v-model="pageForm.year"
|
||||
value-format="yyyy"
|
||||
></el-date-picker>
|
||||
</search-item>
|
||||
<search-item label="活动名称:">
|
||||
<el-select @change="activityChange" style="width: 100%" v-model="pageForm.activityId">
|
||||
<el-option :label="item.activityName" :value="item.id" v-for="item in activityList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item :label="activityType + ':'">
|
||||
<el-select @change="courseChange" :placeholder="'请选择' + activityType" style="width: 100%" v-model="pageForm.courseId">
|
||||
<el-option :label="item.courseName" :value="item.id" v-for="item in courseList" :key="item.id"></el-option>
|
||||
</el-select>
|
||||
</search-item>
|
||||
<search-item label="人员信息:">
|
||||
<el-input clearable placeholder="输入姓名或者工号搜索" v-model="pageForm.userKeyWord"></el-input>
|
||||
</search-item>
|
||||
</search>
|
||||
</el-card>
|
||||
<el-card class="mt10" shadow="never">
|
||||
<table-tool ref="tool" :label="activityType + '(温馨提示:如需补充人员,请在上面选择具体的' + activityType + ')'">
|
||||
<el-button @click="openReserve" type="primary" v-if="reserveMode === 2" size="small">补充人员</el-button>
|
||||
<el-button @click="exportSignPerson" type="primary" size="small">导出签到名单</el-button>
|
||||
<el-button @click="exportGiftPerson" type="primary" size="small">导出领取名单</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :size="tableSize">
|
||||
<el-table-column :index="indexMethod" label="序号" type="index" width="80px"></el-table-column>
|
||||
<el-table-column
|
||||
:label="column.prop === 'courseNames' ? activityType : column.label"
|
||||
:prop="column.prop"
|
||||
:sortable="column.sortable"
|
||||
align="center"
|
||||
header-align="center"
|
||||
show-overflow-tooltip
|
||||
v-if="(column.prop !== 'state' && column.prop !== 'absentCount') || (reserveMode === 2 && column.prop === 'state' && column.prop !== 'absentCount')
|
||||
|| (column.prop === 'absentCount' && course.isMobileSign === true)"
|
||||
v-for="(column,index) in tableColumns"
|
||||
:key="index"
|
||||
>
|
||||
<template v-slot="{row}" v-if="column.prop==='isDisabled'">
|
||||
<span class="text-danger" v-if="row.isDisabled">是</span>
|
||||
<span class="text-success" v-else>否</span>
|
||||
</template>
|
||||
<template v-slot="{row}" v-else-if="column.prop==='state'">
|
||||
<span class="text-success" v-if="row.state === 1">正常报名</span>
|
||||
<span class="text-warning" v-else-if="row.state === 2">候补报名</span>
|
||||
<span class="text-success" v-else-if="row.state === 3">正常报名(候补)</span>
|
||||
<span class="text-info" v-else-if="row.state === 4">无效报名(缺席)</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150px">
|
||||
<template v-slot="{row}">
|
||||
<el-button @click="handleUser(row.userId)" size="mini" type="danger" v-if="!row.isDisabled">拉黑</el-button>
|
||||
<el-button @click="handleUser(row.userId)" size="mini" type="success" v-if="row.isDisabled">解封</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</guava>
|
||||
|
||||
<el-dialog title="补充人员" :visible.sync="reserveDialogVisible" width="55%" top="3%">
|
||||
<vi-title title="以下为候补人员,已为您按照报名时间降序排列"></vi-title>
|
||||
<el-table :data="reserveTableData" ref="multipleTable" @selection-change="handleSelectionChange">
|
||||
<el-table-column :selectable="(row, index) => {return row.state === 2}" type="selection" width="55"></el-table-column>
|
||||
<el-table-column prop="username" label="姓名"></el-table-column>
|
||||
<el-table-column prop="loginname" label="工号"></el-table-column>
|
||||
<el-table-column prop="mobile" label="联系方式"></el-table-column>
|
||||
<el-table-column prop="unitName" label="单位"></el-table-column>
|
||||
<el-table-column prop="unionName" label="工会"></el-table-column>
|
||||
<el-table-column prop="signUpTime" label="报名时间"></el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="reserveDialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="reserveDo">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
new Vue({
|
||||
el: "#app",
|
||||
dicts: ["FAMILY_SIGNUP_TYPE"],
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
reserveDialogVisible: false,
|
||||
reserveTableData: [],
|
||||
activityList: [],
|
||||
pageForm: {
|
||||
year: new Date().getFullYear().toString(),
|
||||
activityId: null
|
||||
},
|
||||
tableColumns: [
|
||||
{ label: "姓名", prop: "username" },
|
||||
{ label: "工号", prop: "loginname" },
|
||||
{ label: "联系方式", prop: "mobile" },
|
||||
{ label: "单位", prop: "unitName", sortable: true },
|
||||
{ label: "分工会", prop: "unionName", sortable: true },
|
||||
{ label: "课程", prop: "courseNames", sortable: true },
|
||||
{ label: "缺席次数", prop: "absentCount" },
|
||||
{ label: "是否黑名单", prop: "isDisabled", sortable: true }
|
||||
],
|
||||
activityType: "子活动",
|
||||
courseList: [],
|
||||
course: {},
|
||||
reserveMode: 1,
|
||||
multipleSelection: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val
|
||||
},
|
||||
async openReserve() {
|
||||
const activity = this.activityList.find((o) => o.id === this.pageForm.activityId)
|
||||
if (this.$moment().unix() < this.$moment(activity.activityEndTime).unix()) {
|
||||
this.$alert("此活动还未结束,无法补充", "提示", {
|
||||
confirmButtonText: "确定"
|
||||
})
|
||||
return
|
||||
}
|
||||
const resp = await this.$axios.post("/platform/family/userManage/getReserveUser", { courseId: this.course.id })
|
||||
this.reserveTableData = resp.data
|
||||
this.reserveDialogVisible = true
|
||||
},
|
||||
reserveDo() {
|
||||
if (this.multipleSelection.length === 0) {
|
||||
this.$message.warning("请先在左侧多选框中选择要补充的人员")
|
||||
return
|
||||
}
|
||||
this.$confirm("您选择了" + this.multipleSelection.length + "位教职工,确定要进行补充操作吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
})
|
||||
.then(async () => {
|
||||
const ids = this.multipleSelection.map((o) => o.userId)
|
||||
const resp = await this.$axios.post("/platform/family/userManage/reserveSingUp", {
|
||||
ids: JSON.stringify(ids),
|
||||
courseId: this.course.id
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.doSearch()
|
||||
this.multipleSelection = []
|
||||
this.$refs.multipleTable.clearSelection()
|
||||
this.reserveDialogVisible = false
|
||||
}
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
courseChange(val) {
|
||||
const course = this.courseList.find((o) => o.id === val)
|
||||
this.course = course
|
||||
this.reserveMode = course.reserveMode
|
||||
if (this.reserveMode === 2) {
|
||||
this.tableColumns.push({ label: "报名状态", prop: "state", sortable: true })
|
||||
} else {
|
||||
const o = this.tableColumns.find((o) => o.label === "报名状态")
|
||||
if (o !== null && o !== undefined) {
|
||||
this.tableColumns.splice(this.tableColumns.length - 1, 1)
|
||||
}
|
||||
}
|
||||
this.$refs.tool.app = this
|
||||
this.doSearch()
|
||||
},
|
||||
exportSignPerson() {
|
||||
this.exportPro(loc() + "/exportSignPerson", { activityId: this.pageForm.activityId })
|
||||
},
|
||||
exportGiftPerson() {
|
||||
this.exportPro(loc() + "/exportGiftPerson", { activityId: this.pageForm.activityId })
|
||||
},
|
||||
exportPro(url, param) {
|
||||
if (param.activityId === null) {
|
||||
this.$message.warning("请选择活动")
|
||||
return
|
||||
}
|
||||
this.$downLoad(url, param)
|
||||
},
|
||||
async activityChange(val) {
|
||||
const activity = this.activityList.find((o) => o.id === val)
|
||||
const type = this.dict.type.FAMILY_SIGNUP_TYPE.find(o => o.code === activity.activityType)
|
||||
this.activityType = type?.name || "子活动"
|
||||
const resp = await this.$axios.post(loc() + "/getCourseByActivityId", { activityId: val })
|
||||
this.courseList = resp.data
|
||||
this.pageForm.courseId = ""
|
||||
},
|
||||
async handleUser(userId) {
|
||||
const resp = await $.post(loc() + "/doHandleUser", { userId })
|
||||
if (resp.code === 0) {
|
||||
this.$message.success(resp.msg)
|
||||
this.doSearch()
|
||||
}
|
||||
},
|
||||
async yearChange() {
|
||||
this.pageForm.activityId = null
|
||||
await this.getActivityList()
|
||||
await this.doSearch()
|
||||
},
|
||||
async getActivityList() {
|
||||
const resp = await this.$axios.post("/platform/family/statistics/activityList", { year: this.pageForm.year })
|
||||
this.activityList = resp.data
|
||||
if (this.activityList && this.activityList.length > 0) {
|
||||
this.pageForm.activityId = this.activityList[0].id
|
||||
await this.activityChange(this.activityList[0].id)
|
||||
}
|
||||
},
|
||||
async initData() {
|
||||
await this.getActivityList()
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
await this.initData()
|
||||
await this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
@@ -12,225 +12,319 @@ const groupBy = (list, fn) => {
|
||||
})
|
||||
}
|
||||
var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
template: /*language=HTML*/ `
|
||||
<div>
|
||||
<el-tabs tab-position="top" v-model="activeName">
|
||||
<el-tab-pane :label="activityTableData.allName" name="1">
|
||||
<el-card>
|
||||
<el-transfer
|
||||
:data="leftApplyUserList"
|
||||
:filter-method="filterMethod"
|
||||
:props="{key: 'id',label: 'name'}"
|
||||
:titles="['可报人员名单', '当前选择']"
|
||||
filterable
|
||||
ref="transfer"
|
||||
v-model="rightApplyUserList">
|
||||
<template #right-footer>
|
||||
<div class="transfer">
|
||||
<el-select :clearable="false"
|
||||
@change="flushApplyUser(applyUserList)"
|
||||
placeholder="队伍"
|
||||
size="small"
|
||||
v-if="activityTableData.eveProjectType=='2'"
|
||||
v-model="applyFromData.teamId">
|
||||
<el-option
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
v-for="item in teamList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button @click="applyUser" icon="el-icon-plus"
|
||||
size="small"
|
||||
type="primary">
|
||||
参加比赛
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-transfer>
|
||||
template: `
|
||||
<div style="margin: 20px">
|
||||
<el-tabs tab-position="top" v-model="activeName">
|
||||
<el-tab-pane :label="activityTableData.allName" name="1">
|
||||
<el-card>
|
||||
<el-transfer
|
||||
:data="leftApplyUserList"
|
||||
:filter-method="filterMethod"
|
||||
:props="{key: 'id',label: 'name'}"
|
||||
:titles="['可报人员名单', '当前选择']"
|
||||
filterable
|
||||
ref="transfer"
|
||||
v-model="rightApplyUserList">
|
||||
<template #right-footer>
|
||||
<div class="transfer">
|
||||
<el-select :clearable="false"
|
||||
@change="flushApplyUser(applyUserList)"
|
||||
placeholder="队伍"
|
||||
size="small"
|
||||
v-if="activityTableData.eveProjectType=='2'"
|
||||
v-model="applyFromData.teamId">
|
||||
<el-option
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
v-for="item in teamList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button @click="applyUser" icon="el-icon-plus"
|
||||
size="small"
|
||||
type="primary">
|
||||
参加比赛
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-transfer>
|
||||
|
||||
<!-- 个人项目-->
|
||||
<template v-if="activityTableData.eveProjectType==='1'">
|
||||
<div style="display: flex;margin: 20px 0">
|
||||
<el-divider content-position="left">
|
||||
单项报名人数最多{{activityTableData.athleteMaxNum}}
|
||||
人,该队已有{{applyUserTableData.length}}
|
||||
名成员,还可报名{{activityTableData.athleteMaxNum-applyUserTableData.length}}
|
||||
人
|
||||
。
|
||||
</el-divider>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 团体项目-->
|
||||
<template v-if="activityTableData.eveProjectType==='2'">
|
||||
<!-- 如果是只需要报领队 -->
|
||||
<div style="display: flex;margin: 20px 0;align-items: center;"
|
||||
v-if="activityTableData.isLeader">
|
||||
<el-divider content-position="left">每支队伍最少运动员人数
|
||||
{{activityTableData.restrictMaxNum}} 人,最多
|
||||
{{activityTableData.restrictMaxNum}} 人,该队运动员已有
|
||||
{{activityTableData.athleteMaxNum}} 名成员,还可报名
|
||||
{{activityTableData.restrictMaxNum-applyUserTableData.filter(v=>v.identity.includes('1')).length}}
|
||||
人。
|
||||
</el-divider>
|
||||
</div>
|
||||
<!--如果是正常报名-->
|
||||
<template v-if="!activityTableData.isLeader">
|
||||
<div style="display: flex;margin: 20px 0;align-items: center;">
|
||||
<el-divider content-position="left">每支队伍最多
|
||||
{{activityTableData.restrictMaxNum}}
|
||||
人,其中领队{{activityTableData.leanderNum}}人,
|
||||
教练{{activityTableData.coachNum}}人,
|
||||
运动员必须设置{{activityTableData.athleteMaxNum}}人,
|
||||
替补{{activityTableData.substituteNum}}人。
|
||||
男运动员最少{{activityTableData.restrictBoyNum?activityTableData.restrictBoyNum:'0'}}人,
|
||||
女运动员最少{{activityTableData.restrictGirlNum?activityTableData.restrictGirlNum:'0'}}人【该队运动员已有
|
||||
{{applyUserTableData.filter(v=>v.identity.includes('1')).length}}
|
||||
人,还可报名
|
||||
{{activityTableData.athleteMaxNum-applyUserTableData.filter(v=>v.identity.includes('1')).length}}人;
|
||||
替补还可以报{{activityTableData.substituteNum-applyUserTableData.filter(v=>v.identity.includes('5')).length}}人(非必需)】
|
||||
</el-divider>
|
||||
</div>
|
||||
<el-button @click="setUserRole('4')"
|
||||
icon="el-icon-check"
|
||||
plain
|
||||
size="small" type="primary"
|
||||
v-if="activityTableData.deputyDirectorNum>0">
|
||||
设置处级领导
|
||||
</el-button>
|
||||
<el-button @click="setUserRole('3')" icon="el-icon-check" plain
|
||||
size="small"
|
||||
type="primary"
|
||||
v-if="activityTableData.leanderNum>0">设置领队
|
||||
</el-button>
|
||||
<el-button @click="setUserRole('2')" icon="el-icon-check" plain
|
||||
size="small" type="primary"
|
||||
v-if="activityTableData.coachNum>0">
|
||||
设置教练
|
||||
</el-button>
|
||||
<!-- 个人项目-->
|
||||
<template v-if="activityTableData.eveProjectType==='1'">
|
||||
<div style="display: flex;margin: 20px 0">
|
||||
<el-divider content-position="left">
|
||||
单项报名人数最多{{activityTableData.athleteMaxNum}}
|
||||
人,该队已有{{applyUserTableData.length}}
|
||||
名成员,还可报名{{activityTableData.athleteMaxNum-applyUserTableData.length}}
|
||||
人
|
||||
。
|
||||
</el-divider>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 团体项目-->
|
||||
<template v-if="activityTableData.eveProjectType==='2'">
|
||||
<!-- 如果是只需要报领队 -->
|
||||
<div style="display: flex;margin: 20px 0;align-items: center;"
|
||||
v-if="activityTableData.isLeader">
|
||||
<el-divider content-position="left">每支队伍最少运动员人数
|
||||
{{activityTableData.restrictMaxNum}} 人,最多
|
||||
{{activityTableData.restrictMaxNum}} 人,该队运动员已有
|
||||
{{activityTableData.athleteMaxNum}} 名成员,还可报名
|
||||
{{activityTableData.restrictMaxNum-applyUserTableData.filter(v=>v.identity.includes('1')).length}}
|
||||
人。
|
||||
</el-divider>
|
||||
</div>
|
||||
<!--如果是正常报名-->
|
||||
<template v-if="!activityTableData.isLeader">
|
||||
<div style="display: flex;margin: 20px 0;align-items: center;">
|
||||
<el-divider content-position="left">每支队伍最多
|
||||
{{activityTableData.restrictMaxNum}}
|
||||
人,其中领队{{activityTableData.leanderNum}}人,
|
||||
教练{{activityTableData.coachNum}}人,
|
||||
运动员必须设置{{activityTableData.athleteMaxNum}}人,
|
||||
替补{{activityTableData.substituteNum}}人。
|
||||
男运动员最少{{activityTableData.restrictBoyNum?activityTableData.restrictBoyNum:'0'}}人,
|
||||
女运动员最少{{activityTableData.restrictGirlNum?activityTableData.restrictGirlNum:'0'}}人【该队运动员已有
|
||||
{{applyUserTableData.filter(v=>v.identity.includes('1')).length}}
|
||||
人,还可报名
|
||||
{{activityTableData.athleteMaxNum-applyUserTableData.filter(v=>v.identity.includes('1')).length}}人;
|
||||
替补还可以报{{activityTableData.substituteNum-applyUserTableData.filter(v=>v.identity.includes('5')).length}}人(非必需)】
|
||||
</el-divider>
|
||||
<div style="padding-left: 10px">
|
||||
<el-tooltip class="item"
|
||||
content="系统中查询不到的人可以点击添加"
|
||||
effect="dark"
|
||||
placement="top">
|
||||
<el-button
|
||||
:disabled="(activityTableData.restrictMaxNum-applyUserTableData.length)<=0"
|
||||
@click="openAddUser" circle icon="el-icon-plus"
|
||||
type="danger"></el-button>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<el-button @click="setUserRole('4')"
|
||||
icon="el-icon-check"
|
||||
plain
|
||||
size="small" type="primary"
|
||||
v-if="activityTableData.deputyDirectorNum>0">
|
||||
设置处级领导
|
||||
</el-button>
|
||||
<el-button @click="setUserRole('3')" icon="el-icon-check" plain
|
||||
size="small"
|
||||
type="primary"
|
||||
v-if="activityTableData.leanderNum>0">设置领队
|
||||
</el-button>
|
||||
<el-button @click="setUserRole('2')" icon="el-icon-check" plain
|
||||
size="small" type="primary"
|
||||
v-if="activityTableData.coachNum>0">
|
||||
设置教练
|
||||
</el-button>
|
||||
|
||||
<el-button @click="setUserRole('5')" icon="el-icon-check"
|
||||
plain
|
||||
size="small" type="primary"
|
||||
v-if="activityTableData.substituteNum>0">
|
||||
设置替补
|
||||
</el-button>
|
||||
<el-button @click="setUserRole('5')" icon="el-icon-check"
|
||||
plain
|
||||
size="small" type="primary"
|
||||
v-if="activityTableData.substituteNum>0">
|
||||
设置替补
|
||||
</el-button>
|
||||
|
||||
<el-dropdown @command="changeTeam"
|
||||
v-if="activityTableData.eveProjectType==2&&teamList.length>1">
|
||||
<el-button size="small" type="primary">
|
||||
修改小队<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="{item}"
|
||||
:key="item.id" v-for="item in teamList">
|
||||
{{item.name}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
|
||||
<el-table :data="applyUserTableData"
|
||||
@selection-change="handleSelectionChange" border
|
||||
class="mt10" ref="multipleTable"
|
||||
row-key="id" size="small"
|
||||
stripe
|
||||
v-loading="applyUserTabLoading">
|
||||
|
||||
<el-table-column :reserve-selection="true"
|
||||
align="center" header-align="center"
|
||||
type="selection"
|
||||
width="55">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="序号"
|
||||
type="index"
|
||||
width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="所属队"
|
||||
prop="team" width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="姓名"
|
||||
prop="username" width="130">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="教工号"
|
||||
prop="loginname" width="130">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="单位"
|
||||
prop="unitname"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="性别"
|
||||
prop="sex" width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="年龄"
|
||||
prop="age" width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="身份"
|
||||
prop="identity" width="300px">
|
||||
<template scope="{$index,row}">
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'4')"
|
||||
closable
|
||||
effect="light"
|
||||
type="info"
|
||||
v-if="row.identity.includes('4')">处级领导
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'3')"
|
||||
closable
|
||||
effect="light"
|
||||
type="warning"
|
||||
v-if="row.identity.includes('3')">领队
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'2')"
|
||||
closable
|
||||
effect="light"
|
||||
type="success"
|
||||
v-if="row.identity.includes('2')">教练
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'1')"
|
||||
closable
|
||||
effect="light"
|
||||
v-if="row.identity.includes('1')">运动员
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'5')"
|
||||
closable
|
||||
effect="light"
|
||||
type="danger"
|
||||
v-if="row.identity.includes('5')">替补
|
||||
</el-tag>
|
||||
|
||||
<el-dropdown @command="changeTeam"
|
||||
v-if="activityTableData.eveProjectType==2&&teamList.length>1">
|
||||
<el-button size="small" type="primary">
|
||||
修改小队<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item :command="{item}"
|
||||
:key="item.id" v-for="item in teamList">
|
||||
{{item.name}}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-table :data="applyUserTableData"
|
||||
@selection-change="handleSelectionChange" border
|
||||
class="mt10" ref="multipleTable"
|
||||
row-key="id" size="small"
|
||||
stripe
|
||||
v-loading="applyUserTabLoading">
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<el-dialog
|
||||
:append-to-body="true"
|
||||
:visible.sync="addUserDialogVisible"
|
||||
title="添加人员"
|
||||
width="40%"
|
||||
>
|
||||
<el-form :model="formData" label-width="100px" ref="lsryform">
|
||||
<el-form-item label="所在队伍" prop="teamId"
|
||||
:rules="{required: true, message: '请选择所在队伍', trigger: 'blur'}">
|
||||
<el-select clearable disabled placeholder="请选择所在队伍" style="width: 100%"
|
||||
v-model="formData.teamId">
|
||||
<el-option
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
v-for="item in teamList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="姓名" prop="userId" :rules="{required: true, message: '请输入工号或者姓名查询', trigger: 'blur'}">
|
||||
<el-select
|
||||
:remote-method="querySearchAsync"
|
||||
@change="addUserChange"
|
||||
filterable
|
||||
placeholder="请输入工号或者下姓名查询"
|
||||
remote
|
||||
reserve-keyword
|
||||
style="width: 100%"
|
||||
v-model="formData.userId">
|
||||
<el-option
|
||||
:key="item.id"
|
||||
:label="item.username+'-'+item.loginname"
|
||||
:value="item.id"
|
||||
v-for="item in lsUserList">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="工号" prop="loginname" :rules="{required: true, message: '请填写工号', trigger: 'blur'}">
|
||||
<el-input disabled maxlength="50" placeholder="请填写工号"
|
||||
type="text" v-model="formData.loginname"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="sex" :rules="{required: true, message: '性别', trigger: 'blur'}">
|
||||
<el-radio-group v-model="formData.sex">
|
||||
<el-radio :label="'男'" border>男</el-radio>
|
||||
<el-radio :label="'女'" border>女</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="出生年月" prop="birthday" :rules="{required: true, message: '选择出生年月', trigger: 'blur'}">
|
||||
<el-date-picker
|
||||
style="width: 100%"
|
||||
v-model="formData.birthday"
|
||||
type="date"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择出生年月">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="电话" prop="mobile">
|
||||
<el-input maxlength="50" placeholder="请填写电话" type="text"
|
||||
v-model="formData.mobile"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号" prop="idcard">
|
||||
<el-input maxlength="30" placeholder="请填写身份证号" type="text"
|
||||
v-model="formData.idcard"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="所在单位" prop="unitId" :rules="{required: true, message: '请选择所在单位', trigger: 'blur'}">
|
||||
<el-select clearable filterable placeholder="请选择所在单位" style="width: 100%"
|
||||
v-model="formData.unitId">
|
||||
<el-option
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
v-for="item in unitOptions">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table-column :reserve-selection="true"
|
||||
align="center" header-align="center"
|
||||
type="selection"
|
||||
width="55">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="序号"
|
||||
type="index"
|
||||
width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="所属队"
|
||||
prop="team" width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="姓名"
|
||||
prop="username" width="130">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="教工号"
|
||||
prop="loginname" width="130">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="单位"
|
||||
prop="unitname"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="性别"
|
||||
prop="sex" width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="年龄"
|
||||
prop="age" width="80">
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
align="center" header-align="center" label="身份"
|
||||
prop="identity" width="300px">
|
||||
<template scope="{$index,row}">
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'4')"
|
||||
closable
|
||||
effect="light"
|
||||
type="info"
|
||||
v-if="row.identity.includes('4')">处级领导
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'3')"
|
||||
closable
|
||||
effect="light"
|
||||
type="warning"
|
||||
v-if="row.identity.includes('3')">领队
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'2')"
|
||||
closable
|
||||
effect="light"
|
||||
type="success"
|
||||
v-if="row.identity.includes('2')">教练
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'1')"
|
||||
closable
|
||||
effect="light"
|
||||
v-if="row.identity.includes('1')">运动员
|
||||
</el-tag>
|
||||
<el-tag :disable-transitions="false"
|
||||
@close="delApplyUser($index,row,'5')"
|
||||
closable
|
||||
effect="light"
|
||||
type="danger"
|
||||
v-if="row.identity.includes('5')">替补
|
||||
</el-tag>
|
||||
|
||||
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</el-card>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
`,
|
||||
<span class="dialog-footer" slot="footer">
|
||||
<el-button @click="addUserDialogVisible = false">取 消</el-button>
|
||||
<el-button @click="doAddUser" type="primary">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
`,
|
||||
store,
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
@@ -253,10 +347,85 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
applyUserTabLoading: false,
|
||||
selection: [],
|
||||
//全部可报名的人员
|
||||
userList: []
|
||||
userList: [],
|
||||
|
||||
addUserDialogVisible: false,
|
||||
lsUserList: [],
|
||||
unitOptions: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doAddUser() {
|
||||
this.$refs["lsryform"].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const birthDate = this.$moment(this.formData.birthday);
|
||||
const age = this.$moment().diff(birthDate, 'years');
|
||||
const data = {
|
||||
isAddUser: true,
|
||||
age: age,
|
||||
unitname: this.unitOptions.find(x => x.id === this.formData.unitId).name,
|
||||
...this.formData
|
||||
}
|
||||
const newUser = this.userList.find(a => a.id === this.formData.userId)
|
||||
if (newUser) {
|
||||
this.notifyWarning('该用户已存在左侧选择框内,请从左侧选择框内选择!')
|
||||
return
|
||||
}
|
||||
this.applyUserList.push(data)
|
||||
this.flushApplyUser(this.applyUserList)
|
||||
this.sortApplyUserTableData()
|
||||
|
||||
this.$notify.success({title: '成功', message: '已添加'});
|
||||
this.addUserDialogVisible = false
|
||||
} else {
|
||||
this.$notify.error({title: '错误', message: '存在未填写的的必填项'});
|
||||
}
|
||||
})
|
||||
},
|
||||
async addUserChange(val) {
|
||||
const user = this.lsUserList.find(l => l.id === val)
|
||||
this.$set(this.formData, 'eventId', this.eventData.eventId)
|
||||
this.$set(this.formData, 'activityId', this.activityTableData.activityId)
|
||||
this.$set(this.formData, 'team', this.applyFromData.teamName)
|
||||
this.$set(this.formData, 'teamId', this.applyFromData.teamId)
|
||||
this.$set(this.formData, 'userId', user ? user.id : null)
|
||||
this.$set(this.formData, 'loginname', user ? user.loginname : null)
|
||||
this.$set(this.formData, 'username', user ? user.username : null)
|
||||
this.$set(this.formData, 'unitId', user ? user.unitId : null)
|
||||
this.$set(this.formData, 'sex', user ? user.sex : null)
|
||||
this.$set(this.formData, 'idcard', user ? user.idCard : null)
|
||||
this.$set(this.formData, 'mobile', user ? user.mobile : null)
|
||||
this.$set(this.formData, 'birthday', user ? user.birthday : null)
|
||||
this.$set(this.formData, 'awardsMode', this.activityTableData.eveProjectType)
|
||||
this.$set(this.formData, 'status', 2)
|
||||
},
|
||||
async querySearchAsync(queryString) {
|
||||
/* const leftApplyUserList = this.leftApplyUserList.map(m => m.loginname)
|
||||
const rightApplyUserList = this.rightApplyUserList.map(m => m.loginname)
|
||||
const loginnames = leftApplyUserList.concat(rightApplyUserList)*/
|
||||
|
||||
const loginnames = this.applyUserTableData.map(m => m.loginname)
|
||||
const {code, data} = await $.get("/platform/activity/apply/getSysUser", {
|
||||
loginnames: JSON.stringify(loginnames),
|
||||
queryString: queryString
|
||||
})
|
||||
if (code === 0) {
|
||||
this.lsUserList = data
|
||||
} else {
|
||||
this.lsUserList = []
|
||||
}
|
||||
},
|
||||
openAddUser() {
|
||||
this.formData = {
|
||||
teamName: this.applyFromData.teamName,
|
||||
teamId: this.applyFromData.teamId,
|
||||
identity: ['1']
|
||||
}
|
||||
this.addUserDialogVisible = true
|
||||
if (this.$refs['lsryform']) {
|
||||
this.$refs['lsryform'].resetFields()
|
||||
}
|
||||
},
|
||||
async openUniteApply(data) {
|
||||
this.activityTableData = data
|
||||
//固定模式
|
||||
@@ -299,7 +468,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
isMenWomenTwo: data.isMenWomen
|
||||
})
|
||||
if (resp.code === 0) {
|
||||
const { users, awardsModeT, awardsModeG, team, activity, getEvent } = resp.data
|
||||
const {users, awardsModeT, awardsModeG, team, activity, getEvent} = resp.data
|
||||
this.activityData = activity
|
||||
this.eventData = getEvent
|
||||
this.teamList = team
|
||||
@@ -332,7 +501,16 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
let message = null
|
||||
|
||||
if (flag) {
|
||||
const { athletesMaxNum, restrictGirlNum, restrictBoyNum, leanderNum, coachNum, deputyDirectorNum, substituteNum, projectType } =
|
||||
const {
|
||||
athletesMaxNum,
|
||||
restrictGirlNum,
|
||||
restrictBoyNum,
|
||||
leanderNum,
|
||||
coachNum,
|
||||
deputyDirectorNum,
|
||||
substituteNum,
|
||||
projectType
|
||||
} =
|
||||
this.eventData
|
||||
|
||||
const applyUserList = clone(this.applyUserList)
|
||||
@@ -388,7 +566,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
message = teamName + "女运动员至少设置" + restrictGirlNum + "人"
|
||||
break
|
||||
}
|
||||
const manYdyNum = teamApplyData[i].filter((v) => v.sex === "女" && v.identity.includes("1")).length
|
||||
const manYdyNum = teamApplyData[i].filter((v) => v.sex === "男" && v.identity.includes("1")).length
|
||||
if (restrictBoyNum > 0 && manYdyNum < restrictBoyNum) {
|
||||
msgFlag = false
|
||||
message = teamName + "男运动员至少设置" + restrictBoyNum + "人"
|
||||
@@ -397,7 +575,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
}
|
||||
}
|
||||
if (!msgFlag && !this.activityTableData.isLeader) {
|
||||
this.$notify.warning({ title: "警告", message: message })
|
||||
this.$notify.warning({title: "警告", message: message})
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -406,7 +584,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
if (!flag) {
|
||||
msg = "确定要保存吗?"
|
||||
}
|
||||
const confirm = await this.$confirm(msg, "提示", { type: "warning" })
|
||||
const confirm = await this.$confirm(msg, "提示", {type: "warning"})
|
||||
if (confirm === "confirm") {
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
@@ -432,15 +610,15 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
},
|
||||
//点击添加运动员操作
|
||||
async applyUser() {
|
||||
const { isManGirlNum, restrictGirlNum, restrictBoyNum } = this.eventData
|
||||
const {isManGirlNum, restrictGirlNum, restrictBoyNum} = this.eventData
|
||||
|
||||
if (!this.rightApplyUserList.length) {
|
||||
this.$notify.warning({ title: "警告", message: "请在右侧列表中选择人员" })
|
||||
this.$notify.warning({title: "警告", message: "请在右侧列表中选择人员"})
|
||||
return
|
||||
}
|
||||
|
||||
//如果是单项
|
||||
if (this.activityTableData.eveProjectType === "1") {
|
||||
if (this.activityTableData.eveProjectType === '1') {
|
||||
if (this.applyUserTableData.length + this.rightApplyUserList.length > this.activityTableData.athleteMaxNum) {
|
||||
this.$notify({
|
||||
title: "警告",
|
||||
@@ -492,7 +670,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
}
|
||||
}
|
||||
|
||||
const resp = await this.$axios.post(loc() + "/getActivityData", { activityId: this.activityData.id })
|
||||
const resp = await this.$axios.post(loc() + "/getActivityData", {activityId: this.activityData.id})
|
||||
const aa = resp.data.filter((v) => {
|
||||
return this.rightApplyUserList.includes(v.userId)
|
||||
})
|
||||
@@ -532,7 +710,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
this.applyUserList.push(data)
|
||||
|
||||
//如果是单项判断每个人可以报几项
|
||||
if (this.eventData.restrictRegNumber >= 0 && this.activityTableData.eveProjectType === "1") {
|
||||
if (this.eventData.restrictRegNumber >= 0 && this.activityTableData.eveProjectType === '1') {
|
||||
cc.forEach((z) => {
|
||||
if (z[0]) {
|
||||
const index = this.applyUserList.findIndex((x) => x.userId === z[0].userId && x.id === null)
|
||||
@@ -545,7 +723,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
})
|
||||
|
||||
//如果是单项判断每个人可以报几项
|
||||
if (this.eventData.restrictRegNumber >= 0 && this.activityTableData.eveProjectType === "1") {
|
||||
if (this.eventData.restrictRegNumber >= 0 && this.activityTableData.eveProjectType === '1') {
|
||||
const usernames = cc.map((v) => v[0].username).join(",")
|
||||
if (usernames) {
|
||||
this.$notify({
|
||||
@@ -586,7 +764,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
this.$refs.multipleTable.clearSelection()
|
||||
},
|
||||
changeTeam(command) {
|
||||
const { item } = command
|
||||
const {item} = command
|
||||
if (!this.selection.length) {
|
||||
this.$notify({
|
||||
title: "警告",
|
||||
@@ -616,7 +794,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
this.$refs.multipleTable.clearSelection()
|
||||
},
|
||||
async findUserOne(id) {
|
||||
const { data } = await this.$axios.post(loc() + "/findUserOne", { id })
|
||||
const {data} = await this.$axios.post(loc() + "/findUserOne", {id})
|
||||
return data
|
||||
},
|
||||
async delApplyUser(index, row, num) {
|
||||
@@ -666,6 +844,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
getTransProp(user) {
|
||||
return {
|
||||
id: user.id,
|
||||
loginname: user.loginname,
|
||||
name: user.username + "(" + (user.sex ? user.sex : "") + "-" + user.loginname + ")"
|
||||
}
|
||||
},
|
||||
@@ -681,5 +860,8 @@ var ACTIVITY_SPORTS_APPLY_USER = {
|
||||
this.userList = []
|
||||
}
|
||||
},
|
||||
async created() {}
|
||||
async created() {
|
||||
this.unitOptions = await this.$businessTool.listUnit()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,7 +237,7 @@ layout("/layouts/platform.html"){
|
||||
</template>
|
||||
|
||||
<template #public>
|
||||
<activity-sports-delete-user @flip="flip" ref="activityDeleteUser"></activity-sports-delete-user>
|
||||
<activity-sports-delete-user @flip="doSearch" ref="activityDeleteUser"></activity-sports-delete-user>
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ let ACTIVITY_SPORTS_ADD_ACTIVITY = {
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
<el-form-item prop="files" label="封面图" v-if="formData.applyWay.includes(1)">
|
||||
<el-form-item prop="files" label="封面图" >
|
||||
<file-upload
|
||||
:value.sync="formData.image"
|
||||
:upload_number="1"
|
||||
|
||||
@@ -16,11 +16,16 @@ const apply_component = {
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="birthday" label="出生日期">
|
||||
<el-date-picker v-model="formData.birthday" type="date" placeholder="选择日期" value-format="yyyy-MM-dd" style="width: 100%"></el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- <el-col :span="12">-->
|
||||
<!-- <el-form-item prop="birthday" label="出生日期">-->
|
||||
<!-- <el-date-picker v-model="formData.birthday" type="date" placeholder="选择日期" value-format="yyyy-MM-dd" style="width: 100%"></el-date-picker>-->
|
||||
<!-- </el-form-item>-->
|
||||
<!-- </el-col>-->
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="governmentPosition" label="党政职务">
|
||||
<el-input v-model="formData.governmentPosition" placeholder="填写党政职务" max="50"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="sex" label="性别" disabled>
|
||||
<el-input v-model="formData.sex" disabled></el-input>
|
||||
@@ -69,11 +74,7 @@ const apply_component = {
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="governmentPosition" label="党政职务">
|
||||
<el-input v-model="formData.governmentPosition" placeholder="填写党政职务" max="50"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@@ -236,7 +237,7 @@ const apply_component = {
|
||||
this.$set(this.formData, "unionId", user.union ? user.union.id : null)
|
||||
this.$set(this.formData, "unionName", user.union ? user.union.name : null)
|
||||
this.$set(this.formData, "sex", user.sex)
|
||||
this.$set(this.formData, "birthday", user.birthday)
|
||||
// this.$set(this.formData, "birthday", user.birthday)
|
||||
this.$set(this.formData, "nation", user.nation)
|
||||
this.$set(this.formData, "political", user.political)
|
||||
this.$set(this.formData, "education", user.education)
|
||||
|
||||
@@ -150,6 +150,7 @@ layout("/layouts/platform.html"){
|
||||
columnStyle: {
|
||||
radius: [20, 20, 0, 0],
|
||||
},
|
||||
maxColumnWidth: 50
|
||||
})
|
||||
singleLevelTypePlot.render()
|
||||
}
|
||||
|
||||
@@ -5,9 +5,10 @@ layout("/layouts/platform.html"){
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<!-- <search-item label="年度">-->
|
||||
<!-- <el-date-picker placeholder="选择年度" type="year" style="width: 100%" v-model="pageForm.year" value-format="yyyy"></el-date-picker>-->
|
||||
<!-- </search-item>-->
|
||||
<!-- <search-item label="年度">-->
|
||||
<!-- <el-date-picker placeholder="选择年度" type="year" style="width: 100%" v-model="pageForm.year"-->
|
||||
<!-- value-format="yyyy"></el-date-picker>-->
|
||||
<!-- </search-item>-->
|
||||
<search-item label="活动">
|
||||
<el-select v-model="pageForm.actId" placeholder="请选择活动">
|
||||
<el-option v-for="item in actOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
|
||||
@@ -146,6 +146,7 @@ layout("/layouts/platform.html"){
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.$store.dispatch("pjaxRoute", "/platform/warmthCondolence/mine")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+2
-2
@@ -129,13 +129,13 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
})
|
||||
},
|
||||
doDelete(id) {
|
||||
doDelete(row) {
|
||||
this.$confirm("您确定要删除吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
this.$axios.post("/platform/warmthCondolenceNotice/delete", { id: id }).then((res) => {
|
||||
this.$axios.post("/platform/warmthCondolenceNotice/delete", { id: row.id }).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.doSearch()
|
||||
|
||||
+1
@@ -153,6 +153,7 @@ const MEMBER_AUDIT_CHANGE_INFO = {
|
||||
})
|
||||
},
|
||||
onOpen(data) {
|
||||
console.log(data)
|
||||
this.findAuditChangeInfo(data.recordId)
|
||||
this.$nextTick(() => {
|
||||
this.findUserInfo(data.userId)
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ const MEMBER_AUDIT_TABLE = {
|
||||
:sortable="column.sortable" :width="column.width"
|
||||
align="center" header-align="center" min-width="100px"
|
||||
show-overflow-tooltip>
|
||||
<template slot-scope="{row}" v-if="column.prop=='loginname'">
|
||||
<template scope="{row}" v-if="column.prop=='loginname'">
|
||||
<el-link @click="openView(row.userId)" type="primary">{{row.loginname}}</el-link>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
+23
-15
@@ -32,6 +32,9 @@ const MEMBER_MANAGE_TABLE = {
|
||||
</div>-->
|
||||
|
||||
<!--<el-button @click="addMember" type="primary" size="small">新增会员</el-button>-->
|
||||
|
||||
<el-button type="primary" size="small" icon="el-icon-printer" @click="exportExcel">导出会员名单
|
||||
</el-button>
|
||||
</table-tool>
|
||||
|
||||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder" ref="table" row-key="id"
|
||||
@@ -114,8 +117,8 @@ const MEMBER_MANAGE_TABLE = {
|
||||
查看
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
:command="{type:'change',data:row}"
|
||||
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','BRANCH_UNION_CHAIRMAN','BRANCH_UNION_CHAIRMAN'])">
|
||||
:command="{type:'change',data:row}"
|
||||
v-if="$auth.hasRoleOr(['SYSADMIN','SCHOOL_UNION_ADMIN','BRANCH_UNION_CHAIRMAN','BRANCH_UNION_CHAIRMAN'])">
|
||||
变更
|
||||
</el-dropdown-item>
|
||||
<!--<el-dropdown-item
|
||||
@@ -149,15 +152,16 @@ const MEMBER_MANAGE_TABLE = {
|
||||
return {
|
||||
changeTypeData: [],
|
||||
tableColumns: [
|
||||
{ prop: "loginname", label: "工号", sortable: true },
|
||||
{ prop: "username", label: "姓名", sortable: true },
|
||||
{ prop: "sex", label: "性别", sortable: true, width: "100px" },
|
||||
{ prop: "birthday", label: "出生年月", sortable: true },
|
||||
{ prop: "userState", label: "在职状态", sortable: true },
|
||||
{ prop: "preparedBy", label: "聘用方式", sortable: true },
|
||||
{ prop: "personType", label: "人员类型", sortable: true },
|
||||
{ prop: "unionName", label: "所属工会", sortable: true },
|
||||
{ prop: "unitName", label: "所属单位", sortable: true }
|
||||
{prop: "loginname", label: "工号", sortable: true},
|
||||
{prop: "username", label: "姓名", sortable: true},
|
||||
{prop: "sex", label: "性别", sortable: true, width: "100px"},
|
||||
{prop: "birthday", label: "出生年月", sortable: true},
|
||||
{prop: "userState", label: "在职状态", sortable: true},
|
||||
{prop: "preparedBy", label: "聘用方式", sortable: true},
|
||||
{prop: "postDoctoralJoinDate", label: "进站时间", sortable: true},
|
||||
{prop: "personType", label: "人员类型", sortable: true},
|
||||
{prop: "unionName", label: "所属工会", sortable: true},
|
||||
{prop: "unitName", label: "所属单位", sortable: true}
|
||||
],
|
||||
changeInfoVisible: false,
|
||||
userId: "",
|
||||
@@ -169,7 +173,7 @@ const MEMBER_MANAGE_TABLE = {
|
||||
},
|
||||
methods: {
|
||||
dropdownCommand(command) {
|
||||
const { type, data } = command
|
||||
const {type, data} = command
|
||||
if (type === "view") {
|
||||
this.openView(data.id)
|
||||
} else if (type === "change") {
|
||||
@@ -187,7 +191,7 @@ const MEMBER_MANAGE_TABLE = {
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/member/modelWorker/manage/setModelWorker", { userId: userId }).then((res) => {
|
||||
this.$axios.post("/platform/member/modelWorker/manage/setModelWorker", {userId: userId}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
this.$emit("refresh-table")
|
||||
@@ -204,7 +208,7 @@ const MEMBER_MANAGE_TABLE = {
|
||||
type: "warning"
|
||||
})
|
||||
.then(() => {
|
||||
this.$axios.post("/platform/member/modelWorker/manage/cancelModelWorker", { userIds: JSON.stringify([userId]) })
|
||||
this.$axios.post("/platform/member/modelWorker/manage/cancelModelWorker", {userIds: JSON.stringify([userId])})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success(res.msg)
|
||||
@@ -216,7 +220,7 @@ const MEMBER_MANAGE_TABLE = {
|
||||
})
|
||||
},
|
||||
openChange(data) {
|
||||
this.$emit("change-member", { id: data.id, username: data.username })
|
||||
this.$emit("change-member", {id: data.id, username: data.username})
|
||||
},
|
||||
openView(id) {
|
||||
this.$emit("view-member", id)
|
||||
@@ -249,6 +253,10 @@ const MEMBER_MANAGE_TABLE = {
|
||||
this.$emit("refresh", this.pageForm)
|
||||
}
|
||||
})
|
||||
},
|
||||
exportExcel() {
|
||||
const pageForm = clone(this.pageForm)
|
||||
this.$downLoad(loc() + "/doExport", pageForm)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
@@ -191,8 +191,8 @@ layout("/layouts/platform_h5.html"){
|
||||
<van-icon name="location-o"></van-icon>
|
||||
报名方式:
|
||||
<span v-if="viewData.signUpMethod===1" style="color: var(--color-primary)">个人报名</span>
|
||||
<span v-if="viewData.signUpMethod===2" style="color: var(--color-primary)">分工会报名</span>
|
||||
<span v-if="viewData.signUpMethod===3" style="color: var(--color-primary)">组队报名</span>
|
||||
<span v-if="viewData.signUpMethod===2" style="color: var(--color-primary)">组队报名</span>
|
||||
<span v-if="viewData.signUpMethod===3" style="color: var(--color-primary)">分工会报名</span>
|
||||
</div>
|
||||
<div class="info-item" v-if="viewData.signUpMethod==3">
|
||||
<van-icon name="location-o"></van-icon>
|
||||
@@ -277,6 +277,51 @@ layout("/layouts/platform_h5.html"){
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分工会报名-->
|
||||
<div v-else-if="viewData.signUpMethod===3" class="block">
|
||||
<div class="notice-title left-tag-title">选择报名人员
|
||||
<span v-if="viewData.userNumberLimit===2">
|
||||
,报名人数 <span style="color: red">
|
||||
{{viewData.unionTeamNum}}</span>人
|
||||
</span>
|
||||
</div>
|
||||
<el-select
|
||||
v-if="inApplyTime"
|
||||
v-model="searchTeammateUserId"
|
||||
filterable
|
||||
clearable
|
||||
remote
|
||||
reserve-keyword
|
||||
placeholder="请输入关键词"
|
||||
:remote-method="queryTeammate">
|
||||
<el-option
|
||||
v-for="item in teammateOptions"
|
||||
:key="item.userId"
|
||||
:label="item.userName + '(' + item.loginName + ')'"
|
||||
:value="item.userId">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button v-if="inApplyTime" class="ml5" type="primary" icon="el-icon-plus"
|
||||
@click="addTeamUser">添加
|
||||
</el-button>
|
||||
|
||||
<el-table :data="teamUsers" class="mt10">
|
||||
<el-table-column label="序号" type="index" width="60px"></el-table-column>
|
||||
<el-table-column prop="userName" label="姓名"></el-table-column>
|
||||
<el-table-column prop="loginName" label="工号"></el-table-column>
|
||||
<!-- <el-table-column prop="sex" label="性别"></el-table-column>-->
|
||||
<!-- <el-table-column prop="unitName" label="单位"></el-table-column>-->
|
||||
<!-- <el-table-column prop="mobile" label="手机号"></el-table-column>-->
|
||||
<el-table-column label="操作" width="100px"
|
||||
v-if="inApplyTime">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="danger" size="mini" @click="removeTeamUser(scope.$index)">删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
|
||||
<div class="form-create-h5" v-if="isCustomForm">
|
||||
<div class="notice-title left-tag-title">填写报名信息</div>
|
||||
<form-create :value.sync="dynamicFormData" v-model="fapi" :rule="formCreateRule"
|
||||
@@ -362,11 +407,22 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$axios.post("/platform/activity/culture/infoManage/activityInfo", {id: this.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.viewData = res.data
|
||||
//总人数限制
|
||||
if (this.viewData.userNumberLimit === 1) {
|
||||
} else if (this.viewData.userNumberLimit === 2) {
|
||||
//分工会人数限制
|
||||
const union = this.viewData.unionUserNumberLimit.find(v => v.id === this.$store.state.user.union.id)
|
||||
this.viewData.unionTeamNum = union.limitNum
|
||||
}
|
||||
if (this.viewData.signUpMethod === 3) {
|
||||
this.listTeamUserUnion()
|
||||
} else {
|
||||
this.listTeamUser()
|
||||
}
|
||||
if (this.viewData.formConfig) {
|
||||
this.formCreateRule = formCreate.parseJson(this.viewData.formConfig.rule)
|
||||
this.formCreateOption = formCreate.parseJson(this.viewData.formConfig.options)
|
||||
}
|
||||
this.listTeamUser()
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -382,6 +438,17 @@ layout("/layouts/platform_h5.html"){
|
||||
}
|
||||
})
|
||||
},
|
||||
//查询报名人员
|
||||
listTeamUserUnion() {
|
||||
this.$axios.post("/platform/activity/culture/applyUser/listTeamUserUnion", {activityId: this.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.isSignUp = res.data.length > 0
|
||||
this.teamUsers = res.data
|
||||
this.defaultAddSelf()
|
||||
this.customFormInit()
|
||||
}
|
||||
})
|
||||
},
|
||||
//表单回显
|
||||
customFormInit() {
|
||||
if (this.teamUsers && this.teamUsers.length > 0) {
|
||||
@@ -467,7 +534,7 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.teamUsers.length > this.viewData.teamNum) {
|
||||
if (this.viewData.teamNum && this.teamUsers.length > this.viewData.teamNum) {
|
||||
this.$dialog
|
||||
.alert({
|
||||
title: "提示",
|
||||
@@ -499,7 +566,11 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$axios.post("/platform/activity/culture/applyUser/signUp", formData).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.listTeamUser()
|
||||
if (this.viewData.signUpMethod === 3) {
|
||||
this.listTeamUserUnion()
|
||||
} else {
|
||||
this.listTeamUser()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -568,7 +639,7 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.teamUsers.length > this.viewData.teamNum) {
|
||||
if (this.viewData.teamNum && this.teamUsers.length > this.viewData.teamNum) {
|
||||
this.$dialog
|
||||
.alert({
|
||||
title: "提示",
|
||||
@@ -601,7 +672,11 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$axios.post("/platform/activity/culture/applyUser/signUp", formData).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.listTeamUser()
|
||||
if (this.viewData.signUpMethod === 3) {
|
||||
this.listTeamUserUnion()
|
||||
} else {
|
||||
this.listTeamUser()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
@@ -618,7 +693,11 @@ layout("/layouts/platform_h5.html"){
|
||||
this.$axios.post("/platform/activity/culture/applyUser/cancelSignUp", {activityId: this.id}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$toast.success(res.msg)
|
||||
this.listTeamUser()
|
||||
if (this.viewData.signUpMethod === 3) {
|
||||
this.listTeamUserUnion()
|
||||
} else {
|
||||
this.listTeamUser()
|
||||
}
|
||||
this.fapi.resetFields()
|
||||
}
|
||||
})
|
||||
@@ -628,7 +707,10 @@ layout("/layouts/platform_h5.html"){
|
||||
//查询队友信息
|
||||
queryTeammate(val) {
|
||||
if (val) {
|
||||
this.$axios.post("/platform/activity/culture/applyUser/queryTeammate", {keyword: val}).then((res) => {
|
||||
this.$axios.post("/platform/activity/culture/applyUser/queryTeammate", {
|
||||
keyword: val,
|
||||
signUpMethod: this.viewData.signUpMethod
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
res.data.map(v => {
|
||||
v.applyUserId = this.$store.state.user.id
|
||||
@@ -663,7 +745,7 @@ layout("/layouts/platform_h5.html"){
|
||||
})
|
||||
return
|
||||
}
|
||||
if (this.teamUsers.length >= this.viewData.teamNum) {
|
||||
if (this.viewData.teamNum && this.teamUsers.length >= this.viewData.teamNum) {
|
||||
this.$dialog
|
||||
.alert({
|
||||
title: "提示",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user