Merge remote-tracking branch 'origin/main'

This commit is contained in:
@jyuhsin
2025-09-25 21:34:42 +08:00
59 changed files with 2492 additions and 412 deletions
@@ -14,6 +14,7 @@ import com.budwk.app.flow.entity.ProcessInstance;
import com.budwk.app.flow.entity.ProcessTask;
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.models.Sys_user_role;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
@@ -136,6 +137,11 @@ public class ActivityCultureApplyActivityController {
flowEngine.executeProcessTask(task.getId(), SecurityUtil.getUserId(), args);
}
return Result.success();
}else{
if (tissue.getIsUnseal()) {
Sys_home_activity sysHomeActivity = tissue.covertToSysHomeActivity();
activityCultureService.insertOrUpdate(sysHomeActivity);
}
}
return Result.success();
}
@@ -11,6 +11,8 @@ 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.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.basic.models.ActivityUserScope;
import com.budwk.app.zhgh.activity.culture.models.ActivityTissue;
import com.budwk.app.zhgh.activity.culture.models.ActivityTissuePerson;
import com.budwk.app.zhgh.activity.culture.service.ActivityCultureApplyUserService;
import io.swagger.annotations.ApiOperation;
@@ -83,6 +85,13 @@ public class ActivityCultureApplyUserController {
@SaCheckLogin
@ApiOperation(value = "报名")
public Result signUp(@Valid String activityId, @Param("teamUserIds") String[] teamUserIds, @Param("ext") String formData, boolean isAgain) {
ActivityTissue tissue = dao.fetch(ActivityTissue.class, activityId);
int count = dao.count(ActivityUserScope.class,
Cnd.where(ActivityUserScope::getUserId, "=", SecurityUtil.getUserId())
.and(ActivityUserScope::getGroupId, "=", tissue.getGroupId()));
if (count == 0){
return Result.error("您没有权限报名!");
}
JSONObject dynamicFormParam = null;
if (StrUtil.isNotBlank(formData)) {
dynamicFormParam = Json.fromJson(JSONObject.class, formData);
@@ -2,24 +2,29 @@ package com.budwk.app.zhgh.activity.culture.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaMode;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.model.Audit;
import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.result.Result;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import com.budwk.app.flow.service.FlowCommonService;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.activity.culture.models.ActivityTissue;
import com.budwk.app.zhgh.activity.culture.service.ActivityCultureService;
import org.nutz.dao.Chain;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
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.json.Json;
import org.nutz.lang.Strings;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;
import java.util.List;
@@ -50,6 +55,9 @@ public class ActivityCultureAuditActivityController {
@Inject
private ActivityCultureService activityCultureService;
@Inject
private FlowCommonService flowCommonService;
@At
@SaCheckPermission(value = {"activity.culture.auditActivity.union", "activity.culture.auditActivity.club"}, mode = SaMode.OR)
@@ -124,14 +132,16 @@ public class ActivityCultureAuditActivityController {
@At
@SLog(tag = "文化活动", msg = "校工会审核了一条记录")
@Aop(TransAop.READ_COMMITTED)
@SaCheckPermission(value = {"activity.culture.auditActivity.union", "activity.culture.auditActivity.club"}, mode = SaMode.OR)
public Result doReview(String id, boolean flag, Audit audit) {
audit.setLoginname(SecurityUtil.getUserLoginname());
activityCultureService.insert(audit);
activityCultureService.dao().update(ActivityTissue.class,
Chain.make("state", flag ? 3 : 2)
.add("auditId", audit.getId()),
Cnd.where("id", "=", id));
public Result doReview(@Param("data") String param, String id) {
Dict args = Json.fromJson(Dict.class, param);
ActivityTissue tissue = activityCultureService.dao().fetch(ActivityTissue.class, id);
if (tissue.getIsUnseal() && args.getInt("submitType") == 1) {
Sys_home_activity sysHomeActivity = tissue.covertToSysHomeActivity();
activityCultureService.insertOrUpdate(sysHomeActivity);
}
flowCommonService.executeTask(args);
return Result.success();
}
@@ -1,11 +1,15 @@
package com.budwk.app.zhgh.activity.culture.models;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import com.budwk.app.base.model.BaseModel;
import com.budwk.app.base.model.CustomFormField;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.services.SysHomeConvert;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.nutz.dao.entity.annotation.*;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import java.io.Serializable;
@@ -21,7 +25,7 @@ import java.util.List;
@Data
@Comment("文化活动表")
@Table("activity_tissue")
public class ActivityTissue extends BaseModel implements Serializable {
public class ActivityTissue extends BaseModel implements Serializable, SysHomeConvert {
@Column
@Name
@@ -253,4 +257,27 @@ public class ActivityTissue extends BaseModel implements Serializable {
private String username;
private String loginname;
@Override
public Sys_home_activity covertToSysHomeActivity() {
Sys_home_activity sysHomeActivity = new Sys_home_activity();
sysHomeActivity.setId(this.getId());
sysHomeActivity.setName(this.getName());
sysHomeActivity.setCover(this.getCover());
if (this.getActivity_type()==40001){
sysHomeActivity.setUrl("/platform/activity/culture/applyUser/school");
}else if (this.getActivity_type()==40002){
sysHomeActivity.setUrl("/platform/activity/culture/applyUser/union");
}else{
sysHomeActivity.setUrl("/platform/activity/culture/applyUser/club");
}
sysHomeActivity.setH5Url("/platform/h5/activity/culture/signUp?id=" + this.getId());
if (Lang.isNotEmpty(this.getApplyStartTime())) {
sysHomeActivity.setStartDate(DateUtil.parseDate(this.getApplyStartTime()));
sysHomeActivity.setEndDate(DateUtil.parseDate(this.getApplyEndTime()));
}
sysHomeActivity.setAllowUserGroupId(this.getGroupId());
sysHomeActivity.setEnable(this.getIsUnseal());
sysHomeActivity.setClassPath(this.getClass().getPackageName() + this.getClass().getName());
return sysHomeActivity;
}
}
@@ -162,14 +162,21 @@ public class ActivitySchoolApply extends BaseModel implements Serializable {
@Excel(name = "姓名", width = 20)
@ColDefine(type = ColType.VARCHAR, width = 50)
private String username;
@Column
@Comment("电话")
@Excel(name = "手机号码", width = 20)
@ColDefine(type = ColType.VARCHAR, width = 50)
private String mobile;
@Column
@Comment("职级")
@Excel(name = "职级", width = 20)
@ColDefine(type = ColType.VARCHAR, width = 50)
private String professionalLevel;
@Excel(name = "身份证号", width = 20)
// @Excel(name = "身份证号", width = 20)
private String idCard;
@Column
@@ -178,7 +185,7 @@ public class ActivitySchoolApply extends BaseModel implements Serializable {
@ColDefine(type = ColType.VARCHAR, width = 50)
private String sex;
@Excel(name = "在职状态", width = 20)
// @Excel(name = "在职状态", width = 20)
private String userState;
@Excel(name = "身份", width = 40)
@@ -282,6 +282,7 @@ public class ActivitySportsApplyUserServiceImpl extends BaseServiceImpl<Activity
u.loginname,
u.sex,
u.birthday,
u.professionalLevel,
u.mobile,
un.`name` unitname
FROM
@@ -200,7 +200,7 @@ public class ActivitySportsServiceImpl extends BaseServiceImpl<ActivitySchool> i
app.activityUnionName unionname,
app.sex,
app.mobile,
u.idCard,
app.professionalLevel,
u.userState,
ev.allName,
sc.`name` activityName,
@@ -53,7 +53,7 @@ public class AssetStocktakingServiceImpl extends BaseServiceImpl<AssetStocktakin
group.orLike("t1.assetName", pageForm.getSearchKeyword());
cnd.and(group);
}
if (!AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name())) {
if (!AuthUtil.hasRole(RoleConstant.SYSADMIN.name()) || !AuthUtil.hasRole(RoleConstant.SCHOOL_UNION_ADMIN.name())) {
cnd.and("t1.assetUseUnionId", "=", SecurityUtil.getUnionId());
}
if (pageForm.getIsStocktaking() != null) {
@@ -208,6 +208,9 @@ public class TeacherCongressDelegatePushController {
tmd.setSeniorTeacher(false);
tmd.setSchoolLeader(false);
tmd.setMiddleLevelLeader(false);
tmd.setIntermediateBelow(false);
tmd.setCadre(false);
tmd.setWorker(false);
tmd.setMobile(user.getMobile());
@@ -311,8 +314,14 @@ public class TeacherCongressDelegatePushController {
int total = writeList.size();
// 已上报女代表人数
int female = (int) writeList.stream().filter(v -> List.of("", "女性").contains(v.getString("sex"))).count();
// 已上报高级职称专任教师人数
// 已上报高级职称人数
int seniorTeacher = (int) writeList.stream().filter(v -> v.getBoolean("seniorTeacher")).count();
//已上报中级职称及以下代表数
int intermediateBelow = (int) writeList.stream().filter(v -> v.getBoolean("intermediateBelow")).count();
//已上报干部代表数
int cadre = (int) writeList.stream().filter(v -> v.getBoolean("cadre")).count();
//已上报工人代表数
int worker = (int) writeList.stream().filter(v -> v.getBoolean("worker")).count();
// 已上报专任教师人数
int ordinaryTeacher = (int) writeList.stream().filter(v -> v.getBoolean("ordinaryTeacher")).count();
// 已上报45岁以下代表
@@ -400,6 +409,12 @@ public class TeacherCongressDelegatePushController {
int female = (int) writeList.stream().filter(v -> List.of("", "女性").contains(v.getString("sex"))).count();
// 高级职称专任教师人数
int seniorTeacher = (int) writeList.stream().filter(v->v.getBoolean("seniorTeacher")).count();
// 中级职称及以下
int intermediateBelow = (int) writeList.stream().filter(v->v.getBoolean("intermediateBelow")).count();
// 干部
int cadre = (int) writeList.stream().filter(v->v.getBoolean("cadre")).count();
// 工人
int worker = (int) writeList.stream().filter(v->v.getBoolean("worker")).count();
// 专任教师人数
int ordinaryTeacher = (int) writeList.stream().filter(v->v.getBoolean("ordinaryTeacher")).count();
// 45岁以下代表
@@ -434,6 +449,27 @@ public class TeacherCongressDelegatePushController {
seniorTeaMap.put("remaining", allocation.getSeniorTeaNum() - seniorTeacher);
hashMap.put("seniorTeacher", seniorTeaMap);
HashMap<String, Object> intermediateBelowMap = new HashMap<>();
intermediateBelowMap.put("current", intermediateBelow);
intermediateBelowMap.put("target", allocation.getIntermediateBelowNum());
intermediateBelowMap.put("progress", allocation.getIntermediateBelowNum() != 0 ? (double) intermediateBelow / allocation.getIntermediateBelowNum() : 0.0);
intermediateBelowMap.put("remaining", allocation.getIntermediateBelowNum() - intermediateBelow);
hashMap.put("intermediateBelow", intermediateBelowMap);
HashMap<String, Object> cadreMap = new HashMap<>();
cadreMap.put("current", cadre);
cadreMap.put("target", allocation.getCadreNum());
cadreMap.put("progress", allocation.getCadreNum() != 0 ? (double) cadre / allocation.getCadreNum() : 0.0);
cadreMap.put("remaining", allocation.getCadreNum() - cadre);
hashMap.put("cadre", cadreMap);
HashMap<String, Object> workerMap = new HashMap<>();
workerMap.put("current", worker);
workerMap.put("target", allocation.getWorkerNum());
workerMap.put("progress", allocation.getWorkerNum() != 0 ? (double) worker / allocation.getWorkerNum() : 0.0);
workerMap.put("remaining", allocation.getWorkerNum() - cadre);
hashMap.put("worker", workerMap);
HashMap<String, Object> ordinaryTeaMap = new HashMap<>();
ordinaryTeaMap.put("current", ordinaryTeacher);
ordinaryTeaMap.put("target", allocation.getOrdinaryTeaNum());
@@ -1,18 +1,25 @@
package com.budwk.app.zhgh.democratic.teachercongress.delegate.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.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.BaseService;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.flow.enums.ProcessTaskStateEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
@@ -20,6 +27,8 @@ 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.util.ArrayList;
import java.util.List;
/**
@@ -44,13 +53,75 @@ public class TeacherCongressDelegatePushZgAuditController {
@At
@ApiOperation("分页查询")
@SaCheckPermission("tc.delegate.push")
@SaCheckPermission("tc.delegate.push.zcAudit")
public Result pageData(PageForm pageForm,
@Param(value = "sessionId") String sessionId,
@Param(value = "unionId") String unionId,
@Param(value = "approval") Boolean approval,
@Param(value = "isFormalOrAttendance") String isFormalOrAttendance) {
Sql sql = getSql(pageForm, sessionId, unionId, approval, isFormalOrAttendance);
Pagination<NutMap> pageVO = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
}
@Ok("void")
@At("/exportExcel")
@ApiOperation("代表资格审查导出")
@SaCheckPermission("tc.delegate.push.zcAudit")
public void exportExcel(PageForm pageForm,
@Param(value = "sessionId") String sessionId,
@Param(value = "unionId") String unionId,
@Param(value = "approval") Boolean approval,
@Param(value = "isFormalOrAttendance") String isFormalOrAttendance, HttpServletResponse response) {
Sql sql = getSql(pageForm, sessionId, unionId, approval, isFormalOrAttendance);
List<NutMap> exportList = baseService.listMap(sql);
exportList.forEach(item -> {
item.put("isJdh", item.getBoolean("isJdh") ? "" : "");
item.put("isGdh", item.getBoolean("isGdh") ? "" : "");
item.put("cadre", item.getBoolean("cadre") ? "" : "");
item.put("worker", item.getBoolean("worker") ? "" : "");
item.put("intermediateBelow", item.getBoolean("intermediateBelow") ? "" : "");
item.put("seniorTeacher", item.getBoolean("seniorTeacher") ? "" : "");
});
List<ExcelExportEntity> entityList = new ArrayList<>();
entityList.add(new ExcelExportEntity("姓名", "userName", 20));
entityList.add(new ExcelExportEntity("工号", "loginName", 20));
entityList.add(new ExcelExportEntity("性别", "sex", 20));
entityList.add(new ExcelExportEntity("联系电话", "mobile", 20));
entityList.add(new ExcelExportEntity("分工会", "unionName", 20));
entityList.add(new ExcelExportEntity("职称", "professionalTitle", 20));
entityList.add(new ExcelExportEntity("职级", "professionalLevel", 20));
entityList.add(new ExcelExportEntity("是否高级职称", "seniorTeacher", 20));
entityList.add(new ExcelExportEntity("是否中级职称及以下", "intermediateBelow", 20));
entityList.add(new ExcelExportEntity("是否干部", "cadre", 20));
entityList.add(new ExcelExportEntity("是否工人", "worker", 20));
entityList.add(new ExcelExportEntity("教代会代表", "isJdh", 20));
entityList.add(new ExcelExportEntity("工代会代表", "isGdh", 20));
entityList.add(new ExcelExportEntity("代表类型", "representativeType", 20));
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, entityList, exportList);
CommonDownloadUtil.download("推选代表汇总表.xlsx", workbook, response);
}
/**
* 公共sql
*
* @return
*/
private Sql getSql(PageForm pageForm,
String sessionId,
String unionId,
Boolean approval,
String isFormalOrAttendance) {
Sql sql = Sqls.create("""
SELECT
info.*,
@@ -92,6 +163,14 @@ public class TeacherCongressDelegatePushZgAuditController {
} else {
cnd.and("t.taskState", "=", ProcessTaskStateEnum.DOING.getCode());
}
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup group = new SqlExpressionGroup();
group.orLike("info.userName", pageForm.getSearchKeyword());
group.orLike("info.loginName", pageForm.getSearchKeyword());
cnd.and(group);
}
cnd.groupBy("t.id");
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.desc("t.createdAt");
@@ -99,11 +178,7 @@ public class TeacherCongressDelegatePushZgAuditController {
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
}
sql.setCondition(cnd);
sql.setCondition(cnd);
Pagination<NutMap> pageVO = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
return Result.success(pageVO);
return sql;
}
@@ -105,6 +105,24 @@ public class TeacherCongressDelegatePush extends BaseModel {
@Default("0")
private Boolean seniorTeacher;
@Column
@Comment("是否中级职称及以下")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean intermediateBelow;
@Column
@Comment("是否干部")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean cadre;
@Column
@Comment("是否工人")
@ColDefine(type = ColType.BOOLEAN)
@Default("0")
private Boolean worker;
@Column
@Comment("是否校领导")
@ColDefine(type = ColType.BOOLEAN)
@@ -58,7 +58,8 @@ public class TeacherCongressDelegatePushServiceImpl extends BaseServiceImpl<Teac
$condition
""");
Cnd cnd = Cnd.NEW();
cnd.and("info.id", "in", ids);
// cnd.and("info.id", "in", ids);
cnd.and("t.taskName", "=", "0cacd1e7-7bb2-47dd-818b-6a73062e0c62");
sql.setCondition(cnd);
List<NutMap> delegatePushList = listMap(sql);
@@ -1,7 +1,6 @@
package com.budwk.app.zhgh.democratic.teachercongress.prepare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
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.democratic.teachercongress.prepare.models.Teacher_congress_quota_allocation;
@@ -59,6 +58,9 @@ public class TeacherCongressQuotaAllocationController {
tcqa.ratio,
tcqa.seniorTeaNum,
tcqa.ordinaryTeaNum,
tcqa.intermediateBelowNum,
tcqa.cadreNum,
tcqa.workerNum,
tcqa.femaleNum,
tcqa.less45Num,
COALESCE(u_count, 0) AS memberCount,
@@ -96,6 +98,9 @@ public class TeacherCongressQuotaAllocationController {
t2.ratio,
t2.seniorTeaNum,
t2.ordinaryTeaNum,
t2.intermediateBelowNum,
t2.cadreNum,
t2.workerNum,
t2.femaleNum,
t2.less45Num
FROM
@@ -53,6 +53,24 @@ public class Teacher_congress_quota_allocation extends BaseModel {
@Default("0")
private Integer seniorTeaNum;
@Column
@Comment("中级职称及以下代表数")
@ColDefine(type = ColType.INT, width = 4)
@Default("0")
private Integer intermediateBelowNum;
@Column
@Comment("干部代表数")
@ColDefine(type = ColType.INT, width = 4)
@Default("0")
private Integer cadreNum;
@Column
@Comment("工人代表数")
@ColDefine(type = ColType.INT, width = 4)
@Default("0")
private Integer workerNum;
@Column
@Comment("专任教师代表数")
@ColDefine(type = ColType.INT, width = 4)
@@ -158,9 +158,12 @@ public class WelfareListController {
if (user != null) {
WelfareList list = new WelfareList();
list.setUserId(user.getId());
list.setWelfareUnitId(user.getUnionId());
list.setWelfareUnitId(user.getUnitId());
list.setWelfareUnitName(user.getUnitName());
list.setWelfareUnionId(user.getUnionId());
list.setWelfareUnionName(user.getUnionName());
list.setProjectId(businessId);
list.setWelfareSecondLevelUnitId(user.getUnitId());
// list.setWelfareSecondLevelUnitId(user.getUnitId());
list.setPersonType(user.getPersonType());
list.setUserState(user.getUserState());
welfareLists.add(list);
@@ -1,34 +1,24 @@
package com.budwk.app.zhgh.welfare.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.date.DateUtil;
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.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.welfare.model.WelfareCourierNumber;
import com.budwk.app.zhgh.welfare.model.WelfareEvaluate;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import com.budwk.app.zhgh.welfare.service.WelfareListService;
import com.budwk.app.zhgh.welfare.service.WelfareProjectService;
import com.budwk.app.zhgh.welfare.utils.ExpressSelectUtil;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.Lang;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import java.util.*;
import java.util.stream.Collectors;
/**
* @ClassName WelfareMineController
* @Description 我的福利
@@ -1,19 +1,17 @@
package com.budwk.app.zhgh.welfare.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
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.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
import com.budwk.app.zhgh.welfare.service.WelfareListService;
import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService;
import com.budwk.app.zhgh.welfare.service.WelfareSingleService;
import com.budwk.app.zhgh.welfare.service.WelfareStatisticsService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -21,8 +19,6 @@ 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;
@@ -86,7 +82,7 @@ public class WelfareSelectionSituationController {
@SaCheckPermission("welfare.selection.situation")
public Result confirmSelect(@Param("selections") WelfareUserSelection[] selections, String projectId, String userId) {
int count = dao.count(WelfareList.class, Cnd.where(WelfareList::getProjectId, "=", projectId).and(WelfareList::getUserId, "=", userId));
if(count==0){
if (count == 0) {
return Result.error("此用户没有选择的权限");
}
@@ -109,4 +105,12 @@ public class WelfareSelectionSituationController {
public void exportXlsx(@Valid @Param("pageForm") WelfareSelectionSituationPageForm pageForm, HttpServletResponse response) {
situationService.exportXlsx(pageForm, response);
}
@At
@SaCheckLogin
public Result getMobileByUserId(String userId) {
Sys_user user = dao.fetch(Sys_user.class, userId);
return Result.success().addData(user.getMobile());
}
}
@@ -1,11 +1,6 @@
package com.budwk.app.zhgh.welfare.controller;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.annotation.SLog;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.param.PageForm;
@@ -23,11 +18,6 @@ import org.apache.poi.ss.usermodel.Workbook;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.FieldFilter;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.dao.util.Daos;
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;
@@ -40,9 +30,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.BufferedOutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@@ -213,7 +201,8 @@ public class WelfareStatisticsController {
@Ok("void")
@SaCheckPermission("welfare.statistics")
public void exportSummary(String projectId, String unionId, HttpServletResponse response) {
welfareSingleService.exportSummary(projectId, unionId, response);
// welfareSingleService.exportSummary(projectId, unionId, response);
welfareStatisticsService.exportSummary(projectId,response);
}
@At
@@ -11,7 +11,6 @@ import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import com.budwk.app.zhgh.welfare.service.WelfareProjectService;
import io.swagger.annotations.ApiOperation;
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;
@@ -7,8 +7,6 @@ import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
* 福利名单
*
@@ -63,7 +61,7 @@ public class WelfareList extends BaseModel{
private String welfareUnionName;
@Column
@Comment("教职工类别")
@Comment("人员类型")
@ColDefine(type = ColType.VARCHAR)
private String personType;
@@ -73,7 +71,7 @@ public class WelfareList extends BaseModel{
private String userState;
@Column
@Comment("编制类别")
@Comment("聘用方式")
@ColDefine(type = ColType.VARCHAR)
private String preparedBy;
@@ -9,7 +9,6 @@ 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;
import java.util.List;
@@ -1,9 +1,6 @@
package com.budwk.app.zhgh.welfare.model;
import com.budwk.app.base.model.BaseModel;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@@ -6,6 +6,7 @@ import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.nutz.dao.entity.annotation.*;
import org.nutz.dao.interceptor.annotation.PrevInsert;
import java.io.Serializable;
/**
@@ -43,10 +43,10 @@ public class WelfareFilterUserPageForm extends PageForm {
@ApiModelProperty("单位名称")
private String unitName;
@ApiModelProperty("教职工类别")
@ApiModelProperty("人员类型")
private String[] personTypes;
@ApiModelProperty("编制类别")
@ApiModelProperty("聘用方式")
private String[] preparedBys;
@ApiModelProperty("在职状态")
@@ -46,10 +46,10 @@ public class WelfareListPageForm extends PageForm {
@ApiModelProperty("单位名称")
private String unitName;
@ApiModelProperty("教职工类别")
@ApiModelProperty("人员类型")
private String[] personTypes;
@ApiModelProperty("编制类别")
@ApiModelProperty("聘用方式")
private String[] preparedBys;
@ApiModelProperty("在职状态")
@@ -1,7 +1,6 @@
package com.budwk.app.zhgh.welfare.param;
import com.budwk.app.base.param.PageForm;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@@ -1,10 +1,7 @@
package com.budwk.app.zhgh.welfare.service;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.service.BaseService;
import com.budwk.app.zhgh.welfare.model.WelfareProject;
import com.budwk.app.zhgh.welfare.param.WelfareFilterUserPageForm;
import org.nutz.lang.util.NutMap;
import java.util.List;
@@ -32,7 +32,6 @@ 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.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
@@ -104,7 +103,7 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
List<ExcelExportEntity> exportEntities = new ArrayList<>();
exportEntities.add(new ExcelExportEntity("工号", "loginname", 20));
exportEntities.add(new ExcelExportEntity("姓名", "username", 20));
exportEntities.add(new ExcelExportEntity("教职工类别", "personType", 20));
exportEntities.add(new ExcelExportEntity("人员类别", "personType", 20));
exportEntities.add(new ExcelExportEntity("所在分工会", "unionname", 20));
exportEntities.add(new ExcelExportEntity("所在部门", "unitname", 20));
exportEntities.add(new ExcelExportEntity("份数", "selectNum", 20));
@@ -370,8 +369,10 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
WelfareList welfareList = new WelfareList();
welfareList.setProjectId(id);
welfareList.setUserId(v.getId());
welfareList.setWelfareUnitId(v.getUnionId());
welfareList.setWelfareSecondLevelUnitId(v.getUnitId());
welfareList.setWelfareUnitId(v.getUnitId());
welfareList.setWelfareUnitName(v.getUnitName());
welfareList.setWelfareUnionId(v.getUnionId());
welfareList.setWelfareUnionName(v.getUnionName());
welfareList.setPersonType(v.getPersonType());
welfareList.setUserState(v.getUserState());
return welfareList;
@@ -466,6 +467,7 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
cnd.andEX("u.personType", "in", pageForm.getPersonTypes());
cnd.andEX("u.preparedBy", "in", pageForm.getPreparedBys());
cnd.andEX("u.userState", "in", pageForm.getUserStates());
cnd.andEX("u.member","=",pageForm.getIsMember());
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.asc("u.unionCode");
@@ -517,6 +519,7 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
cnd.andEX("personType", "in", pageForm.getPersonTypes());
cnd.andEX("preparedBy", "in", pageForm.getPreparedBys());
cnd.andEX("userState", "in", pageForm.getUserStates());
cnd.andEX("member","=",pageForm.getIsMember());
if (StrUtil.isAllBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
cnd.asc("unionCode");
@@ -597,8 +600,8 @@ public class WelfareListServiceImpl extends BaseServiceImpl<WelfareList> impleme
entities.add(new ExcelExportEntity("姓名", "username", 20));
entities.add(new ExcelExportEntity("性别", "sex", 20));
entities.add(new ExcelExportEntity("出生日期", "birthday", 20));
entities.add(new ExcelExportEntity("教职工类别", "personType", 20));
entities.add(new ExcelExportEntity("编制类别", "preparedBy", 20));
entities.add(new ExcelExportEntity("人员类型", "personType", 20));
entities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
entities.add(new ExcelExportEntity("在职状态", "userState", 20));
entities.add(new ExcelExportEntity("所属工会", "welfareUnionName", 20));
entities.add(new ExcelExportEntity("所属单位", "welfareUnitName", 20));
@@ -1,29 +1,21 @@
package com.budwk.app.zhgh.welfare.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.page.Pagination;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.sys.models.Sys_home_activity;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.welfare.model.*;
import com.budwk.app.zhgh.welfare.param.WelfareFilterUserPageForm;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareProject;
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import com.budwk.app.zhgh.welfare.service.WelfareProjectService;
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.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -175,8 +167,10 @@ public class WelfareProjectServiceImpl extends BaseServiceImpl<WelfareProject> i
WelfareList list = new WelfareList();
list.setProjectId(projectId);
list.setUserId(user.getString("id"));
list.setWelfareUnitId(user.getString("unionId"));
list.setWelfareSecondLevelUnitId(user.getString("unitId"));
list.setWelfareUnitId(user.getString("unitId"));
list.setWelfareUnitName(user.getString("unitName"));
list.setWelfareUnionId(user.getString("unionId"));
list.setWelfareUnionName(user.getString("unionName"));
list.setPersonType(user.getString("personType"));
list.setUserState(user.getString("userState"));
lists.add(list);
@@ -7,13 +7,13 @@ import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import cn.hutool.core.util.StrUtil;
import com.budwk.app.base.constant.RoleConstant;
import com.budwk.app.base.page.Pagination;
import com.budwk.app.base.result.Result;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.base.utils.PageUtil;
import com.budwk.app.web.commons.auth.utils.AuthUtil;
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareProject;
import com.budwk.app.zhgh.welfare.param.WelfareSelectionSituationPageForm;
import com.budwk.app.zhgh.welfare.service.WelfareSelectionSituationService;
import lombok.extern.slf4j.Slf4j;
@@ -45,8 +45,10 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
t1.userId,
t1.welfareUnionName,
t1.welfareUnitName,
t1.welfareUnitId,
GROUP_CONCAT(DISTINCT t3.optionName) AS selectedOptions,
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
t4.username AS userName,
t4.loginname AS loginName,
t4.sex,
@@ -105,6 +107,7 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
t1.welfareUnitName,
GROUP_CONCAT(DISTINCT t3.optionName) AS selectedOptions,
GROUP_CONCAT(DISTINCT t2.mobile) AS mobile,
GROUP_CONCAT(DISTINCT t2.receiveAddress) AS receiveAddress,
t4.username AS userName,
t4.loginname AS loginName,
t4.sex
@@ -152,6 +155,9 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
sql.setCondition(cnd);
List<NutMap> list = listMap(sql);
// 项目
WelfareProject project = dao().fetch(WelfareProject.class, pageForm.getProjectId());
// excel列
List<ExcelExportEntity> entities = new ArrayList<>();
@@ -163,6 +169,10 @@ public class WelfareSelectionSituationServiceImpl extends BaseServiceImpl<Welfar
entities.add(new ExcelExportEntity("所选福利", "selectedOptions", 20));
entities.add(new ExcelExportEntity("联系电话", "mobile", 20));
if(project.getProvideMode() == 3){
entities.add(new ExcelExportEntity("收货地址", "receiveAddress", 40));
}
// 设置导出参数
ExportParams exportParams = new ExportParams();
exportParams.setType(ExcelType.XSSF);
@@ -12,10 +12,8 @@ import com.budwk.app.base.param.PageForm;
import com.budwk.app.base.service.impl.BaseServiceImpl;
import com.budwk.app.base.utils.CommonDownloadUtil;
import com.budwk.app.sys.models.Sys_union;
import com.budwk.app.zhgh.welfare.model.WelfareList;
import com.budwk.app.zhgh.welfare.model.WelfareProject;
import com.budwk.app.zhgh.welfare.model.WelfareProjectSubjectOption;
import com.budwk.app.zhgh.welfare.model.WelfareUserSelection;
import com.budwk.app.zhgh.welfare.service.WelfareStatisticsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
@@ -31,7 +29,9 @@ import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.util.NutMap;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@IocBean(args = {"refer:dao"})
@@ -76,6 +76,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
Cnd cnd = Cnd.NEW();
cnd.and("t1.projectId", "=", projectId);
cnd.andEX("t1.welfareUnionId", "=", unionId);
cnd.groupBy("t1.userId");
sql.setCondition(cnd);
List<NutMap> welfareSelectionList = listMap(sql);
@@ -96,11 +97,11 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
for (NutMap union : mapUnions) {
// 福利人数
long teacherSum = welfareSelectionList.stream().filter(v -> (union.getString("id")).equals(v.getString("welfareUnionId"))).count();
long teacherSum = welfareSelectionList.stream().filter(v -> v.getString("welfareUnionId", "").equals(union.getString("id"))).count();
union.put("teacherSum", teacherSum);
// 已选人数
long selectedNum = welfareSelectionList.stream().filter(v -> (union.getString("id")).equals(v.getString("welfareUnionId")) && v.getBoolean("has_selected")).count();
long selectedNum = welfareSelectionList.stream().filter(v -> v.getString("welfareUnionId", "").equals(union.getString("id")) && v.getBoolean("has_selected")).count();
union.put("selectedNum", selectedNum);
// 未选人数
@@ -108,7 +109,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
// 各选项的选择人数
for (WelfareProjectSubjectOption option : welfareOptions) {
long count = userSelections.stream().filter(v -> (union.getString("id")).equals(v.getString("welfareUnionId")) && StrUtil.isNotBlank(v.getString("selectOptionId")) && v.getString("selectOptionId").equals(option.getId())).map(v -> v.getString("selectUserId")).distinct().count();
long count = userSelections.stream().filter(v -> v.getString("welfareUnionId").equals(union.getString("id")) && StrUtil.isNotBlank(v.getString("selectOptionId")) && v.getString("selectOptionId").equals(option.getId())).map(v -> v.getString("selectUserId")).distinct().count();
union.put(option.getId(), count);
}
}
@@ -201,7 +202,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
entities.add(new ExcelExportEntity("生日", "birthday", 20));
entities.add(new ExcelExportEntity("在职状态", "userState", 20));
entities.add(new ExcelExportEntity("教职工类别", "personType", 20));
entities.add(new ExcelExportEntity("编制类别", "preparedBy", 20));
entities.add(new ExcelExportEntity("聘用方式", "preparedBy", 20));
entities.add(new ExcelExportEntity("进站时间", "postDoctoralJoinDate", 20));
entities.add(new ExcelExportEntity("单位", "welfareUnitName", 20));
entities.add(new ExcelExportEntity("工会", "welfareUnionName", 20));
@@ -247,7 +248,7 @@ public class WelfareStatisticsServiceImpl extends BaseServiceImpl<WelfareProject
cnd.groupBy("u.loginname");
cnd.desc("wl.welfareUnionName").desc("wl.welfareUnitName");
if(StrUtil.isNotBlank(pageForm.getSearchKeyword())){
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
SqlExpressionGroup seg = new SqlExpressionGroup();
seg.orLike("u.loginname", pageForm.getSearchKeyword());
seg.orLike("u.username", pageForm.getSearchKeyword());
@@ -616,6 +616,7 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
this.$axios.post('/platform/activity/culture/applyActivity/save', {data: JSON.stringify(formData)}).then(res => {
if (res.code === 0) {
this.$message.success("保存成功")
this.$emit("goBack")
if (this.activity_type === 40002) {
commonUtil.pjaxPush("/platform/activity/culture/infoManage/union")
} else if (this.activity_type === 40003) {
@@ -656,6 +657,7 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
data: JSON.stringify(formData)
}).then(res => {
if (res.code === 0) {
this.$emit("goBack")
this.$message.success("提交成功")
if (this.activity_type === 40002) {
commonUtil.pjaxPush("/platform/activity/culture/infoManage/union")
@@ -698,6 +700,7 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
taskId: this.taskId
}).then(res => {
if (res.code === 0) {
this.$emit("goBack")
this.$message.success("提交成功")
if (this.activity_type === 40002) {
commonUtil.pjaxPush("/platform/activity/culture/infoManage/union")
@@ -776,11 +779,11 @@ const ACTIVITY_CULTURE_APPLY_ACTIVITY = {
this.$emit("goBack")
} else {
if (this.activity_type === 40002) {
pjaxReplace("/platform/activity/culture/infoManage/union")
commonUtil.pjaxPush("/platform/activity/culture/infoManage/union")
} else if (this.activity_type === 40003) {
pjaxReplace("/platform/activity/culture/infoManage/club")
commonUtil.pjaxPush("/platform/activity/culture/infoManage/club")
} else {
pjaxReplace("/platform/activity/culture/infoManage/school")
commonUtil.pjaxPush("/platform/activity/culture/infoManage/school")
}
}
@@ -130,7 +130,7 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
`,
props: {
activity_type: {
value: { type: Object, default: "" }
value: {type: Object, default: ""}
}
},
store,
@@ -141,20 +141,20 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
unionList: [],
showApprovalForm: false,
auditList: [
{ code: true, name: "已审核" },
{ code: false, name: "未审核" }
{code: true, name: "已审核"},
{code: false, name: "未审核"}
],
pageForm: {
approval: false,
year: new Date().getFullYear() + ""
},
tableColumns: [
{ prop: "name", label: "活动名称" },
{ prop: "address", label: "活动地点" },
{ prop: "projectTypeName", label: "活动项目类型" },
{ prop: "tussueName", label: "举办单位" },
{ prop: "time", label: "活动日期" },
{ prop: "applyTime", label: "创建时间", sortable: true },
{prop: "name", label: "活动名称"},
{prop: "address", label: "活动地点"},
{prop: "projectTypeName", label: "活动项目类型"},
{prop: "tussueName", label: "举办单位"},
{prop: "time", label: "活动日期"},
{prop: "applyTime", label: "创建时间", sortable: true},
]
}
},
@@ -164,7 +164,7 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
methods: {
openAudit(row) {
this.$refs.guava.edit(()=>{
this.$refs.guava.edit(() => {
this.showApprovalForm = true
this.formData = {
processTaskId: row.taskId,
@@ -175,7 +175,7 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
},
onView(row) {
this.$refs.guava.edit(()=>{
this.$refs.guava.edit(() => {
this.showApprovalForm = false
this.$refs.editInfo.onOpen(row)
})
@@ -197,11 +197,11 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$axios.post("/flow/common/executeTask", {
this.$axios.post("/platform/activity/culture/auditActivity/doReview", {
data: JSON.stringify({
...this.formData,
submitType: val
})
}), id: this.formData.id
}).then((res) => {
if (res.code === 0) {
this.$refs.guava.index()
@@ -230,8 +230,8 @@ const ACTIVITY_CULTURE_AUDIT_ACTIVITY = {
// 根据 activity_type 动态添加流程相关列
if (this.activity_type === 40002 || this.activity_type === 40003) {
this.tableColumns.push(
{prop: "curTaskName", label: "当前节点"},
{prop: "instanceState", label: "流程状态"}
{prop: "curTaskName", label: "当前节点"},
{prop: "instanceState", label: "流程状态"}
);
}
this.unionList = await this.$businessTool.listUnion()
@@ -56,6 +56,12 @@ const ACTIVITY_CULTURE_INFO_MANAGE = {
<template scope="{row}" v-else-if="column.prop=='projectTypeName'">
{{row.projectTypeName}}({{row.projectTypeCode}})
</template>
<template scope="{row}" v-else-if="column.prop=='tussueName'">
<span v-if="row.activity_type==40002">{{row.unionname?row.unionname:'暂无'}}</span>
<span v-if="row.activity_type==40003">{{row.clubName?row.clubName:'暂无'}}</span>
<span v-if="row.activity_type==40001">校工会</span>
</template>
<template scope="{row}" v-else-if="column.prop=='isUnseal'">
<el-switch
@@ -151,50 +151,63 @@ var ACTIVITY_SPORTS_APPLY_USER = {
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="序号"
label="序号"
type="index"
width="80">
</el-table-column>
<el-table-column
align="center" header-align="center" label="所属队"
label="所属队"
prop="team" width="80">
</el-table-column>
<el-table-column
align="center" header-align="center" label="姓名"
label="姓名"
prop="username" width="130">
</el-table-column>
<el-table-column
align="center" header-align="center" label="教工号"
label="教工号"
prop="loginname" width="130">
</el-table-column>
<el-table-column
align="center" header-align="center" label="单位"
label="单位"
prop="unitname"
sortable>
</el-table-column>
<el-table-column
align="center" header-align="center" label="性别"
label="性别"
prop="sex" width="80">
</el-table-column>
<el-table-column
label="联系方式"
prop="mobile" width="150">
<template v-slot="{row}">
<el-input placeholder="请输入联系方式"
v-model="row.mobile"></el-input>
</template>
</el-table-column>
<el-table-column
align="center" header-align="center" label="年龄"
label="职级"
prop="professionalLevel" width="80">
</el-table-column>
<el-table-column
label="年龄"
prop="age" width="80">
</el-table-column>
<el-table-column
align="center" header-align="center" label="身份"
label="身份"
prop="identity" width="300px">
<template scope="{$index,row}">
<el-tag :disable-transitions="false"
@@ -530,6 +543,14 @@ var ACTIVITY_SPORTS_APPLY_USER = {
})
return
}
//判断每一个选手填写的是否正确
for (let i = 0; i < applyUserList.length; i++) {
if (!applyUserList[i].mobile) {
this.$message.warning("请输入联系方式!")
return
}
}
if (projectType !== "1") {
for (let i = 0; i < teamApplyData.length; i++) {
@@ -697,6 +718,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
loginname: v.loginname,
username: v.username,
age: v.age,
professionalLevel: v.professionalLevel,
birthday: v.birthday,
unitId: v.unitId,
unionId: v.unionId,
@@ -850,7 +872,7 @@ var ACTIVITY_SPORTS_APPLY_USER = {
return {
id: user.id,
loginname: user.loginname,
name: user.username + "" + (user.sex ? user.sex : "") + "-" + user.loginname + ""
name: user.username + "" + (user.sex ? user.sex : "") + "-" + user.loginname + "-" + user.age + (user.professionalLevel ? ("-" + user.professionalLevel) : "") + ""
}
},
uniteApplyReset() {
@@ -69,8 +69,9 @@ var ACTIVITY_SPORTS_DELETE_USER = {
{ prop: "name", label: "所属小队" },
{ prop: "username", label: "姓名" },
{ prop: "loginname", label: "工号" },
{ prop: "mobile", label: "电话" },
{ prop: "sex", label: "性别" },
{ prop: "mobile", label: "联系方式" },
{ prop: "professionalLevel", label: "职级" },
{ prop: "identity", label: "身份", sortable: true },
{ prop: "allName", label: "报名项目" }
]
@@ -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"
@@ -60,20 +60,21 @@ layout("/layouts/platform.html"){
row-key="id"
@sort-change="pageOrder"
>
<el-table-column type="selection" width="55" reserve-selection fixed="left" :selectable="(row)=>{return row.taskKey==='0cacd1e7-7bb2-47dd-818b-6a73062e0c62'}"></el-table-column>
<!-- <el-table-column type="selection" width="55" reserve-selection fixed="left" :selectable="(row)=>{return row.taskKey==='0cacd1e7-7bb2-47dd-818b-6a73062e0c62'}"></el-table-column>-->
<el-table-column type="index" width="55" label="序号" :index="indexMethod" fixed="left"></el-table-column>
<el-table-column label="姓名" prop="userName" width="100" fixed="left"></el-table-column>
<el-table-column label="年龄" prop="age" width="100"></el-table-column>
<el-table-column label="性别" prop="sex" width="100" fixed="left"></el-table-column>
<el-table-column label="民族" prop="nation" min-width="100"></el-table-column>
<!-- <el-table-column label="民族" prop="nation" min-width="100"></el-table-column>-->
<el-table-column label="职称" prop="professionalTitle" min-width="150"></el-table-column>
<el-table-column label="职级" prop="professionalLevel" min-width="100"></el-table-column>
<el-table-column label="校级领导" prop="schoolLeader" min-width="100">
<!-- :style="{'pointer-events':(row.taskKey === 'startTask' || row.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080' || !row.instanceId)?'auto':'none'}"-->
<!-- <el-table-column label="校级领导" prop="schoolLeader" min-width="100">
<template v-slot="{row}">
<el-checkbox
v-if="row"
v-model="row.schoolLeader"
:style="{'pointer-events':(row.taskKey === 'startTask' || row.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080' || !row.instanceId)?'auto':'none'}"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
@@ -82,25 +83,53 @@ layout("/layouts/platform.html"){
<el-checkbox
v-if="row"
v-model="row.middleLevelLeader"
:style="{'pointer-events':(row.taskKey === 'startTask' || row.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080' || !row.instanceId)?'auto':'none'}"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
</el-table-column>-->
<!--
<el-table-column label="专任教师" prop="ordinaryTeacher" min-width="100">
<template v-slot="{row}">
<el-checkbox
v-if="row"
v-model="row.ordinaryTeacher"
:style="{'pointer-events':(row.taskKey === 'startTask' || row.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080' || !row.instanceId)?'auto':'none'}"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
<el-table-column label="高级职称专任教师" prop="seniorTeacher" min-width="150">
</el-table-column>-->
<el-table-column label="高级职称" prop="seniorTeacher" min-width="120">
<template v-slot="{row}">
<el-checkbox
v-if="row"
v-model="row.seniorTeacher"
:style="{'pointer-events':(row.taskKey === 'startTask' || row.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080' || !row.instanceId)?'auto':'none'}"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
<el-table-column label="中级职称及以下" prop="intermediateBelow" min-width="120">
<template v-slot="{row}">
<el-checkbox
v-if="row"
v-model="row.intermediateBelow"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
<el-table-column label="干部" prop="cadre" min-width="100">
<template v-slot="{row}">
<el-checkbox
v-if="row"
v-model="row.cadre"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
<el-table-column label="工人" prop="worker" min-width="100">
<template v-slot="{row}">
<el-checkbox
v-if="row"
v-model="row.worker"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
@@ -109,7 +138,7 @@ layout("/layouts/platform.html"){
<el-checkbox
v-if="row"
v-model="row.isJdh"
:style="{'pointer-events':(row.taskKey === 'startTask' || row.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080' || !row.instanceId)?'auto':'none'}"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
@@ -118,7 +147,7 @@ layout("/layouts/platform.html"){
<el-checkbox
v-if="row"
v-model="row.isGdh"
:style="{'pointer-events':(row.taskKey === 'startTask' || row.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080' || !row.instanceId)?'auto':'none'}"
style="pointer-events:none"
></el-checkbox>
</template>
</el-table-column>
@@ -234,19 +263,21 @@ layout("/layouts/platform.html"){
},
onBatchSubmit() {
const selection = this.$refs.tableRef.selection
if (selection.length === 0){
/*if (selection.length === 0){
this.$message.warning('请选择要上报的记录')
return
}
}*/
this.$confirm('您确定要上报吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const loading = createLoading('正在提交中')
const {code, msg} = await this.$axios.post('/platform/teacherCongress/delegate/push/batchSubmit', {
ids: JSON.stringify(selection.map(v => v.id)),
sessionId: this.pageForm.sessionId
})
loading.close()
if (code === 0) {
this.$message.success(msg)
this.doSearch()
@@ -20,8 +20,10 @@ const pushAttendanceDialog = {
<div class="transfer-item-details">
<span class="detail-item">{{ option.sex}}</span>
<span class="detail-item" v-if="option.age">{{ option.age }}</span>
<span class="detail-item" v-if="option.professionalTitle">{{ option.professionalTitle }}</span>
<span class="detail-item" v-if="option.professionalLevel">{{ option.professionalLevel }}</span>
<span class="detail-item"
v-if="option.professionalTitle">{{ option.professionalTitle }}</span>
<span class="detail-item"
v-if="option.professionalLevel">{{ option.professionalLevel }}</span>
<span class="detail-item" v-if="option.nation">{{ option.nation }}</span>
</div>
</div>
@@ -63,11 +65,13 @@ const pushAttendanceDialog = {
return item.userName.indexOf(query) > -1
},
async onConfirm() {
const loading = createLoading('正在提交中')
const {code, msg} = await $.post('/platform/teacherCongress/delegate/push/addPreselectionDb', {
userValue: JSON.stringify(this.userValue),
sessionId: this.sessionId,
representativeType: '列席代表'
})
loading.close()
if (code === 0) {
this.dialogVisible = false
this.$message.success(msg)
@@ -76,10 +80,10 @@ const pushAttendanceDialog = {
}
},
style: /*language=CSS*/ `
.push-attendance-dialog ::v-deep .el-transfer{
text-align: center!important;
.push-attendance-dialog ::v-deep .el-transfer {
text-align: center !important;
}
.push-attendance-dialog ::v-deep .el-transfer-panel__item.el-checkbox {
height: auto;
display: block;
@@ -115,7 +119,8 @@ const pushAttendanceDialog = {
display: inline-flex;
align-items: center;
}
.push-attendance-dialog ::v-deep .el-transfer-panel{
.push-attendance-dialog ::v-deep .el-transfer-panel {
height: 60vh;
text-align: left !important;
width: 35% !important;
@@ -20,8 +20,10 @@ const pushFormalDialog = {
<div class="transfer-item-details">
<span class="detail-item">{{ option.sex}}</span>
<span class="detail-item" v-if="option.age">{{ option.age }}</span>
<span class="detail-item" v-if="option.professionalTitle">{{ option.professionalTitle }}</span>
<span class="detail-item" v-if="option.professionalLevel">{{ option.professionalLevel }}</span>
<span class="detail-item"
v-if="option.professionalTitle">{{ option.professionalTitle }}</span>
<span class="detail-item"
v-if="option.professionalLevel">{{ option.professionalLevel }}</span>
<span class="detail-item" v-if="option.nation">{{ option.nation }}</span>
</div>
</div>
@@ -63,11 +65,13 @@ const pushFormalDialog = {
return item.userName.indexOf(query) > -1
},
async onConfirm() {
const loading = createLoading('正在提交中')
const {code, msg} = await this.$axios.post('/platform/teacherCongress/delegate/push/addPreselectionDb', {
userValue: JSON.stringify(this.userValue),
sessionId: this.sessionId,
representativeType: '正式代表'
})
loading.close()
if (code === 0) {
this.dialogVisible = false
this.$message.success(msg)
@@ -76,11 +80,11 @@ const pushFormalDialog = {
}
},
style: /*language=CSS*/ `
.push-formal-dialog ::v-deep .el-transfer{
text-align: center!important;
.push-formal-dialog ::v-deep .el-transfer {
text-align: center !important;
}
.push-formal-dialog ::v-deep .el-transfer-panel__item.el-checkbox {
.push-formal-dialog ::v-deep .el-transfer-panel__item.el-checkbox {
height: auto;
display: block;
margin-right: 0;
@@ -116,7 +120,7 @@ const pushFormalDialog = {
align-items: center;
}
.push-formal-dialog ::v-deep .el-transfer-panel{
.push-formal-dialog ::v-deep .el-transfer-panel {
height: 60vh;
text-align: left !important;
width: 35% !important;
@@ -53,7 +53,7 @@ const pushProgress = {
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">高级职称专任教师</div>
<div class="metric-title">高级职称代表</div>
<div class="metric-value">{{ metrics.seniorTeacher.current }}<span
class="metric-target"
>/ {{ metrics.seniorTeacher.target }}</span></div>
@@ -81,14 +81,14 @@ const pushProgress = {
</div>
</div>
<!-- 专任教师代表数 -->
<!-- 中级职称及以下-->
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">专任教师代表</div>
<div class="metric-value">{{ metrics.ordinaryTeacher.current }}<span
<div class="metric-title">中级职称及以下代表</div>
<div class="metric-value">{{ metrics.intermediateBelow.current }}<span
class="metric-target"
>/ {{ metrics.ordinaryTeacher.target }}</span></div>
>/ {{ metrics.intermediateBelow.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-chalkboard-teacher text-primary"></i>
@@ -97,23 +97,121 @@ const pushProgress = {
<div class="progress-bar">
<div
class="progress-bar-inner bg-primary"
:style="{width: metrics.ordinaryTeacher.progress * 100 + '%'}"
:style="{width: metrics.intermediateBelow.progress * 100 + '%'}"
></div>
</div>
<div class="progress-info">
<span v-if="metrics.ordinaryTeacher.progress>=1 || metrics.ordinaryTeacher.target===0"
<span v-if="metrics.intermediateBelow.progress>=1 || metrics.intermediateBelow.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.ordinaryTeacher.progress<1" class="text-primary">
<span v-else-if="metrics.intermediateBelow.progress<1" class="text-primary">
未达标
</span>
<span
v-if="metrics.ordinaryTeacher.remaining>0"
v-if="metrics.intermediateBelow.remaining>0"
class="text-gray-500"
>剩余 {{ metrics.ordinaryTeacher.remaining }} </span>
>剩余 {{ metrics.intermediateBelow.remaining }} </span>
</div>
</div>
<!-- 干部-->
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">干部代表</div>
<div class="metric-value">{{ metrics.cadre.current }}<span
class="metric-target"
>/ {{ metrics.cadre.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-chalkboard-teacher text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.cadre.progress * 100 + '%'}"
></div>
</div>
<div class="progress-info">
<span v-if="metrics.cadre.progress>=1 || metrics.cadre.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.cadre.progress<1" class="text-primary">
未达标
</span>
<span
v-if="metrics.cadre.remaining>0"
class="text-gray-500"
>剩余 {{ metrics.cadre.remaining }} </span>
</div>
</div>
<!-- 工人-->
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">工人代表</div>
<div class="metric-value">{{ metrics.worker.current }}<span
class="metric-target"
>/ {{ metrics.worker.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-chalkboard-teacher text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.worker.progress * 100 + '%'}"
></div>
</div>
<div class="progress-info">
<span v-if="metrics.worker.progress>=1 || metrics.worker.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.worker.progress<1" class="text-primary">
未达标
</span>
<span
v-if="metrics.worker.remaining>0"
class="text-gray-500"
>剩余 {{ metrics.worker.remaining }} </span>
</div>
</div>
<!-- 专任教师代表数 -->
<!-- <div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">专任教师代表</div>
<div class="metric-value">{{ metrics.ordinaryTeacher.current }}<span
class="metric-target"
>/ {{ metrics.ordinaryTeacher.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-chalkboard-teacher text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div
class="progress-bar-inner bg-primary"
:style="{width: metrics.ordinaryTeacher.progress * 100 + '%'}"
></div>
</div>
<div class="progress-info">
<span v-if="metrics.ordinaryTeacher.progress>=1 || metrics.ordinaryTeacher.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.ordinaryTeacher.progress<1" class="text-primary">
未达标
</span>
<span
v-if="metrics.ordinaryTeacher.remaining>0"
class="text-gray-500"
>剩余 {{ metrics.ordinaryTeacher.remaining }} </span>
</div>
</div>-->
<!-- 女代表数 -->
<div class="metric-card">
@@ -178,100 +276,100 @@ const pushProgress = {
}} </span>
</div>
</div>
<!-- &lt;!&ndash; 少数民族数 &ndash;&gt;
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">少数民族代表</div>
<div class="metric-value">{{ metrics.ethnicMinority.current }}<span
class="metric-target"
>/ {{ metrics.ethnicMinority.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-user-graduate text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.ethnicMinority.progress * 100 + '%'}"></div>
</div>
<div class="progress-info">
<span v-if="metrics.ethnicMinority.progress>=1 || metrics.ethnicMinority.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.ethnicMinority.progress<1" class="text-primary">
未达标
</span>
<span v-if="metrics.ethnicMinority.remaining>0" class="text-gray-500">剩余 {{
metrics.ethnicMinority.remaining
}} </span>
</div>
</div>
&lt;!&ndash; 校级领导 &ndash;&gt;
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">校级领导代表</div>
<div class="metric-value">{{ metrics.schoolLeader.current }}<span
class="metric-target"
>/ {{ metrics.schoolLeader.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-user-graduate text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.schoolLeader.progress * 100 + '%'}"></div>
</div>
<div class="progress-info">
<span v-if="metrics.schoolLeader.progress>=1 || metrics.schoolLeader.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.schoolLeader.progress<1" class="text-primary">
未达标
</span>
<span v-if="metrics.schoolLeader.remaining>0" class="text-gray-500">剩余 {{
metrics.schoolLeader.remaining
}} </span>
</div>
</div>
<!-- &lt;!&ndash; 少数民族数 &ndash;&gt;
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">少数民族代表</div>
<div class="metric-value">{{ metrics.ethnicMinority.current }}<span
class="metric-target"
>/ {{ metrics.ethnicMinority.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-user-graduate text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.ethnicMinority.progress * 100 + '%'}"></div>
</div>
<div class="progress-info">
<span v-if="metrics.ethnicMinority.progress>=1 || metrics.ethnicMinority.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.ethnicMinority.progress<1" class="text-primary">
未达标
</span>
<span v-if="metrics.ethnicMinority.remaining>0" class="text-gray-500">剩余 {{
metrics.ethnicMinority.remaining
}} </span>
</div>
</div>
&lt;!&ndash; 校级领导 &ndash;&gt;
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">校级领导代表</div>
<div class="metric-value">{{ metrics.schoolLeader.current }}<span
class="metric-target"
>/ {{ metrics.schoolLeader.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-user-graduate text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.schoolLeader.progress * 100 + '%'}"></div>
</div>
<div class="progress-info">
<span v-if="metrics.schoolLeader.progress>=1 || metrics.schoolLeader.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.schoolLeader.progress<1" class="text-primary">
未达标
</span>
<span v-if="metrics.schoolLeader.remaining>0" class="text-gray-500">剩余 {{
metrics.schoolLeader.remaining
}} </span>
</div>
</div>
&lt;!&ndash; 中层领导 &ndash;&gt;
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">中层领导</div>
<div class="metric-value">{{ metrics.middleLevelLeader.current }}<span
class="metric-target"
>/ {{ metrics.middleLevelLeader.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-user-graduate text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.middleLevelLeader.progress * 100 + '%'}"></div>
</div>
<div class="progress-info">
<span v-if="metrics.middleLevelLeader.progress>=1 || metrics.middleLevelLeader.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.middleLevelLeader.progress<1" class="text-primary">
未达标
</span>
<span v-if="metrics.middleLevelLeader.remaining>0" class="text-gray-500">剩余 {{
metrics.middleLevelLeader.remaining
}} </span>
</div>
</div>-->
&lt;!&ndash; 中层领导 &ndash;&gt;
<div class="metric-card">
<div class="metric-header">
<div>
<div class="metric-title">中层领导</div>
<div class="metric-value">{{ metrics.middleLevelLeader.current }}<span
class="metric-target"
>/ {{ metrics.middleLevelLeader.target }}</span></div>
</div>
<div class="metric-icon bg-primary-light">
<i class="fas fa-user-graduate text-primary"></i>
</div>
</div>
<div class="progress-bar">
<div class="progress-bar-inner bg-primary"
:style="{width: metrics.middleLevelLeader.progress * 100 + '%'}"></div>
</div>
<div class="progress-info">
<span v-if="metrics.middleLevelLeader.progress>=1 || metrics.middleLevelLeader.target===0"
class="text-success">
已达标
</span>
<span v-else-if="metrics.middleLevelLeader.progress<1" class="text-primary">
未达标
</span>
<span v-if="metrics.middleLevelLeader.remaining>0" class="text-gray-500">剩余 {{
metrics.middleLevelLeader.remaining
}} </span>
</div>
</div>-->
</div>
</div>
@@ -336,6 +434,24 @@ const pushProgress = {
progress: 66.7,
remaining: 2
},
intermediateBelow: {
current: 4,
target: 6,
progress: 66.7,
remaining: 2
},
cadre: {
current: 4,
target: 6,
progress: 66.7,
remaining: 2
},
worker: {
current: 4,
target: 6,
progress: 66.7,
remaining: 2
},
ordinaryTeacher: {
current: 8,
target: 10,
@@ -88,15 +88,15 @@ const write = {
<el-input maxlength="100" placeholder="政治面貌"
v-model="formData.political"></el-input>
</el-form-item>
<el-form-item label="学历" prop="education">
<dict-select v-model="formData.education" style="width: 100%" placeholder="请选择学历"
code="USER_EDUCATION"></dict-select>
</el-form-item>
<el-form-item label="学位" prop="academicDegree">
<dict-select v-model="formData.academicDegree" style="width: 100%"
placeholder="请选择学位"
code="USER_ACADEMIC_DEGREE"></dict-select>
</el-form-item>
<!-- <el-form-item label="学历" prop="education">
<dict-select v-model="formData.education" style="width: 100%" placeholder="请选择学历"
code="USER_EDUCATION"></dict-select>
</el-form-item>
<el-form-item label="学位" prop="academicDegree">
<dict-select v-model="formData.academicDegree" style="width: 100%"
placeholder="请选择学位"
code="USER_ACADEMIC_DEGREE"></dict-select>
</el-form-item>-->
<el-form-item label="所属工会">
<el-input
@@ -128,15 +128,36 @@ const write = {
code="JobTitle"></dict-select>
</el-form-item>
<el-form-item label="是否专任教师" prop="ordinaryTeacher">
<el-radio-group v-model="formData.ordinaryTeacher" size="small">
<!-- <el-form-item label="是否专任教师" prop="ordinaryTeacher">
<el-radio-group v-model="formData.ordinaryTeacher" size="small">
<el-radio border :label="true"></el-radio>
<el-radio border :label="false"></el-radio>
</el-radio-group>
</el-form-item>-->
<el-form-item label="是否高级职称" prop="seniorTeacher">
<el-radio-group v-model="formData.seniorTeacher" size="small">
<el-radio border :label="true"></el-radio>
<el-radio border :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否级职称专任教师" prop="seniorTeacher">
<el-radio-group v-model="formData.seniorTeacher" size="small">
<el-form-item label="是否级职称及以下" prop="intermediateBelow">
<el-radio-group v-model="formData.intermediateBelow" size="small">
<el-radio border :label="true"></el-radio>
<el-radio border :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否干部" prop="cadre">
<el-radio-group v-model="formData.cadre" size="small">
<el-radio border :label="true"></el-radio>
<el-radio border :label="false"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="是否工人" prop="worker">
<el-radio-group v-model="formData.worker" size="small">
<el-radio border :label="true"></el-radio>
<el-radio border :label="false"></el-radio>
</el-radio-group>
@@ -169,13 +190,15 @@ const write = {
</div>
</div>
<div v-if="formData && formData.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080'" class="form-actions">
<div v-if="formData && formData.taskKey==='53ff0c2a-ba93-45e9-a9fd-db51cdab3080'"
class="form-actions">
<el-button @click="onSave">保存草稿</el-button>
<el-button type="primary" @click="onSubmit">提交信息</el-button>
</div>
</el-form>
<div v-if="isSelected && formData && formData.taskKey!=='53ff0c2a-ba93-45e9-a9fd-db51cdab3080'" class="completion-panel">
<div v-if="isSelected && formData && formData.taskKey!=='53ff0c2a-ba93-45e9-a9fd-db51cdab3080'"
class="completion-panel">
<div>
<i class="el-icon-success completion-icon"></i>
<h2 class="completion-title">信息提交成功</h2>
@@ -308,7 +331,9 @@ const write = {
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const loading = createLoading('正在提交中')
const {code} = await $.post('/platform/teacherCongress/delegate/push/write/save', this.formData)
loading.close()
if (code === 0) {
this.$message.success('保存成功')
this.$emit('refresh')
@@ -447,7 +472,7 @@ const write = {
margin-bottom: 24px;
}
.completion-panel ::v-deep .completion-actions {
.completion-panel ::v-deep .completion-actions {
display: flex;
justify-content: center;
gap: 16px;
@@ -467,32 +492,32 @@ const write = {
margin-bottom: 32px;
}
.info-box ::v-deep .info-content {
.info-box ::v-deep .info-content {
display: flex;
align-items: flex-start;
}
.info-box .info-content ::v-deep .info-icon {
.info-box .info-content ::v-deep .info-icon {
color: #2563eb;
margin-right: 12px;
margin-top: 2px;
}
.info-box .info-content ::v-deep .info-text {
.info-box .info-content ::v-deep .info-text {
flex: 1;
}
.info-box .info-content .info-text ::v-deep .info-title {
.info-box .info-content .info-text ::v-deep .info-title {
font-weight: 600;
margin-bottom: 8px;
}
.info-box .info-content .info-text ::v-deep .info-desc {
.info-box .info-content .info-text ::v-deep .info-desc {
color: #666;
margin-bottom: 8px;
}
.info-box .info-content .info-text ::v-deep .info-details {
.info-box .info-content .info-text ::v-deep .info-details {
font-size: 14px;
color: #666;
margin-top: 8px;
@@ -506,19 +531,19 @@ const write = {
margin-bottom: 32px;
}
.form-section ::v-deep .section-title {
.form-section ::v-deep .section-title {
font-size: 18px;
font-weight: 500;
margin-bottom: 16px;
}
.form-section ::v-deep .form-grid {
.form-section ::v-deep .form-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
column-gap: 12px;
}
.form-section ::v-deep .form-grid.full-width {
.form-section ::v-deep .form-grid.full-width {
grid-template-columns: 1fr;
}
@@ -14,7 +14,7 @@ layout("/layouts/platform.html"){
</el-select>
</search-item>
<search-item label="分工会">
<el-select v-model="pageForm.unionId" filterable @change="listUnit" clearable style="width: 100%">
<el-select v-model="pageForm.unionId" filterable clearable style="width: 100%">
<el-option v-for="i in unionOptions" :label="i.name" :key="i.id" :value="i.id"></el-option>
</el-select>
</search-item>
@@ -33,6 +33,7 @@ layout("/layouts/platform.html"){
<el-radio-button :label="true">已审核</el-radio-button>
<el-radio-button :label="false">未审核</el-radio-button>
</el-radio-group>
<el-button type="primary" size="small" @click="exportExcel" class="ml5">导出</el-button>
</table-tool>
<el-table
@@ -47,20 +48,46 @@ layout("/layouts/platform.html"){
<el-table-column label="工号" prop="loginName"></el-table-column>
<el-table-column label="性别" prop="sex" width="50"></el-table-column>
<el-table-column label="分工会" prop="unionName" show-overflow-tooltip></el-table-column>
<el-table-column label="民族" prop="nation"></el-table-column>
<!-- <el-table-column label="民族" prop="nation"></el-table-column>&lt;!&ndash;
<el-table-column label="政治面貌" prop="political"
show-overflow-tooltip></el-table-column>
<el-table-column label="学历" prop="education"></el-table-column>
<el-table-column label="学历" prop="education"></el-table-column>-->
<el-table-column label="职称" prop="professionalTitle"></el-table-column>
<el-table-column label="职级" prop="professionalLevel"></el-table-column>
<el-table-column label="是否高级职称" prop="seniorTeacher">
<template v-slot="{row}">
<span v-if="row.seniorTeacher" style="color:#0037ff;"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="是否中级职称及以下" prop="intermediateBelow">
<template v-slot="{row}">
<span v-if="row.intermediateBelow" style="color:#0037ff;"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="是否干部" prop="cadre">
<template v-slot="{row}">
<span v-if="row.cadre" style="color:#0037ff;"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="是否工人" prop="worker">
<template v-slot="{row}">
<span v-if="row.worker" style="color:#0037ff;"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="教代会代表" prop="isJdh">
<template v-slot="{row}">
{{row.isJdh?"是":"否"}}
<span v-if="row.isJdh" style="color:#0037ff;"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="工代会代表" prop="isGdh">
<template v-slot="{row}">
{{row.isGdh?"是":"否"}}
<span v-if="row.isGdh" style="color:#0037ff;"></span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="代表类型" prop="representativeType"></el-table-column>
@@ -130,6 +157,9 @@ layout("/layouts/platform.html"){
}
},
methods: {
exportExcel() {
this.$downLoad("/platform/teacherCongress/delegate/push/zcAudit/exportExcel", this.pageForm)
},
onView(row) {
this.writeDialog = true
this.userId = row.userId
@@ -45,8 +45,11 @@ layout("/layouts/platform.html"){
<el-table-column prop="memberCount" label="会员人数"></el-table-column>
<el-table-column prop="dbCount" label="代表人数"></el-table-column>
<el-table-column prop="allocationNum" label="名额分配人数"></el-table-column>
<el-table-column prop="seniorTeaNum" label="高级职称专任教师代表数"></el-table-column>
<el-table-column prop="ordinaryTeaNum" label="专任教师代表数"></el-table-column>
<el-table-column prop="seniorTeaNum" label="高级职称代表数"></el-table-column>
<el-table-column prop="intermediateBelowNum" label="中级职称及以下代表数"></el-table-column>
<el-table-column prop="cadreNum" label="干部代表数"></el-table-column>
<el-table-column prop="workerNum" label="工人代表数"></el-table-column>
<!-- <el-table-column prop="ordinaryTeaNum" label="专任教师代表数"></el-table-column>-->
<el-table-column prop="femaleNum" label="女代表数"></el-table-column>
<el-table-column prop="less45Num" label="45岁以下代表数"></el-table-column>
</el-table>
@@ -51,7 +51,7 @@ const MANUAL_ALLOCATION_DIALOG = {
></el-input-number>
</template>
</el-table-column>
<el-table-column prop="seniorTeaNum" label="高级职称专任教师代表数">
<el-table-column prop="seniorTeaNum" label="高级职称代表数">
<template v-slot="{row}">
<el-input-number
style="width: 100%"
@@ -63,11 +63,11 @@ const MANUAL_ALLOCATION_DIALOG = {
></el-input-number>
</template>
</el-table-column>
<el-table-column prop="ordinaryTeaNum" label="专任教师代表数">
<el-table-column prop="intermediateBelowNum" label="中级职称及以下代表数">
<template v-slot="{row}">
<el-input-number
style="width: 100%"
v-model="row.ordinaryTeaNum"
v-model="row.intermediateBelowNum"
:precision="0"
:step="1"
:min="0"
@@ -75,6 +75,42 @@ const MANUAL_ALLOCATION_DIALOG = {
></el-input-number>
</template>
</el-table-column>
<el-table-column prop="cadreNum" label="干部代表数">
<template v-slot="{row}">
<el-input-number
style="width: 100%"
v-model="row.cadreNum"
:precision="0"
:step="1"
:min="0"
:max="row.quota"
></el-input-number>
</template>
</el-table-column>
<el-table-column prop="workerNum" label="工人代表数">
<template v-slot="{row}">
<el-input-number
style="width: 100%"
v-model="row.workerNum"
:precision="0"
:step="1"
:min="0"
:max="row.quota"
></el-input-number>
</template>
</el-table-column>
<!-- <el-table-column prop="ordinaryTeaNum" label="专任教师代表数">
<template v-slot="{row}">
<el-input-number
style="width: 100%"
v-model="row.ordinaryTeaNum"
:precision="0"
:step="1"
:min="0"
:max="row.quota"
></el-input-number>
</template>
</el-table-column>-->
<el-table-column prop="femaleNum" label="女代表数">
<template v-slot="{row}">
<el-input-number
@@ -66,7 +66,7 @@ let commonColumns = [
{prop: 'loginname', label: '工号', width: "100"},
{prop: 'username', label: '姓名', width: "80"},
{prop: 'sex', label: '性别', sortable: true, width: '100px', checked: 0},
{prop: 'personType', label: '教职工类别', sortable: true, width: "100"},
{prop: 'personType', label: '人员类型', sortable: true, width: "100"},
{prop: 'userState', label: '在职状态', sortable: true, width: "100"},
{prop: 'unionname', label: '所属工会', sortable: true},
{prop: 'unitname', label: '所属单位', sortable: true}
@@ -124,6 +124,320 @@ layout("/layouts/platform.html"){
}
})
</script>
<style>
.welfare-select-view-dialog .el-dialog__body {
padding: 20px;
}
/* 项目信息卡片 */
.project-info-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
margin-bottom: 16px;
overflow: hidden;
}
.project-info-header {
padding: 14px 16px;
border-bottom: 1px solid #EBEEF5;
font-size: 16px;
font-weight: 600;
color: #303133;
display: flex;
align-items: center;
background: linear-gradient(135deg, #f8f9fb 0%, #fff 100%);
}
.project-info-header i {
margin-right: 8px;
color: var(--color-primary);
font-size: 18px;
}
.project-info-content {
padding: 0;
}
.info-item {
display: flex;
align-items: center;
padding: 12px 16px;
border-bottom: 1px solid #EBEEF5;
}
.info-item:last-child {
border-bottom: none;
}
.info-label {
width: 100px;
color: #606266;
font-weight: 500;
flex-shrink: 0;
}
.info-value {
flex: 1;
color: #303133;
}
/* 选择卡片 */
.my-selections-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
overflow: hidden;
}
.selections-header {
padding: 14px 16px;
border-bottom: 1px solid #EBEEF5;
font-size: 16px;
font-weight: 600;
color: #303133;
display: flex;
align-items: center;
background: linear-gradient(135deg, #f8f9fb 0%, #fff 100%);
}
.selections-header i {
margin-right: 8px;
color: var(--color-primary);
font-size: 18px;
}
.selections-content {
padding: 16px;
}
.selection-item {
display: flex;
align-items: center;
padding: 12px;
border-radius: 6px;
margin-bottom: 12px;
background: #f8f9fb;
transition: all 0.3s;
}
.selection-item:last-child {
margin-bottom: 0;
}
.selection-item:hover {
transform: translateX(4px);
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
}
.selection-item-image {
width: 80px;
height: 80px;
border-radius: 4px;
overflow: hidden;
flex-shrink: 0;
}
.selection-item-image .el-image {
width: 100%;
height: 100%;
}
.image-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #f5f7fa;
color: #909399;
font-size: 24px;
}
.selection-item-info {
flex: 1;
padding: 0 16px;
display: flex;
flex-direction: column;
}
.selection-item-name {
font-size: 15px;
font-weight: 600;
color: #303133;
margin-bottom: 6px;
}
.selection-item-meta {
margin-bottom: 8px;
}
.selection-item-count, .selection-item-time {
font-size: 13px;
color: #606266;
margin-bottom: 4px;
}
.selection-item-actions {
margin-top: 4px;
}
.detail-btn {
padding: 4px 8px;
font-size: 12px;
color: var(--color-primary);
background: #ecf5ff;
border-radius: 4px;
}
.detail-btn:hover {
background: #dbecff;
color: #3a8ee6;
}
.detail-btn i {
margin-right: 4px;
}
.count-value {
color: var(--color-primary);
font-weight: 600;
background: #ecf5ff;
padding: 2px 6px;
border-radius: 10px;
font-size: 12px;
}
.selection-item-status {
flex-shrink: 0;
width: 70px;
text-align: right;
}
.no-selections {
padding: 40px 0;
text-align: center;
color: #909399;
font-size: 14px;
display: flex;
flex-direction: column;
align-items: center;
}
.no-selections i {
font-size: 40px;
margin-bottom: 10px;
color: #C0C4CC;
}
/* 详情弹窗样式 */
.welfare-detail-dialog .el-dialog__body {
padding: 0;
}
.welfare-detail-content {
padding: 20px;
}
.detail-header {
display: flex;
margin-bottom: 20px;
}
.detail-image {
width: 120px;
height: 120px;
border-radius: 6px;
overflow: hidden;
flex-shrink: 0;
margin-right: 20px;
}
.detail-image .el-image {
width: 100%;
height: 100%;
}
.detail-title {
flex: 1;
}
.detail-title h3 {
margin: 0 0 12px 0;
font-size: 18px;
color: #303133;
}
.detail-meta {
display: flex;
flex-direction: column;
gap: 8px;
}
.detail-count, .detail-time {
display: flex;
align-items: center;
font-size: 14px;
color: #606266;
}
.detail-count i, .detail-time i {
margin-right: 6px;
color: #909399;
}
.detail-divider {
height: 1px;
background: #EBEEF5;
margin: 20px 0;
}
.detail-description {
color: #606266;
line-height: 1.6;
}
/* 富文本内容样式 */
.rich-text-content {
overflow-x: hidden;
word-break: break-word;
}
.rich-text-content img {
max-width: 100%;
height: auto;
border-radius: 4px;
margin: 10px 0;
}
.rich-text-content p {
margin: 8px 0;
line-height: 1.6;
}
.rich-text-content a {
color: var(--color-primary);
text-decoration: none;
}
.rich-text-content a:hover {
text-decoration: underline;
}
.rich-text-content ul, .rich-text-content ol {
padding-left: 20px;
margin: 10px 0;
}
.rich-text-content blockquote {
padding: 10px 15px;
border-left: 4px solid #EBEEF5;
background: #f8f9fb;
margin: 10px 0;
color: #606266;
}
</style>
<!--#
}
#-->
@@ -76,7 +76,7 @@ const filterUser = {
</el-select>
</search-item>
<search-item label="教职工类别">
<search-item label="人员类型">
<dict-select clearable code="USER_PERSON_TYPE"
multiple
collapse-tags
@@ -88,7 +88,7 @@ const filterUser = {
<dict-select clearable code="USER_PREPARED_BY_TYPE"
multiple
collapse-tags
placeholder="请选择聘用方式"
placeholder="请选择编制类别"
v-model="pageForm.preparedBys"></dict-select>
</search-item>
@@ -168,7 +168,7 @@ const filterUser = {
{ prop: "username", label: "姓名" },
{ prop: "sex", label: "性别", sortable: true, checked: 0 },
{ prop: "birthday", label: "出生日期", sortable: true, checked: 0 },
{ prop: "personType", label: "教职工类别", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "preparedBy", label: "编制类别", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
@@ -18,8 +18,8 @@ layout("/layouts/platform.html"){
></el-date-picker>
</search-item>
<search-item label="项目名称">
<el-input clearable placeholder="请输入项目名称" v-model="pageForm.name"></el-input>
<search-item label="活动时间">
<el-input clearable placeholder="请输入活动名称" v-model="pageForm.name"></el-input>
</search-item>
</search>
</el-card>
@@ -172,22 +172,591 @@ layout("/layouts/platform.html"){
})
</script>
<style>
.desc_label {
width: 75px;
-webkit-flex-shrink: 0;
flex-shrink: 0;
padding-right: 4px;
display: inline-block;
font-size: 14px;
color: #7f7f7f;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
/* 全局变量 */
:root {
--primary-color: #409EFF;
--primary-light: #ecf5ff;
--text-primary: #303133;
--text-secondary: #606266;
--text-light: #909399;
--border-color: #EBEEF5;
--success-color: #67c23a;
--warning-color: #e6a23c;
--danger-color: #f56c6c;
}
.desc_value {
color: #333;
/* 主容器样式 */
.welfare-select-container {
background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%);
padding: 16px;
border-radius: 8px;
max-width: 1000px;
margin: 0 auto;
}
/* 截止时间提醒 */
.welfare-deadline {
background: linear-gradient(135deg, #fff7f7 0%, #fff 100%);
border-left: 3px solid var(--danger-color);
padding: 12px 16px;
margin-bottom: 16px;
border-radius: 6px;
display: flex;
align-items: center;
color: var(--danger-color);
box-shadow: 0 2px 8px rgba(245, 108, 108, 0.1);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.01);
}
100% {
transform: scale(1);
}
}
.welfare-deadline i {
margin-right: 8px;
font-size: 16px;
}
/* 选择提示 */
.welfare-notice {
margin-bottom: 16px;
}
.welfare-notice .el-alert {
border-radius: 6px;
padding: 12px 16px;
}
/* 内容区域 */
.welfare-content {
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 16px;
}
/* 项目信息卡片 */
.welfare-info-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
width: 100%;
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.project-cover {
height: 140px;
overflow: hidden;
position: relative;
margin: -10px -20px 16px;
}
.project-cover::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
}
.project-cover .el-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.welfare-info-header {
padding: 14px 16px;
border-bottom: 1px solid var(--border-color);
font-size: 16px;
font-weight: 600;
color: var(--text-primary);
display: flex;
align-items: center;
background: linear-gradient(135deg, #f8f9fb 0%, #fff 100%);
}
.welfare-info-header i {
margin-right: 8px;
color: var(--primary-color);
font-size: 18px;
}
.info-item {
display: flex;
padding: 12px 16px;
border-bottom: 1px solid var(--border-color);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.info-item:hover {
background: var(--primary-light);
}
.info-item:last-child {
border-bottom: none;
}
.info-label {
width: 100px;
color: var(--text-secondary);
font-weight: 500;
flex-shrink: 0;
}
.info-value {
flex: 1;
color: var(--text-primary);
}
/* 福利选项卡片 */
.welfare-options-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
width: 100%;
overflow: hidden;
}
.options-count {
font-size: 14px;
color: var(--text-light);
font-weight: normal;
margin-left: 8px;
opacity: 0.8;
}
/* 选项网格 */
.welfare-options-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
padding: 16px;
}
/* 选项卡片 */
.welfare-option {
position: relative;
border-radius: 6px;
overflow: hidden;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 2px solid transparent;
height: 100%;
display: flex;
flex-direction: column;
cursor: pointer;
animation: fadeIn 0.6s ease-out forwards;
}
.welfare-option:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
transform: translateY(-2px);
}
.welfare-option.selected {
border-color: var(--primary-color);
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.15);
}
.welfare-option.selected::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--primary-color), #66b1ff);
z-index: 1;
}
/* 选项标签 */
.option-tag {
position: absolute;
top: 8px;
right: 8px;
z-index: 2;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
box-shadow: 0 2px 6px rgba(64, 158, 255, 0.2);
}
/* 选项图片 */
.option-image {
width: 100%;
height: 160px;
overflow: hidden;
position: relative;
}
.option-image::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: linear-gradient(to top, rgba(0, 0, 0, 0.2), transparent);
}
.option-image .el-image {
width: 100%;
height: 100%;
transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.welfare-option:hover .option-image .el-image {
transform: scale(1.06);
}
/* 选项内容 */
.option-content {
padding: 12px 16px;
flex: 1;
display: flex;
flex-direction: column;
position: relative;
background: linear-gradient(135deg, #fff 0%, #f8f9fb 100%);
}
.option-title {
font-size: 14px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 8px;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
padding-right: 24px;
}
.option-detail-btn {
display: inline-flex;
align-items: center;
color: var(--primary-color);
font-size: 13px;
margin-top: 8px;
padding: 4px 8px;
border-radius: 4px;
background: var(--primary-light);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
}
.option-detail-btn i {
margin-right: 4px;
font-size: 14px;
}
.option-detail-btn:hover {
background: #dceeff;
transform: translateX(4px);
}
/* 选择控件 */
.option-radio {
position: absolute;
top: 12px;
right: 12px;
}
.option-stepper {
position: absolute;
bottom: 12px;
right: 12px;
}
.option-stepper .el-input-number {
width: 100px;
}
/* 底部按钮 */
.welfare-footer {
display: flex;
justify-content: center;
padding: 16px 0;
}
.welfare-footer .el-button {
min-width: 140px;
height: 40px;
font-size: 15px;
font-weight: 500;
border-radius: 20px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.welfare-footer .el-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.25);
}
/* 确认弹窗样式 */
.welfare-confirm-dialog {
border-radius: 8px;
}
.confirm-content {
padding: 16px 0;
}
.confirm-section-title {
font-size: 15px;
color: var(--text-primary);
margin-bottom: 12px;
font-weight: 500;
position: relative;
padding-left: 10px;
}
.confirm-section-title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 14px;
background: var(--primary-color);
border-radius: 2px;
}
.confirm-mobile-section {
margin-bottom: 20px;
}
.selected-items {
background: #f8f9fb;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
max-height: 300px;
overflow-y: auto;
}
.selected-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
background: #fff;
border-radius: 8px;
margin-bottom: 10px;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}
.selected-item:last-child {
margin-bottom: 0;
}
.selected-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.selected-item-left {
display: flex;
align-items: center;
flex: 1;
min-width: 0;
}
.selected-item-image {
width: 60px;
height: 60px;
border-radius: 8px;
overflow: hidden;
margin-right: 12px;
flex-shrink: 0;
background: #f5f5f5;
border: 1px solid rgba(0, 0, 0, 0.06);
}
.selected-item-image .el-image {
width: 100%;
height: 100%;
display: block;
}
.image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
color: #909399;
font-size: 20px;
}
.selected-item-info {
flex: 1;
min-width: 0;
padding: 4px 0;
}
.selected-item-name {
color: var(--text-primary);
font-weight: 500;
font-size: 15px;
line-height: 1.4;
margin-bottom: 6px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.selected-item-quantity {
color: var(--text-secondary);
font-size: 13px;
display: flex;
align-items: center;
}
.selected-item-quantity i {
margin-right: 4px;
font-size: 14px;
color: var(--primary-color);
}
.selected-item-right {
flex-shrink: 0;
margin-left: 16px;
}
.selected-item-right .el-tag {
font-size: 13px;
font-weight: 600;
padding: 0 10px;
height: 24px;
line-height: 22px;
border-radius: 12px;
}
.confirm-total {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
background: #f8f9fb;
border-radius: 6px;
margin-top: 16px;
}
.total-label {
color: var(--text-secondary);
font-weight: 500;
font-size: 14px;
}
.total-value {
color: var(--primary-color);
font-weight: 600;
font-size: 15px;
}
.confirm-warning {
margin-top: 16px;
padding: 10px 14px;
background: #fff7e6;
border-radius: 6px;
color: var(--warning-color);
display: flex;
align-items: center;
font-size: 13px;
}
.confirm-warning.warning {
background: #fef0f0;
color: var(--danger-color);
}
.confirm-warning i {
margin-right: 6px;
font-size: 16px;
}
.deadline-info {
margin-top: 12px;
padding: 10px 14px;
background: var(--primary-light);
border-radius: 6px;
color: var(--primary-color);
display: flex;
align-items: center;
font-size: 13px;
}
.deadline-info i {
margin-right: 6px;
font-size: 16px;
}
/* 详情弹窗 */
.welfare-detail-dialog {
border-radius: 8px;
}
.welfare-detail-popup {
padding: 16px;
min-height: 200px;
}
.welfare-detail-title {
font-size: 18px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid var(--border-color);
text-align: center;
}
.welfare-detail-content {
color: var(--text-secondary);
line-height: 1.6;
font-size: 14px;
}
/* 加载状态 */
.welfare-loading {
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
}
/* 动画 */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.welfare-select-container > * {
animation: fadeIn 0.5s ease-out forwards;
}
</style>
@@ -138,16 +138,24 @@ const optionSelect = {
<!-- 联系电话输入 -->
<div class="confirm-mobile-section">
<div class="confirm-section-title">联系信息</div>
<el-form :model="contactForm" ref="contactForm" :rules="contactRules">
<el-form-item prop="mobile">
<el-form :model="contactForm" ref="contactForm" :rules="contactRules" label-width="80px">
<el-form-item prop="mobile" label="联系电话">
<el-input
v-model="contactForm.mobile"
placeholder="请输入手机号码"
maxlength="11"
clearable>
<template slot="prepend">联系电话</template>
</el-input>
</el-form-item>
<el-form-item v-if="projectInfo.provideMode == 3" prop="receiveAddress" label="收货地址" :rules="[{ required: true, message: '请选择收货地址', trigger: 'change' }]">
<el-select v-model="contactForm.receiveAddress" placeholder="请选择收货地址" style="width: 100%">
<el-option v-for="item in addressOptions"
:key="item.id"
:label="item.userName + ' ' + item.tel + ' ' + item.province + ' ' + item.city + ' ' + item.county + ' ' + item.addressDetail"
:value="item.userName + ' ' + item.tel + ' ' + item.province + ' ' + item.city + ' ' + item.county + ' ' + item.addressDetail">
</el-option>
</el-select>
</el-form-item>
</el-form>
</div>
@@ -222,7 +230,8 @@ const optionSelect = {
showOptionDetailDialog: false, // 选项详情弹窗
selectedOption: null, // 当前选中的选项
contactForm: {
mobile: "" // 联系电话
mobile: "", // 联系电话,
receiveAddress: ""
},
contactRules: {
mobile: [
@@ -316,7 +325,8 @@ const optionSelect = {
this.selectedRadioId = null
this.contactForm = {
mobile: ""
mobile: "",
receiveAddress: ""
}
this.getProjectInfo()
@@ -329,6 +339,11 @@ const optionSelect = {
this.projectInfo = res.data
this.deadlineTime = this.projectInfo.choiceTimeEnd
// 获取收货地址
if (this.projectInfo.provideMode === 3) {
this.getAddress()
}
// 初始化选项的selectNum为0
if (this.projectInfo.options) {
this.projectInfo.options.forEach((option) => {
@@ -363,6 +378,22 @@ const optionSelect = {
if (this.userSelection && this.userSelection.length > 0) {
this.contactForm.mobile = this.userSelection[0]?.mobile
} else {
if (this.isProxySelect) {
// 否则使用默认手机号
$.post("/platform/welfare/selection/situation/getMobileByUserId", { userId: this.userId }).then((res) => {
if (res.code === 0) {
this.contactForm.mobile = res.data
}
})
}
}
// 地址回显
if (this.projectInfo.provideMode === 3) {
if (this.userSelection && this.userSelection[0].receiveAddress) {
this.contactForm.receiveAddress = this.userSelection[0].receiveAddress
}
}
// 设置已选择的选项
@@ -411,7 +442,8 @@ const optionSelect = {
{
selectOptionId: this.selectedRadioId,
selectNum: 1,
mobile: this.contactForm.mobile
mobile: this.contactForm.mobile,
receiveAddress: this.contactForm.receiveAddress
}
]
}
@@ -421,7 +453,8 @@ const optionSelect = {
selections = this.selectedOptions.map((option) => ({
selectOptionId: option.id,
selectNum: option.selectNum,
mobile: this.contactForm.mobile
mobile: this.contactForm.mobile,
receiveAddress: this.contactForm.receiveAddress
}))
}
@@ -501,6 +534,14 @@ const optionSelect = {
event.stopPropagation()
this.selectedOption = option
this.showOptionDetailDialog = true
},
// 获取收货地址
async getAddress() {
const resp = await this.$axios.post("/platform/welfare/addressManage/selectUserAddress")
if (resp.code === 0) {
this.addressOptions = resp.data
}
}
},
watch: {
@@ -526,7 +567,7 @@ const optionSelect = {
},
style: /*language=CSS*/ `
/* 全局变量 */
:root {
:root {
--primary-color: #409EFF;
--primary-light: #ecf5ff;
--text-primary: #303133;
@@ -539,7 +580,7 @@ const optionSelect = {
}
/* 主容器样式 */
.welfare-select-container {
.welfare-select-container {
background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%);
padding: 16px;
border-radius: 8px;
@@ -548,7 +589,7 @@ const optionSelect = {
}
/* 截止时间提醒 */
.welfare-deadline {
.welfare-deadline {
background: linear-gradient(135deg, #fff7f7 0%, #fff 100%);
border-left: 3px solid var(--danger-color);
padding: 12px 16px;
@@ -573,23 +614,23 @@ const optionSelect = {
}
}
.welfare-deadline i {
.welfare-deadline i {
margin-right: 8px;
font-size: 16px;
}
/* 选择提示 */
.welfare-notice {
.welfare-notice {
margin-bottom: 16px;
}
.welfare-notice .el-alert {
.welfare-notice .el-alert {
border-radius: 6px;
padding: 12px 16px;
}
/* 内容区域 */
.welfare-content {
.welfare-content {
display: flex;
flex-direction: column;
gap: 16px;
@@ -597,7 +638,7 @@ const optionSelect = {
}
/* 项目信息卡片 */
.welfare-info-card {
.welfare-info-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
@@ -606,14 +647,14 @@ const optionSelect = {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.project-cover {
.project-cover {
height: 140px;
overflow: hidden;
position: relative;
margin: -10px -20px 16px;
}
.project-cover::after {
.project-cover::after {
content: '';
position: absolute;
bottom: 0;
@@ -623,13 +664,13 @@ const optionSelect = {
background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
}
.project-cover .el-image {
.project-cover .el-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.welfare-info-header {
.welfare-info-header {
padding: 14px 16px;
border-bottom: 1px solid var(--border-color);
font-size: 16px;
@@ -640,41 +681,41 @@ const optionSelect = {
background: linear-gradient(135deg, #f8f9fb 0%, #fff 100%);
}
.welfare-info-header i {
.welfare-info-header i {
margin-right: 8px;
color: var(--primary-color);
font-size: 18px;
}
.info-item {
.info-item {
display: flex;
padding: 12px 16px;
border-bottom: 1px solid var(--border-color);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.info-item:hover {
.info-item:hover {
background: var(--primary-light);
}
.info-item:last-child {
.info-item:last-child {
border-bottom: none;
}
.info-label {
.info-label {
width: 100px;
color: var(--text-secondary);
font-weight: 500;
flex-shrink: 0;
}
.info-value {
.info-value {
flex: 1;
color: var(--text-primary);
}
/* 福利选项卡片 */
.welfare-options-card {
.welfare-options-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
@@ -682,7 +723,7 @@ const optionSelect = {
overflow: hidden;
}
.options-count {
.options-count {
font-size: 14px;
color: var(--text-light);
font-weight: normal;
@@ -691,7 +732,7 @@ const optionSelect = {
}
/* 选项网格 */
.welfare-options-grid {
.welfare-options-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
@@ -699,7 +740,7 @@ const optionSelect = {
}
/* 选项卡片 */
.welfare-option {
.welfare-option {
position: relative;
border-radius: 6px;
overflow: hidden;
@@ -714,17 +755,17 @@ const optionSelect = {
animation: fadeIn 0.6s ease-out forwards;
}
.welfare-option:hover {
.welfare-option:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
transform: translateY(-2px);
}
.welfare-option.selected {
.welfare-option.selected {
border-color: var(--primary-color);
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.15);
}
.welfare-option.selected::before {
.welfare-option.selected::before {
content: '';
position: absolute;
top: 0;
@@ -736,7 +777,7 @@ const optionSelect = {
}
/* 选项标签 */
.option-tag {
.option-tag {
position: absolute;
top: 8px;
right: 8px;
@@ -749,14 +790,14 @@ const optionSelect = {
}
/* 选项图片 */
.option-image {
.option-image {
width: 100%;
height: 160px;
overflow: hidden;
position: relative;
}
.option-image::after {
.option-image::after {
content: '';
position: absolute;
bottom: 0;
@@ -766,18 +807,18 @@ const optionSelect = {
background: linear-gradient(to top, rgba(0, 0, 0, 0.2), transparent);
}
.option-image .el-image {
.option-image .el-image {
width: 100%;
height: 100%;
transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.welfare-option:hover .option-image .el-image {
.welfare-option:hover .option-image .el-image {
transform: scale(1.06);
}
/* 选项内容 */
.option-content {
.option-content {
padding: 12px 16px;
flex: 1;
display: flex;
@@ -786,7 +827,7 @@ const optionSelect = {
background: linear-gradient(135deg, #fff 0%, #f8f9fb 100%);
}
.option-title {
.option-title {
font-size: 14px;
font-weight: 600;
color: var(--text-primary);
@@ -800,7 +841,7 @@ const optionSelect = {
padding-right: 24px;
}
.option-detail-btn {
.option-detail-btn {
display: inline-flex;
align-items: center;
color: var(--primary-color);
@@ -813,41 +854,41 @@ const optionSelect = {
cursor: pointer;
}
.option-detail-btn i {
.option-detail-btn i {
margin-right: 4px;
font-size: 14px;
}
.option-detail-btn:hover {
.option-detail-btn:hover {
background: #dceeff;
transform: translateX(4px);
}
/* 选择控件 */
.option-radio {
.option-radio {
position: absolute;
top: 12px;
right: 12px;
}
.option-stepper {
.option-stepper {
position: absolute;
bottom: 12px;
right: 12px;
}
.option-stepper .el-input-number {
.option-stepper .el-input-number {
width: 100px;
}
/* 底部按钮 */
.welfare-footer {
.welfare-footer {
display: flex;
justify-content: center;
padding: 16px 0;
}
.welfare-footer .el-button {
.welfare-footer .el-button {
min-width: 140px;
height: 40px;
font-size: 15px;
@@ -856,21 +897,21 @@ const optionSelect = {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.welfare-footer .el-button:hover {
.welfare-footer .el-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.25);
}
/* 确认弹窗样式 */
.welfare-confirm-dialog {
.welfare-confirm-dialog {
border-radius: 8px;
}
.confirm-content {
.confirm-content {
padding: 16px 0;
}
.confirm-section-title {
.confirm-section-title {
font-size: 15px;
color: var(--text-primary);
margin-bottom: 12px;
@@ -879,7 +920,7 @@ const optionSelect = {
padding-left: 10px;
}
.confirm-section-title::before {
.confirm-section-title::before {
content: '';
position: absolute;
left: 0;
@@ -891,11 +932,11 @@ const optionSelect = {
border-radius: 2px;
}
.confirm-mobile-section {
.confirm-mobile-section {
margin-bottom: 20px;
}
.selected-items {
.selected-items {
background: #f8f9fb;
border-radius: 8px;
padding: 16px;
@@ -904,7 +945,7 @@ const optionSelect = {
overflow-y: auto;
}
.selected-item {
.selected-item {
display: flex;
justify-content: space-between;
align-items: center;
@@ -916,11 +957,11 @@ const optionSelect = {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}
.selected-item:last-child {
.selected-item:last-child {
margin-bottom: 0;
}
.selected-item:hover {
.selected-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
@@ -99,6 +99,9 @@ layout("/layouts/platform.html"){
show-overflow-tooltip
v-for="column in tableColumns"
></el-table-column>
<el-table-column label="收货地址" prop="receiveAddress" v-if="provideMode===3"></el-table-column>
<el-table-column align="center" fixed="right" header-align="center" label="操作" width="100px">
<template slot-scope="{row}">
<el-button size="mini" type="primary" @click="proxySelect(row)">代选</el-button>
@@ -152,6 +155,9 @@ layout("/layouts/platform.html"){
return this.projectOptions.find((item) => item.id === this.pageForm.projectId).options
}
return []
},
provideMode() {
return this.projectOptions.find((item) => item.id === this.pageForm.projectId).provideMode
}
},
methods: {
@@ -205,6 +211,595 @@ layout("/layouts/platform.html"){
})
</script>
<style>
/* 全局变量 */
:root {
--primary-color: #409EFF;
--primary-light: #ecf5ff;
--text-primary: #303133;
--text-secondary: #606266;
--text-light: #909399;
--border-color: #EBEEF5;
--success-color: #67c23a;
--warning-color: #e6a23c;
--danger-color: #f56c6c;
}
/* 主容器样式 */
.welfare-select-container {
background: linear-gradient(135deg, #f5f7fa 0%, #ffffff 100%);
padding: 16px;
border-radius: 8px;
max-width: 1000px;
margin: 0 auto;
}
/* 截止时间提醒 */
.welfare-deadline {
background: linear-gradient(135deg, #fff7f7 0%, #fff 100%);
border-left: 3px solid var(--danger-color);
padding: 12px 16px;
margin-bottom: 16px;
border-radius: 6px;
display: flex;
align-items: center;
color: var(--danger-color);
box-shadow: 0 2px 8px rgba(245, 108, 108, 0.1);
animation: pulse 2s infinite;
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.01);
}
100% {
transform: scale(1);
}
}
.welfare-deadline i {
margin-right: 8px;
font-size: 16px;
}
/* 选择提示 */
.welfare-notice {
margin-bottom: 16px;
}
.welfare-notice .el-alert {
border-radius: 6px;
padding: 12px 16px;
}
/* 内容区域 */
.welfare-content {
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 16px;
}
/* 项目信息卡片 */
.welfare-info-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
width: 100%;
overflow: hidden;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.project-cover {
height: 140px;
overflow: hidden;
position: relative;
margin: -10px -20px 16px;
}
.project-cover::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: linear-gradient(to top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));
}
.project-cover .el-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.welfare-info-header {
padding: 14px 16px;
border-bottom: 1px solid var(--border-color);
font-size: 16px;
font-weight: 600;
color: var(--text-primary);
display: flex;
align-items: center;
background: linear-gradient(135deg, #f8f9fb 0%, #fff 100%);
}
.welfare-info-header i {
margin-right: 8px;
color: var(--primary-color);
font-size: 18px;
}
.info-item {
display: flex;
padding: 12px 16px;
border-bottom: 1px solid var(--border-color);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.info-item:hover {
background: var(--primary-light);
}
.info-item:last-child {
border-bottom: none;
}
.info-label {
width: 100px;
color: var(--text-secondary);
font-weight: 500;
flex-shrink: 0;
}
.info-value {
flex: 1;
color: var(--text-primary);
}
/* 福利选项卡片 */
.welfare-options-card {
background: #fff;
border-radius: 8px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
width: 100%;
overflow: hidden;
}
.options-count {
font-size: 14px;
color: var(--text-light);
font-weight: normal;
margin-left: 8px;
opacity: 0.8;
}
/* 选项网格 */
.welfare-options-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
gap: 16px;
padding: 16px;
}
/* 选项卡片 */
.welfare-option {
position: relative;
border-radius: 6px;
overflow: hidden;
background: #fff;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
border: 2px solid transparent;
height: 100%;
display: flex;
flex-direction: column;
cursor: pointer;
animation: fadeIn 0.6s ease-out forwards;
}
.welfare-option:hover {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
transform: translateY(-2px);
}
.welfare-option.selected {
border-color: var(--primary-color);
box-shadow: 0 4px 16px rgba(64, 158, 255, 0.15);
}
.welfare-option.selected::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 3px;
background: linear-gradient(90deg, var(--primary-color), #66b1ff);
z-index: 1;
}
/* 选项标签 */
.option-tag {
position: absolute;
top: 8px;
right: 8px;
z-index: 2;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: 500;
box-shadow: 0 2px 6px rgba(64, 158, 255, 0.2);
}
/* 选项图片 */
.option-image {
width: 100%;
height: 160px;
overflow: hidden;
position: relative;
}
.option-image::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background: linear-gradient(to top, rgba(0, 0, 0, 0.2), transparent);
}
.option-image .el-image {
width: 100%;
height: 100%;
transition: transform 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.welfare-option:hover .option-image .el-image {
transform: scale(1.06);
}
/* 选项内容 */
.option-content {
padding: 12px 16px;
flex: 1;
display: flex;
flex-direction: column;
position: relative;
background: linear-gradient(135deg, #fff 0%, #f8f9fb 100%);
}
.option-title {
font-size: 14px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 8px;
line-height: 1.4;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
padding-right: 24px;
}
.option-detail-btn {
display: inline-flex;
align-items: center;
color: var(--primary-color);
font-size: 13px;
margin-top: 8px;
padding: 4px 8px;
border-radius: 4px;
background: var(--primary-light);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
}
.option-detail-btn i {
margin-right: 4px;
font-size: 14px;
}
.option-detail-btn:hover {
background: #dceeff;
transform: translateX(4px);
}
/* 选择控件 */
.option-radio {
position: absolute;
top: 12px;
right: 12px;
}
.option-stepper {
position: absolute;
bottom: 12px;
right: 12px;
}
.option-stepper .el-input-number {
width: 100px;
}
/* 底部按钮 */
.welfare-footer {
display: flex;
justify-content: center;
padding: 16px 0;
}
.welfare-footer .el-button {
min-width: 140px;
height: 40px;
font-size: 15px;
font-weight: 500;
border-radius: 20px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.welfare-footer .el-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.25);
}
/* 确认弹窗样式 */
.welfare-confirm-dialog {
border-radius: 8px;
}
.confirm-content {
padding: 16px 0;
}
.confirm-section-title {
font-size: 15px;
color: var(--text-primary);
margin-bottom: 12px;
font-weight: 500;
position: relative;
padding-left: 10px;
}
.confirm-section-title::before {
content: '';
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
width: 3px;
height: 14px;
background: var(--primary-color);
border-radius: 2px;
}
.confirm-mobile-section {
margin-bottom: 20px;
}
.selected-items {
background: #f8f9fb;
border-radius: 8px;
padding: 16px;
margin-bottom: 16px;
max-height: 300px;
overflow-y: auto;
}
.selected-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
background: #fff;
border-radius: 8px;
margin-bottom: 10px;
transition: all 0.3s ease;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
}
.selected-item:last-child {
margin-bottom: 0;
}
.selected-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}
.selected-item-left {
display: flex;
align-items: center;
flex: 1;
min-width: 0;
}
.selected-item-image {
width: 60px;
height: 60px;
border-radius: 8px;
overflow: hidden;
margin-right: 12px;
flex-shrink: 0;
background: #f5f5f5;
border: 1px solid rgba(0, 0, 0, 0.06);
}
.selected-item-image .el-image {
width: 100%;
height: 100%;
display: block;
}
.image-slot {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
color: #909399;
font-size: 20px;
}
.selected-item-info {
flex: 1;
min-width: 0;
padding: 4px 0;
}
.selected-item-name {
color: var(--text-primary);
font-weight: 500;
font-size: 15px;
line-height: 1.4;
margin-bottom: 6px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.selected-item-quantity {
color: var(--text-secondary);
font-size: 13px;
display: flex;
align-items: center;
}
.selected-item-quantity i {
margin-right: 4px;
font-size: 14px;
color: var(--primary-color);
}
.selected-item-right {
flex-shrink: 0;
margin-left: 16px;
}
.selected-item-right .el-tag {
font-size: 13px;
font-weight: 600;
padding: 0 10px;
height: 24px;
line-height: 22px;
border-radius: 12px;
}
.confirm-total {
display: flex;
justify-content: space-between;
align-items: center;
padding: 12px;
background: #f8f9fb;
border-radius: 6px;
margin-top: 16px;
}
.total-label {
color: var(--text-secondary);
font-weight: 500;
font-size: 14px;
}
.total-value {
color: var(--primary-color);
font-weight: 600;
font-size: 15px;
}
.confirm-warning {
margin-top: 16px;
padding: 10px 14px;
background: #fff7e6;
border-radius: 6px;
color: var(--warning-color);
display: flex;
align-items: center;
font-size: 13px;
}
.confirm-warning.warning {
background: #fef0f0;
color: var(--danger-color);
}
.confirm-warning i {
margin-right: 6px;
font-size: 16px;
}
.deadline-info {
margin-top: 12px;
padding: 10px 14px;
background: var(--primary-light);
border-radius: 6px;
color: var(--primary-color);
display: flex;
align-items: center;
font-size: 13px;
}
.deadline-info i {
margin-right: 6px;
font-size: 16px;
}
/* 详情弹窗 */
.welfare-detail-dialog {
border-radius: 8px;
}
.welfare-detail-popup {
padding: 16px;
min-height: 200px;
}
.welfare-detail-title {
font-size: 18px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 16px;
padding-bottom: 12px;
border-bottom: 1px solid var(--border-color);
text-align: center;
}
.welfare-detail-content {
color: var(--text-secondary);
line-height: 1.6;
font-size: 14px;
}
/* 加载状态 */
.welfare-loading {
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
}
/* 动画 */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.welfare-select-container > * {
animation: fadeIn 0.5s ease-out forwards;
}
</style>
<!--#
}
#-->
@@ -78,7 +78,7 @@ const addUser = {
</el-select>
</search-item>
<search-item label="教职工类别">
<search-item label="人员类型">
<dict-select clearable code="USER_PERSON_TYPE"
multiple
collapse-tags
@@ -90,7 +90,7 @@ const addUser = {
<dict-select clearable code="USER_PREPARED_BY_TYPE"
multiple
collapse-tags
placeholder="请选择聘用方式"
placeholder="请选择编制类别"
v-model="pageForm.preparedBys"></dict-select>
</search-item>
@@ -174,7 +174,7 @@ const addUser = {
{ prop: "username", label: "姓名" },
{ prop: "sex", label: "性别", sortable: true, checked: 0 },
{ prop: "birthday", label: "出生日期", sortable: true, checked: 0 },
{ prop: "personType", label: "教职工类别", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "preparedBy", label: "编制类别", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true },
@@ -27,7 +27,7 @@ let ADD_WELFARE_LIST_BY_SELECT = {
<el-table-column label="工号" prop="loginname" sortable width="150px"></el-table-column>
<el-table-column label="姓名" prop="username" sortable width="150px"></el-table-column>
<el-table-column label="在职状态" prop="userState" sortable width="150px"></el-table-column>
<el-table-column label="编制类别" prop="personType" sortable width="150px"></el-table-column>
<el-table-column label="人事编制" prop="personType" sortable width="150px"></el-table-column>
<el-table-column label="所在单位" prop="unitName" show-overflow-tooltip
sortable></el-table-column>
<el-table-column label="所在工会" prop="unionName" sortable></el-table-column>
@@ -87,7 +87,7 @@ layout("/layouts/platform.html"){
</el-select>
</search-item>
<search-item label="教职工类别">
<search-item label="人员类型">
<dict-select
clearable
code="USER_PERSON_TYPE"
@@ -104,7 +104,7 @@ layout("/layouts/platform.html"){
code="USER_PREPARED_BY_TYPE"
multiple
collapse-tags
placeholder="请选择聘用方式"
placeholder="请选择编制类别"
v-model="pageForm.preparedBys"
></dict-select>
</search-item>
@@ -264,7 +264,7 @@ layout("/layouts/platform.html"){
{ prop: "username", label: "姓名" },
{ prop: "sex", label: "性别", sortable: true, checked: 0 },
{ prop: "birthday", label: "出生日期", sortable: true, checked: 0 },
{ prop: "personType", label: "教职工类别", sortable: true },
{ prop: "personType", label: "人员类型", sortable: true },
{ prop: "preparedBy", label: "编制类别", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "welfareUnionName", label: "所属工会", sortable: true },
@@ -8,6 +8,8 @@ layout("/layouts/platform_h5.html"){
}
.list-card-body {
/* width: calc(100% - 140px);
display: flex;*/
width: calc(100% - 140px);
display: flex;
flex-direction: column;
@@ -35,6 +37,9 @@ layout("/layouts/platform_h5.html"){
padding: 5px;
border-radius: 5px;
}
.list-card-img img{
width: 100%;
}
</style>
<div id="app" v-cloak>
@@ -44,6 +49,7 @@ layout("/layouts/platform_h5.html"){
<year-van-dropdown-item :num="5" @change="doSearch" v-model="pageForm.year"></year-van-dropdown-item>
<van-dropdown-item :options="stateList" @change="doSearch" v-model="pageForm.state"></van-dropdown-item>
<van-dropdown-item :options="isEnrolledOptions" @change="doSearch" v-model="pageForm.isEnrolledText"></van-dropdown-item>
<van-dropdown-item :options="activityTypeOptions" @change="doSearch" v-model="pageForm.activity_type"></van-dropdown-item>
</van-dropdown-menu>
</van-sticky>
@@ -58,33 +64,33 @@ layout("/layouts/platform_h5.html"){
<div class="time">{{item.startTime + ' 至 ' + item.endTime}}</div>
<div class="footer">
<span
class="tag"
v-if="$moment(item.applyStartTime).valueOf() > $moment().valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
class="tag"
v-if="$moment(item.applyStartTime).valueOf() > $moment().valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
>
未开始报名
</span>
<span
class="tag"
v-else-if="$moment(item.applyEndTime).valueOf() > $moment().valueOf() && $moment().valueOf() > $moment(item.applyStartTime).valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
class="tag"
v-else-if="$moment(item.applyEndTime).valueOf() > $moment().valueOf() && $moment().valueOf() > $moment(item.applyStartTime).valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
>
报名进行中
</span>
<span
class="tag"
v-else-if="$moment(item.applyEndTime).valueOf() < $moment().valueOf() && $moment().valueOf() < $moment(item.startTime).valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
class="tag"
v-else-if="$moment(item.applyEndTime).valueOf() < $moment().valueOf() && $moment().valueOf() < $moment(item.startTime).valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
>
报名已结束
</span>
<span
class="tag"
v-else-if="$moment(item.startTime).valueOf() < $moment().valueOf() && $moment().valueOf() < $moment(item.endTime).valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
class="tag"
v-else-if="$moment(item.startTime).valueOf() < $moment().valueOf() && $moment().valueOf() < $moment(item.endTime).valueOf()"
style="color: var(--color-primary); border: 1px solid var(--color-primary)"
>
活动进行中
</span>
@@ -120,7 +126,8 @@ layout("/layouts/platform_h5.html"){
year: new Date().getFullYear(),
pageNumber: 1,
pageSize: 5,
totalCount: 0
totalCount: 0,
activity_type: 40001
},
yearList: [],
isEnrolledOptions: [
@@ -134,7 +141,12 @@ layout("/layouts/platform_h5.html"){
],
subLoading: false,
viewShow: false,
viewData: {}
viewData: {},
activityTypeOptions: [
{ value: 40001, text: "校文化活动" },
{ value: 40002, text: "分工会文化活动" },
{ value: 40003, text: "协会文化活动" },
]
}
},
components: {
@@ -270,3 +282,4 @@ layout("/layouts/platform_h5.html"){
<!--#
}
#-->
@@ -74,11 +74,7 @@ layout("/layouts/platform_h5.html"){
}, 500)
},
back() {
if (this.projectId) {
this.$pjaxReplace("/platform/h5/welfare/userChoose/index?id=" + this.projectId)
} else {
this.$pjaxReplace("/platform/h5/home")
}
this.historyBack()
},
onEdit(row) {
this.title = "编辑地址"
@@ -56,6 +56,10 @@ const selectView = {
<div class="info-row__label">联系电话</div>
<div class="info-row__value">{{ mergedSelections[0]?.mobile || '暂无' }}</div>
</div>
<div class="info-row">
<div class="info-row__label">收货地址</div>
<div class="info-row__value">{{ mergedSelections[0]?.receiveAddress || '暂无' }}</div>
</div>
</div>
</div>
@@ -73,7 +77,7 @@ const selectView = {
:key="item.id"
@click="showOptionDetail(item)">
<div class="selection-item__image">
<img :src="item.imgUrl || '/static/images/default-welfare.png'"
<img :src="item.imgUrl"
alt="福利图片"
@error="handleImageError">
</div>
@@ -678,18 +678,17 @@ layout("/layouts/platform_h5.html"){
maxlength="11"
required
></van-field>
<!--
收货地址字段预留位置
<!--收货地址-->
<van-field
v-if="projectInfo.needAddress"
v-model="formData.address"
v-if="projectInfo.provideMode == 3"
v-model="formData.receiveAddress"
label="收货地址"
placeholder="请输入收货地址"
type="textarea"
rows="2"
placeholder="请选择收货地址"
readonly
is-link
@click="showAddressSheet = true"
required
></van-field>
-->
></van-field>
</div>
<!-- 选择内容 -->
@@ -733,6 +732,35 @@ layout("/layouts/platform_h5.html"){
<div class="welfare-detail-content" v-html="selectedOption.description"></div>
</div>
</van-popup>
<!-- 收货地址选择弹窗 -->
<van-action-sheet v-model="showAddressSheet" title="选择收货地址" :round="true">
<div style="padding: 16px 0 0">
<div
v-for="address in addressOptions"
:key="address.id"
class="address-item"
@click="selectAddress(address)"
style="padding: 12px 16px; border-bottom: 1px solid #f0f0f0; cursor: pointer"
>
<div style="display: flex; justify-content: space-between; align-items: flex-start">
<div style="flex: 1">
<div style="font-size: 16px; font-weight: 500; color: #323233; margin-bottom: 4px">
{{ address.userName }} {{ address.tel }}
</div>
<div style="font-size: 14px; color: #646566; line-height: 1.4">
{{ address.province }}{{ address.city }}{{ address.county }}{{ address.addressDetail }}
</div>
</div>
<van-tag v-if="address.isDefault" type="primary" size="mini" style="margin-left: 8px">默认</van-tag>
</div>
</div>
<div v-if="addressOptions.length === 0" style="text-align: center; padding: 40px 16px; color: #969799">暂无收货地址</div>
</div>
<div style="padding: 16px; border-top: 1px solid #f0f0f0; background: #fafafa">
<van-button type="info" block round @click="goToAddressManage">收货地址管理</van-button>
</div>
</van-action-sheet>
</div>
</div>
@@ -757,8 +785,12 @@ layout("/layouts/platform_h5.html"){
formData: {
userSign: "", // 用户签名
mobile: "", // 手机号码
address: "" // 收货地址(预留)
}
address: "" // 收货地址
},
addressOptions: [],
showAddressSheet: false, // 收货地址选择弹窗
selectedAddressText: "" // 选中的收货地址显示文本
}
},
@@ -815,6 +847,11 @@ layout("/layouts/platform_h5.html"){
if (res.code === 0) {
this.projectInfo = res.data
// 获取收货地址
if (this.projectInfo.provideMode === 3) {
this.getAddress()
}
// 初始化选项的selectNum为0
if (this.projectInfo.options) {
this.projectInfo.options.forEach((option) => {
@@ -846,10 +883,16 @@ layout("/layouts/platform_h5.html"){
}
} else if (this.$store.user && this.$store.user.mobile) {
// 如果没有选择过,使用store中的默认手机号
debugger
this.formData.mobile = this.$store.user.mobile
}
// 地址回显
if (this.projectInfo.provideMode === 3) {
if (this.userSelection && this.userSelection[0].receiveAddress) {
this.formData.receiveAddress = this.userSelection[0].receiveAddress
}
}
// 设置已选择的选项
if (this.projectInfo.options && this.userSelection.length > 0) {
// 单选模式
@@ -898,6 +941,12 @@ layout("/layouts/platform_h5.html"){
return
}
// 如果需要邮寄
if (this.projectInfo.provideMode === 3 && !this.formData.receiveAddress) {
this.$toast.fail("请填写邮寄地址")
return
}
if (this.isSubmitting) return
this.isSubmitting = true
@@ -937,10 +986,10 @@ layout("/layouts/platform_h5.html"){
})
}
// 未来可扩展添加收货地址
if (this.formData.address) {
// 收货地址
if (this.projectInfo.provideMode === 3 && this.formData.receiveAddress) {
selections.forEach((selection) => {
selection.address = this.formData.address
selection.receiveAddress = this.formData.receiveAddress
})
}
@@ -1082,6 +1131,18 @@ layout("/layouts/platform_h5.html"){
}
},
// 选择收货地址
selectAddress(address) {
this.formData.receiveAddress =
address.userName + " " + address.tel + " " + address.province + address.city + address.county + address.addressDetail
this.showAddressSheet = false
},
// 跳转到地址管理页面
goToAddressManage() {
this.$pjaxReplace("/platform/h5/welfare/address/list")
},
// 切换选项选中状态
toggleOption(option) {
if (this.projectInfo.isCheckBox === "radio") {
@@ -1120,6 +1181,14 @@ layout("/layouts/platform_h5.html"){
}
}
}
},
// 获取收货地址
async getAddress() {
const resp = await this.$axios.post("/platform/welfare/addressManage/selectUserAddress")
if (resp.code === 0) {
this.addressOptions = resp.data
}
}
},