commit
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
package io.v.nutz.base.event.user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:UserChangeEventListener
|
||||||
|
* @Date 2025/8/13 14:18
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public interface UserChangeEventListener {
|
||||||
|
|
||||||
|
void receive(UserChangeMsg message);
|
||||||
|
}
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package io.v.nutz.base.event.user;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:UserChangeMsg
|
||||||
|
* @Date 2025/8/13 11:51
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class UserChangeMsg {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更资源,用户Id
|
||||||
|
*/
|
||||||
|
private List<String> userIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 操作类型
|
||||||
|
*/
|
||||||
|
private Integer operationType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更前的单位Id,当operationType值为1时,该字段有效
|
||||||
|
*/
|
||||||
|
private String sourceUnitId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更后的单位Id,当operationType值为1时,该字段有效
|
||||||
|
*/
|
||||||
|
private String targetUnitId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 单位变动
|
||||||
|
*/
|
||||||
|
public final static int UNIT_CHANGE_OPERATION = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 退休
|
||||||
|
*/
|
||||||
|
public final static int RETIRE_OPERATION = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 入会
|
||||||
|
*/
|
||||||
|
public final static int RESTORE_OPERATION = 3;
|
||||||
|
|
||||||
|
|
||||||
|
public UserChangeMsg(List<String> userIds, Integer operationType) {
|
||||||
|
super();
|
||||||
|
this.userIds = userIds;
|
||||||
|
this.operationType = operationType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public UserChangeMsg(List<String> userIds, Integer operationType, String sourceUnitId) {
|
||||||
|
super();
|
||||||
|
this.userIds = userIds;
|
||||||
|
this.operationType = operationType;
|
||||||
|
this.sourceUnitId = sourceUnitId;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.v.nutz.base.event.user;
|
||||||
|
|
||||||
|
import org.nutz.mvc.Mvcs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:UserChangePublisher
|
||||||
|
* @Date 2025/8/13 14:23
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public class UserChangePublisher {
|
||||||
|
|
||||||
|
// 发送消息给所有订阅者
|
||||||
|
public static void broadcast(UserChangeMsg msg) {
|
||||||
|
String[] names = Mvcs.getIoc().getNamesByType(UserChangeEventListener.class);
|
||||||
|
for (String listener : names) {
|
||||||
|
UserChangeEventListener listenerBean = Mvcs.getIoc().get(UserChangeEventListener.class, listener);
|
||||||
|
listenerBean.receive(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -107,6 +107,63 @@ public class MsgApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param channels 推送渠道 (INNER:站内消息; SMS:短信; Mail:邮件; WeChat:微信; DingTalk:钉钉;同时推送多个渠道用英文逗号分隔 )
|
||||||
|
* @param loginNameList 工号集合
|
||||||
|
* @param mtype 消息类型; 0: 图文 1: 文字 2: 外链
|
||||||
|
* @param title 标题
|
||||||
|
* @param content 内容
|
||||||
|
* @param imageUrl 图片URL
|
||||||
|
* @author zhf
|
||||||
|
* @description
|
||||||
|
*/
|
||||||
|
public void sendMsg(List<String> channels, List<String> loginNameList, Integer mtype, String title, String content, String imageUrl,String link) {
|
||||||
|
try {
|
||||||
|
if (!Globals.MyConfig.getBoolean("SendMsg")) {
|
||||||
|
log.info("发送失败,消息暂未开启!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Globals.isEnv(Env.dev)) {
|
||||||
|
log.info("开发模式不允许发送短信!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StrUtil.isBlank(title)||StrUtil.isBlank(content) ||Lang.isEmpty(channels) || Lang.isEmpty(loginNameList)) {
|
||||||
|
log.info("发送失败,缺少需要参数请检查!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Lang.isNotEmpty(loginNameList)) {
|
||||||
|
List<List<String>> splitList = ListUtil.split(loginNameList, 100);
|
||||||
|
|
||||||
|
|
||||||
|
for (List<String> sublist : splitList) {
|
||||||
|
// 获取token
|
||||||
|
String msgToken = getMsgToken();
|
||||||
|
// 封装发送消息的参数
|
||||||
|
NutMap map = createMessageMap(channels, sublist, mtype, title, content, imageUrl, link);
|
||||||
|
System.out.println(map);
|
||||||
|
// 发送请求
|
||||||
|
JSONObject jsonObject = sendRequest(msgToken, map);
|
||||||
|
// 判断发送结果
|
||||||
|
int status = jsonObject.getInteger("code");
|
||||||
|
if (status == 200) {
|
||||||
|
log.info("=================================================================================================发送成功: {}", jsonObject.toJSONString());
|
||||||
|
} else {
|
||||||
|
log.error("=================================================================================================发送失败: {}", jsonObject.toJSONString());
|
||||||
|
throw new RuntimeException("Message sending failed with status code: " + status + ", Message: " + jsonObject.getString("message"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 封装发送消息的参数
|
* 封装发送消息的参数
|
||||||
* @param channels
|
* @param channels
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
|
|||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.wizzer.framework.base.Result;
|
import cn.wizzer.framework.base.Result;
|
||||||
import io.v.nutz.base.annontation.ViReturn;
|
import io.v.nutz.base.annontation.ViReturn;
|
||||||
|
import io.v.nutz.base.event.user.UserChangeMsg;
|
||||||
|
import io.v.nutz.base.event.user.UserChangePublisher;
|
||||||
import io.v.nutz.base.page.Pagination;
|
import io.v.nutz.base.page.Pagination;
|
||||||
import io.v.nutz.base.utils.PageUtil;
|
import io.v.nutz.base.utils.PageUtil;
|
||||||
import io.v.nutz.base.utils.Roles;
|
import io.v.nutz.base.utils.Roles;
|
||||||
@@ -30,6 +32,7 @@ import org.nutz.ioc.loader.annotation.IocBean;
|
|||||||
import org.nutz.json.Json;
|
import org.nutz.json.Json;
|
||||||
import org.nutz.lang.Lang;
|
import org.nutz.lang.Lang;
|
||||||
import org.nutz.lang.Strings;
|
import org.nutz.lang.Strings;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
import org.nutz.log.Log;
|
import org.nutz.log.Log;
|
||||||
import org.nutz.log.Logs;
|
import org.nutz.log.Logs;
|
||||||
import org.nutz.mvc.annotation.At;
|
import org.nutz.mvc.annotation.At;
|
||||||
@@ -38,10 +41,7 @@ import org.nutz.mvc.annotation.Param;
|
|||||||
import org.nutz.trans.Trans;
|
import org.nutz.trans.Trans;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,9 +342,37 @@ public class SysUnionMangeCon {
|
|||||||
try {
|
try {
|
||||||
//再删除工会负责人的权限
|
//再删除工会负责人的权限
|
||||||
sysUnionService.clear("sys_user_role", Cnd.where("unionid", "=", unionid).and("roleid", "=", Roles.UNION_MANGER));
|
sysUnionService.clear("sys_user_role", Cnd.where("unionid", "=", unionid).and("roleid", "=", Roles.UNION_MANGER));
|
||||||
for (String id : Json.fromJsonAsList(String.class, userids)) {
|
sysUnionService.clear("sys_user_role", Cnd.where("unionid", "is", null).and("roleid", "=", Roles.UNION_MANGER));
|
||||||
|
List<String> strings = Json.fromJsonAsList(String.class, userids).stream().distinct().collect(Collectors.toList());
|
||||||
|
for (String id : strings) {
|
||||||
sysUnionService.insert("sys_user_role", Chain.make("roleid", Roles.UNION_MANGER).add("userid", id).add("unionid", unionid));
|
sysUnionService.insert("sys_user_role", Chain.make("roleid", Roles.UNION_MANGER).add("userid", id).add("unionid", unionid));
|
||||||
}
|
}
|
||||||
|
// 删除这个人在其他分工会的角色 096072
|
||||||
|
sysUserService.dao().clear(Sys_user_role.class, Cnd.where("userId", "in", strings)
|
||||||
|
.and("unionId", "!=", unionid));
|
||||||
|
|
||||||
|
// 找出分工会里面所有的工会干部,看这些人的工会与对应的分工会管理员是不是一致的,不一致的删除
|
||||||
|
List<Sys_user_role> userRoleList = sysUserService.dao().query(Sys_user_role.class, Cnd.where("roleId", "=", Roles.UNION_MANGER));
|
||||||
|
|
||||||
|
// 去查询user中的unionid
|
||||||
|
Set<String> userIds = userRoleList.stream().map(Sys_user_role::getUserId).collect(Collectors.toSet());
|
||||||
|
Sql sql = Sqls.create("SELECT u.id,u.unionid from `user` u WHERE u.id in (@userIds)").setParam("userIds", userIds);
|
||||||
|
sql.setCallback(Sqls.callback.maps());
|
||||||
|
sysUserService.dao().execute(sql);
|
||||||
|
List<NutMap> userList = (List<NutMap>) sql.getResult();
|
||||||
|
// 转map,找差异
|
||||||
|
Map<String, String> userMap = userList.stream().collect(Collectors.toMap(v -> v.getString("id"), v -> v.getString("unionid")));
|
||||||
|
|
||||||
|
List<Sys_user_role> diffUnionRoleList = userRoleList.stream().filter(v -> userMap.containsKey(v.getUserId())
|
||||||
|
&& !v.getUnionid().equals(userMap.get(v.getUserId()))).collect(Collectors.toList());
|
||||||
|
// 删除这些人的角色
|
||||||
|
if (org.nutz.lang.Lang.isNotEmpty(diffUnionRoleList)) {
|
||||||
|
sysUserService.dao().clear(Sys_user_role.class, Cnd.where("userId", "in", diffUnionRoleList.stream().map(Sys_user_role::getUserId).collect(Collectors.toList())));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 发送广播订阅
|
||||||
|
UserChangePublisher.broadcast(new UserChangeMsg(List.of("1"), UserChangeMsg.UNIT_CHANGE_OPERATION));
|
||||||
|
|
||||||
sysUserService.clearCache();
|
sysUserService.clearCache();
|
||||||
sysRoleService.clearCache();
|
sysRoleService.clearCache();
|
||||||
return Result.success();
|
return Result.success();
|
||||||
|
|||||||
+2
-3
@@ -6,7 +6,7 @@ import cn.afterturn.easypoi.excel.entity.ExportParams;
|
|||||||
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import io.v.nutz.web.commons.controller.userpartupdate.models.UserPartUp;
|
import io.v.nutz.web.commons.controller.userpartupdate.models.UserPartUp;
|
||||||
import io.v.nutz.web.commons.controller.userpartupdate.service.UserPatUpService;
|
import io.v.nutz.web.commons.controller.userpartupdate.service.UserPartUpService;
|
||||||
import io.v.nutz.zhgh.activity.models.ActivityUserCnd;
|
import io.v.nutz.zhgh.activity.models.ActivityUserCnd;
|
||||||
import io.v.nutz.base.annontation.ViReturn;
|
import io.v.nutz.base.annontation.ViReturn;
|
||||||
import io.v.nutz.base.service.BaseService;
|
import io.v.nutz.base.service.BaseService;
|
||||||
@@ -16,7 +16,6 @@ import io.v.nutz.base.utils.ViTool;
|
|||||||
import io.v.nutz.web.commons.utils.ShiroUtil;
|
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
import org.apache.poi.ss.usermodel.Workbook;
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.nutz.dao.Cnd;
|
import org.nutz.dao.Cnd;
|
||||||
import org.nutz.dao.Dao;
|
import org.nutz.dao.Dao;
|
||||||
@@ -53,7 +52,7 @@ public class UserPartUpdateController {
|
|||||||
private BaseService baseService;
|
private BaseService baseService;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private UserPatUpService userPartUpService;
|
private UserPartUpService userPartUpService;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+12
-1
@@ -5,14 +5,25 @@ import io.v.nutz.web.commons.controller.userpartupdate.models.UserPartUp;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface UserPatUpService extends ViService<UserPartUp> {
|
public interface UserPartUpService extends ViService<UserPartUp> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 大量数据插入
|
* 大量数据插入
|
||||||
*/
|
*/
|
||||||
void largeDataInsert(List<UserPartUp> list);
|
void largeDataInsert(List<UserPartUp> list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新在职状态和人员类型
|
||||||
|
*/
|
||||||
void renewUserState();
|
void renewUserState();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 修改不在源数据中的人员为普通角色,同时修改在职状态和人员类型
|
||||||
|
*/
|
||||||
void deleteNotInSourceUser(Boolean isAuto);
|
void deleteNotInSourceUser(Boolean isAuto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工会小组
|
||||||
|
*/
|
||||||
|
void renewUnionGroup();
|
||||||
}
|
}
|
||||||
+22
-3
@@ -4,13 +4,13 @@ import cn.hutool.core.collection.CollectionUtil;
|
|||||||
import io.v.nutz.base.service.impl.ViServiceImpl;
|
import io.v.nutz.base.service.impl.ViServiceImpl;
|
||||||
import io.v.nutz.base.utils.DateUtil;
|
import io.v.nutz.base.utils.DateUtil;
|
||||||
import io.v.nutz.base.utils.Roles;
|
import io.v.nutz.base.utils.Roles;
|
||||||
|
import io.v.nutz.sys.models.Sys_unit;
|
||||||
import io.v.nutz.sys.models.Sys_user;
|
import io.v.nutz.sys.models.Sys_user;
|
||||||
import io.v.nutz.sys.models.Sys_user_role;
|
import io.v.nutz.sys.models.Sys_user_role;
|
||||||
import io.v.nutz.web.commons.controller.userpartupdate.models.UserPartUp;
|
import io.v.nutz.web.commons.controller.userpartupdate.models.UserPartUp;
|
||||||
import io.v.nutz.web.commons.controller.userpartupdate.service.UserPatUpService;
|
import io.v.nutz.web.commons.controller.userpartupdate.service.UserPartUpService;
|
||||||
import io.v.nutz.sys.models.Sys_dict;
|
import io.v.nutz.sys.models.Sys_dict;
|
||||||
import io.v.nutz.sys.services.SysDictService;
|
import io.v.nutz.sys.services.SysDictService;
|
||||||
import io.v.nutz.zhgh.data.model.UserSource;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
import org.nutz.dao.Chain;
|
import org.nutz.dao.Chain;
|
||||||
@@ -36,7 +36,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
@IocBean(args = {"refer:dao"})
|
@IocBean(args = {"refer:dao"})
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class UserPartUpServiceImpl extends ViServiceImpl<UserPartUp> implements UserPatUpService {
|
public class UserPartUpServiceImpl extends ViServiceImpl<UserPartUp> implements UserPartUpService {
|
||||||
public UserPartUpServiceImpl(Dao dao) {
|
public UserPartUpServiceImpl(Dao dao) {
|
||||||
super(dao);
|
super(dao);
|
||||||
}
|
}
|
||||||
@@ -204,4 +204,23 @@ public class UserPartUpServiceImpl extends ViServiceImpl<UserPartUp> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新工会小组
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
public void renewUnionGroup() {
|
||||||
|
// 直接全部清空所有人的工会小组
|
||||||
|
dao().update(Sys_user.class, Chain.make("threeUnitId", ""), Cnd.where("threeUnitId", "!=", ""));
|
||||||
|
|
||||||
|
// 在单位表里面查出有工会小组的单位
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
UPDATE sys_user
|
||||||
|
SET threeUnitId = CONCAT(unitid, 'SJDW')
|
||||||
|
WHERE
|
||||||
|
unitid IN (SELECT parentId FROM sys_unit WHERE unionGroupId IS NOT NULL AND unionGroupId <> '' GROUP BY parentId)
|
||||||
|
""");
|
||||||
|
dao().execute(sql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package io.v.nutz.zhgh.activity.listener;
|
||||||
|
|
||||||
|
import io.v.nutz.base.event.user.UserChangeEventListener;
|
||||||
|
import io.v.nutz.base.event.user.UserChangeMsg;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:ActivityCommonListener
|
||||||
|
* @Date 2025/8/13 14:41
|
||||||
|
* @注释 活动的广播监听
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
public class ActivityUserChangeListener implements UserChangeEventListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void receive(UserChangeMsg message) {
|
||||||
|
System.out.println("=======================================================接收到消息=======================================================");
|
||||||
|
System.out.println(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,7 +53,7 @@ public interface SourceData {
|
|||||||
put("XBM", new String[]{"sex"});// 性别码
|
put("XBM", new String[]{"sex"});// 性别码
|
||||||
put("MZMC", new String[]{"nation"});// 民族码
|
put("MZMC", new String[]{"nation"});// 民族码
|
||||||
put("SJ", new String[]{"mobile"}); // 手机号
|
put("SJ", new String[]{"mobile"}); // 手机号
|
||||||
// put("SFZJH", new String[]{"idcard"}); // 身份证件号
|
put("SFZJH", new String[]{"idcard"}); // 身份证件号
|
||||||
put("ZZMMM", new String[]{"political"}); // 政治面貌码
|
put("ZZMMM", new String[]{"political"}); // 政治面貌码
|
||||||
put("DQZTM", new String[]{"userState", "personalStatus"}); // 在职状态码
|
put("DQZTM", new String[]{"userState", "personalStatus"}); // 在职状态码
|
||||||
put("RYFLMC", new String[]{"personType"}); // 人员类型码
|
put("RYFLMC", new String[]{"personType"}); // 人员类型码
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import io.v.nutz.sys.models.Sys_user;
|
|||||||
import io.v.nutz.sys.services.SysRoleService;
|
import io.v.nutz.sys.services.SysRoleService;
|
||||||
import io.v.nutz.sys.services.SysUserService;
|
import io.v.nutz.sys.services.SysUserService;
|
||||||
import io.v.nutz.web.commons.controller.userpartupdate.models.UserPartUp;
|
import io.v.nutz.web.commons.controller.userpartupdate.models.UserPartUp;
|
||||||
import io.v.nutz.web.commons.controller.userpartupdate.service.UserPatUpService;
|
import io.v.nutz.web.commons.controller.userpartupdate.service.UserPartUpService;
|
||||||
import io.v.nutz.zhgh.staffmanage.member.constant.MemberChangeOrigin;
|
import io.v.nutz.zhgh.staffmanage.member.constant.MemberChangeOrigin;
|
||||||
import io.v.nutz.zhgh.staffmanage.member.constant.MemberChangeType;
|
import io.v.nutz.zhgh.staffmanage.member.constant.MemberChangeType;
|
||||||
import io.v.nutz.zhgh.staffmanage.member.service.MemberCommonService;
|
import io.v.nutz.zhgh.staffmanage.member.service.MemberCommonService;
|
||||||
@@ -51,8 +51,6 @@ import org.springframework.beans.BeanUtils;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.concurrent.locks.Lock;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -86,7 +84,7 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
|
|||||||
@Inject
|
@Inject
|
||||||
private HistoryUserService historyUserService;
|
private HistoryUserService historyUserService;
|
||||||
@Inject
|
@Inject
|
||||||
private UserPatUpService userPatUpService;
|
private UserPartUpService userPatUpService;
|
||||||
@Inject
|
@Inject
|
||||||
private SysRoleService sysRoleService;
|
private SysRoleService sysRoleService;
|
||||||
@Inject
|
@Inject
|
||||||
@@ -313,6 +311,10 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
|
|||||||
dao().clear(SourceChangeMiddleTable.class, Cnd.where("loginname", "in", loginNameList).and("isOperate", "=", false));
|
dao().clear(SourceChangeMiddleTable.class, Cnd.where("loginname", "in", loginNameList).and("isOperate", "=", false));
|
||||||
manyAddOrRenewUtil.asyncExecuteFastInsert(middleTables, 200);
|
manyAddOrRenewUtil.asyncExecuteFastInsert(middleTables, 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 修改三级单位
|
||||||
|
userPatUpService.renewUnionGroup();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
throw new RuntimeException(e.getMessage());
|
throw new RuntimeException(e.getMessage());
|
||||||
@@ -687,60 +689,57 @@ public class SourceUserServiceImpl extends ViServiceImpl<UserSource> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 类级别定义共享线程池(推荐使用ThreadPoolExecutor便于后续调优)
|
||||||
|
private static final ExecutorService ASYNC_UPDATE_EXECUTOR = new ThreadPoolExecutor(
|
||||||
|
Runtime.getRuntime().availableProcessors() * 2,
|
||||||
|
Runtime.getRuntime().availableProcessors() * 4,
|
||||||
|
60L, TimeUnit.SECONDS,
|
||||||
|
new LinkedBlockingQueue<>(1000),
|
||||||
|
new ThreadPoolExecutor.CallerRunsPolicy()
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据大批量更新
|
* 数据大批量更新
|
||||||
|
*
|
||||||
* @param needDoUpdateList 需要更新的数据
|
* @param needDoUpdateList 需要更新的数据
|
||||||
* @param isPart 是否部分更新
|
* @param isPart 是否部分更新
|
||||||
* @param filterColumnDao 部分更新传递(部分更新存在过滤字段)
|
* @param filterColumnDao 部分更新传递(部分更新存在过滤字段)
|
||||||
*/
|
*/
|
||||||
private void massUpdatesAsync(List<Sys_user> needDoUpdateList, Boolean isPart, AtomicReference<Dao> filterColumnDao) {
|
public void massUpdatesAsync(List<Sys_user> needDoUpdateList, Boolean isPart, AtomicReference<Dao> filterColumnDao) {
|
||||||
// 创建一个CPU核心数的2倍的线程池
|
|
||||||
int numberOfThreads = Runtime.getRuntime().availableProcessors() * 2;
|
|
||||||
ExecutorService executorService = Executors.newFixedThreadPool(numberOfThreads);
|
|
||||||
ExecutorCompletionService<Void> ecs = new ExecutorCompletionService<>(executorService);
|
|
||||||
|
|
||||||
int batchSize = 200;
|
// 参数校验
|
||||||
// 共享锁
|
if (needDoUpdateList == null || needDoUpdateList.isEmpty()) {
|
||||||
Lock lock = new ReentrantLock();
|
CompletableFuture.completedFuture(null);
|
||||||
try {
|
return;
|
||||||
for (int i = 0; i < needDoUpdateList.size(); i += batchSize) {
|
|
||||||
final int end = Math.min(i + batchSize, needDoUpdateList.size());
|
|
||||||
List<Sys_user> batch = needDoUpdateList.subList(i, end);
|
|
||||||
|
|
||||||
ecs.submit(() -> {
|
|
||||||
Dao daoToUse = isPart ? filterColumnDao.get() : dao();
|
|
||||||
lock.lock();
|
|
||||||
try {
|
|
||||||
daoToUse.updateIgnoreNull(batch);
|
|
||||||
} finally {
|
|
||||||
lock.unlock();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < needDoUpdateList.size(); i += batchSize) {
|
|
||||||
try {
|
|
||||||
Future<Void> future = ecs.take();
|
|
||||||
future.get();
|
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
throw new RuntimeException("Error during batch update", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error in massUpdatesAsync", e);
|
|
||||||
throw new RuntimeException("Error in massUpdatesAsync", e);
|
|
||||||
} finally {
|
|
||||||
executorService.shutdown();
|
|
||||||
try {
|
|
||||||
if (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
|
|
||||||
executorService.shutdownNow();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
Thread.currentThread().interrupt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int batchSize = 200;
|
||||||
|
final int totalBatches = (needDoUpdateList.size() + batchSize - 1) / batchSize;
|
||||||
|
|
||||||
|
// 存储所有batch的future
|
||||||
|
List<CompletableFuture<Void>> batchFutures = new ArrayList<>(totalBatches);
|
||||||
|
|
||||||
|
for (int i = 0; i < needDoUpdateList.size(); i += batchSize) {
|
||||||
|
final int end = Math.min(i + batchSize, needDoUpdateList.size());
|
||||||
|
List<Sys_user> batch = needDoUpdateList.subList(i, end);
|
||||||
|
|
||||||
|
CompletableFuture<Void> batchFuture = CompletableFuture.runAsync(() -> {
|
||||||
|
Dao daoToUse = isPart ? filterColumnDao.get() : dao();
|
||||||
|
try {
|
||||||
|
// 假设updateIgnoreNull内部已处理线程安全
|
||||||
|
daoToUse.updateIgnoreNull(batch);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Batch update failed", e);
|
||||||
|
throw new CompletionException(e);
|
||||||
|
}
|
||||||
|
}, ASYNC_UPDATE_EXECUTOR);
|
||||||
|
|
||||||
|
batchFutures.add(batchFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并所有future
|
||||||
|
CompletableFuture.allOf(batchFutures.toArray(new CompletableFuture[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -110,10 +110,10 @@ public class MemberInquireIntegrateController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (StrUtil.isNotBlank(isUnit)) {
|
if (StrUtil.isNotBlank(isUnit)) {
|
||||||
cnd.and("u.unitid", isUnit.equals("true") ? "is not" : "is", null);
|
cnd.and("u.unitid", "true".equals(isUnit) ? "is not" : "is", null);
|
||||||
}
|
}
|
||||||
if (StrUtil.isNotBlank(isUnion)) {
|
if (StrUtil.isNotBlank(isUnion)) {
|
||||||
cnd.and("u.unionid", isUnion.equals("true") ? "is not" : "is", null);
|
cnd.and("u.unionid", "true".equals(isUnion) ? "is not" : "is", null);
|
||||||
}
|
}
|
||||||
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
if (StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||||
cnd.and(new SqlExpressionGroup().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword()));
|
cnd.and(new SqlExpressionGroup().andLike(pageForm.getSearchName(), pageForm.getSearchKeyword()));
|
||||||
@@ -123,7 +123,7 @@ public class MemberInquireIntegrateController {
|
|||||||
cnd.and(new SqlExpressionGroup().andLike(memberSearchName, memberSearchKeyWord));
|
cnd.and(new SqlExpressionGroup().andLike(memberSearchName, memberSearchKeyWord));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Integer> status = new ArrayList<>();
|
// List<Integer> status = new ArrayList<>();
|
||||||
// status.add(MemberStatus.NORMAL.getCode());
|
// status.add(MemberStatus.NORMAL.getCode());
|
||||||
// status.add(MemberStatus.TURN_IN.getCode());
|
// status.add(MemberStatus.TURN_IN.getCode());
|
||||||
// status.add(MemberStatus.RESTORE.getCode());
|
// status.add(MemberStatus.RESTORE.getCode());
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ public class MemberApplyRecord {
|
|||||||
|
|
||||||
@Column
|
@Column
|
||||||
@Comment("变更类型")
|
@Comment("变更类型")
|
||||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
private String changeType;
|
private String changeType;
|
||||||
|
|
||||||
@Column
|
@Column
|
||||||
|
|||||||
+6
-1
@@ -305,7 +305,7 @@ public class SourceChangeManageServiceImpl extends BaseServiceImpl<SourceChangeM
|
|||||||
NutMap afterUnionMap = (NutMap) afterUnionSql.getResult();
|
NutMap afterUnionMap = (NutMap) afterUnionSql.getResult();
|
||||||
|
|
||||||
// 如果这两个单位归属的是不同的分工会,发送消息提醒两个分工会
|
// 如果这两个单位归属的是不同的分工会,发送消息提醒两个分工会
|
||||||
if (!beforeUnionMap.getString("id").equals(afterUnionMap.getString("id"))) {
|
if (StrUtil.isAllNotBlank(beforeUnionMap.getString("id"), afterUnionMap.getString("id")) && !beforeUnionMap.getString("id").equals(afterUnionMap.getString("id"))) {
|
||||||
// 找到变更前的分工会会员管理员,发送消息提醒
|
// 找到变更前的分工会会员管理员,发送消息提醒
|
||||||
Sql beforeUnionAdminSql = Sqls.create("""
|
Sql beforeUnionAdminSql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
@@ -357,6 +357,11 @@ public class SourceChangeManageServiceImpl extends BaseServiceImpl<SourceChangeM
|
|||||||
msgApi.sendMsg(List.of("DingTalk"), map.getString("loginname"), 1, "工会关系转入通知", afterContent, "", "");
|
msgApi.sendMsg(List.of("DingTalk"), map.getString("loginname"), 1, "工会关系转入通知", afterContent, "", "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发送消息给个人,告知异动到了新工会
|
||||||
|
String content = "亲爱的%s老师,欢迎您加入%s!".formatted(middleTable.getUsername(), afterUnionMap.getString("unionname"));
|
||||||
|
msgApi.sendMsg(List.of("DingTalk"), middleTable.getLoginname(), 1, "", content, "", "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -82,6 +82,8 @@ public class TheRapyRecuperationAuditServiceImpl extends ViServiceImpl<Audit> im
|
|||||||
Sql sql = Sqls.create("""
|
Sql sql = Sqls.create("""
|
||||||
SELECT
|
SELECT
|
||||||
lxs.travelAgencyName,
|
lxs.travelAgencyName,
|
||||||
|
travel.travelAgencyName AS baseTravelAgencyName,
|
||||||
|
base.baseName,
|
||||||
enroll.*,
|
enroll.*,
|
||||||
line.lineName,
|
line.lineName,
|
||||||
if(enroll.takePartInUnionId!=enroll.selfUnionId,true,false) isTransferIn,
|
if(enroll.takePartInUnionId!=enroll.selfUnionId,true,false) isTransferIn,
|
||||||
@@ -91,6 +93,8 @@ public class TheRapyRecuperationAuditServiceImpl extends ViServiceImpl<Audit> im
|
|||||||
LEFT JOIN the_rapy_recuperation_line_union_select lineu ON lineu.id = enroll.takePartInLineId
|
LEFT JOIN the_rapy_recuperation_line_union_select lineu ON lineu.id = enroll.takePartInLineId
|
||||||
LEFT JOIN the_rapy_recuperation_line line ON line.id = lineu.lineId
|
LEFT JOIN the_rapy_recuperation_line line ON line.id = lineu.lineId
|
||||||
LEFT JOIN the_rapy_recuperation_travel_agency lxs ON lxs.id = line.travelAgencyId
|
LEFT JOIN the_rapy_recuperation_travel_agency lxs ON lxs.id = line.travelAgencyId
|
||||||
|
LEFT JOIN the_rapy_recuperation_base_management base ON base.id = enroll.takePartInBaseManagementId
|
||||||
|
LEFT JOIN the_rapy_recuperation_travel_agency travel ON travel.id = base.travelAgencyId
|
||||||
where enroll.id=@id
|
where enroll.id=@id
|
||||||
""").setParam("id", id);
|
""").setParam("id", id);
|
||||||
|
|
||||||
|
|||||||
-93
@@ -1,93 +0,0 @@
|
|||||||
package io.v.nutz.zhgh.welfare.controller;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import io.v.nutz.base.annontation.ViReturn;
|
|
||||||
import io.v.nutz.base.query.PageForm;
|
|
||||||
import io.v.nutz.base.service.SimpleService;
|
|
||||||
import io.v.nutz.zhgh.welfare.model.WelfareProjectSubject;
|
|
||||||
import io.v.nutz.zhgh.welfare.model.WelfareProjectSubjectOption;
|
|
||||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|
||||||
import org.nutz.dao.Cnd;
|
|
||||||
import org.nutz.dao.Dao;
|
|
||||||
import org.nutz.dao.Sqls;
|
|
||||||
import org.nutz.dao.sql.Sql;
|
|
||||||
import org.nutz.ioc.loader.annotation.Inject;
|
|
||||||
import org.nutz.ioc.loader.annotation.IocBean;
|
|
||||||
import org.nutz.mvc.annotation.At;
|
|
||||||
import org.nutz.mvc.annotation.Ok;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @ClassName WelfareEvaluateStatisticsController
|
|
||||||
* @Description 评价统计
|
|
||||||
* @Author zhf
|
|
||||||
* @Date 2024/5/7 20:02
|
|
||||||
*/
|
|
||||||
@IocBean
|
|
||||||
@Ok("json:full")
|
|
||||||
@At("/platform/welfare/evaluate/statistics")
|
|
||||||
public class WelfareEvaluateStatisticsController {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private SimpleService simpleService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
private Dao dao;
|
|
||||||
|
|
||||||
@At("")
|
|
||||||
@Ok("beetl:/platform/welfare/evaluateStatistics.html")
|
|
||||||
@RequiresPermissions("welfare.evaluate.statistics")
|
|
||||||
public void index() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@At
|
|
||||||
@ViReturn
|
|
||||||
@RequiresPermissions("welfare.evaluate.statistics")
|
|
||||||
public Object pageData(PageForm pageForm, String projectId, String unionId, String unitId, String personType, String userState, Integer evaluateScore, String optionId) {
|
|
||||||
Sql sql = Sqls.create("""
|
|
||||||
SELECT
|
|
||||||
we.evaluateText,
|
|
||||||
we.evaluateScore,
|
|
||||||
we.userName,
|
|
||||||
we.loginName,
|
|
||||||
u.unionname,
|
|
||||||
u.unitname,
|
|
||||||
u.userState,
|
|
||||||
u.personType
|
|
||||||
FROM
|
|
||||||
`welfare_evaluate` we
|
|
||||||
LEFT JOIN `user` u ON u.id = we.userId
|
|
||||||
$condition
|
|
||||||
""");
|
|
||||||
Cnd cnd = Cnd.NEW();
|
|
||||||
if (StrUtil.isNotBlank(pageForm.getSearchName()) && StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
|
||||||
cnd.and(Cnd.likeEX(pageForm.getSearchName(), pageForm.getSearchKeyword()));
|
|
||||||
}
|
|
||||||
if (StrUtil.isNotBlank(pageForm.getPageOrderName()) && StrUtil.isNotBlank(pageForm.getPageOrderBy())) {
|
|
||||||
cnd.orderBy(pageForm.getPageOrderName(), pageForm.getPageOrderBy().equals("ascending") ? "asc" : "desc");
|
|
||||||
} else {
|
|
||||||
cnd.desc("we.evaluateScore");
|
|
||||||
}
|
|
||||||
cnd.and("we.projectId", "=", projectId);
|
|
||||||
cnd.andEX("u.unionid", "=", unionId);
|
|
||||||
cnd.andEX("u.unitid", "=", unitId);
|
|
||||||
cnd.andEX("u.personType", "=", personType);
|
|
||||||
cnd.andEX("u.userState", "=", userState);
|
|
||||||
cnd.andEX("we.evaluateScore", "=", evaluateScore);
|
|
||||||
cnd.andEX("optionId", "=", optionId);
|
|
||||||
sql.setCondition(cnd);
|
|
||||||
return simpleService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
|
||||||
}
|
|
||||||
|
|
||||||
@At
|
|
||||||
@ViReturn
|
|
||||||
@RequiresPermissions("welfare.evaluate.statistics")
|
|
||||||
public Object welfareOptions(String projectId) {
|
|
||||||
List<WelfareProjectSubject> subjects = dao.query(WelfareProjectSubject.class, Cnd.where("projectId", "=", projectId));
|
|
||||||
List<String> subjectIds = subjects.stream().map(v -> v.getId()).collect(Collectors.toList());
|
|
||||||
return dao.query(WelfareProjectSubjectOption.class, Cnd.where("subjectId", "in", subjectIds).asc("optionSort"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -74,19 +74,21 @@ public class WelfareMineController {
|
|||||||
GROUP_CONCAT( DISTINCT wuso.optionName, IF(wus.selectSpecs is not null, (CONCAT('—规格:', wus.selectSpecs)), ''), '(', wus.selectNum, '份)' ) AS gist_list,
|
GROUP_CONCAT( DISTINCT wuso.optionName, IF(wus.selectSpecs is not null, (CONCAT('—规格:', wus.selectSpecs)), ''), '(', wus.selectNum, '份)' ) AS gist_list,
|
||||||
wus.receiveAddress,
|
wus.receiveAddress,
|
||||||
wcn.courierNumber,
|
wcn.courierNumber,
|
||||||
wl.userId
|
wl.userId,
|
||||||
|
wea.id AS evaId
|
||||||
FROM
|
FROM
|
||||||
welfare_project wp
|
welfare_project wp
|
||||||
LEFT JOIN welfare_project_user_selection wus ON wp.id = wus.welfareId AND wus.selectUserId = @selectUserId
|
LEFT JOIN welfare_project_user_selection wus ON wp.id = wus.welfareId AND wus.selectUserId = @selectUserId
|
||||||
LEFT JOIN welfare_courier_number wcn ON wp.id = wcn.welfareId AND wcn.selectUserId = @selectUserId
|
LEFT JOIN welfare_courier_number wcn ON wp.id = wcn.welfareId AND wcn.selectUserId = @selectUserId
|
||||||
LEFT JOIN welfare_list wl ON wp.id = wl.projectId AND wl.userId = @selectUserId
|
LEFT JOIN welfare_list wl ON wp.id = wl.projectId AND wl.userId = @selectUserId
|
||||||
LEFT JOIN welfare_project_subject_option wuso ON wus.selectOptionId = wuso.id
|
LEFT JOIN welfare_project_subject_option wuso ON wus.selectOptionId = wuso.id
|
||||||
|
LEFT JOIN welfare_evaluate_activity wea ON wea.welfareId = wp.id
|
||||||
$condition
|
$condition
|
||||||
""");
|
""");
|
||||||
sql.setParam("selectUserId", ShiroUtil.getUserId());
|
sql.setParam("selectUserId", ShiroUtil.getUserId());
|
||||||
Cnd cnd = Cnd.NEW();
|
Cnd cnd = Cnd.NEW();
|
||||||
cnd.and("wp.isDisabled", "=", 0);
|
cnd.and("wp.isDisabled", "=", 0);
|
||||||
// cnd.andEX("YEAR(wp.choiceTimeStart)", "=", year);
|
cnd.andEX("YEAR(wp.choiceTimeStart)", "=", year);
|
||||||
cnd.and("wp.id","in",Sqls.create("(select projectId from view_welfare_list where id = @userId)").setParam("userId",ShiroUtil.getUserId()));
|
cnd.and("wp.id","in",Sqls.create("(select projectId from view_welfare_list where id = @userId)").setParam("userId",ShiroUtil.getUserId()));
|
||||||
cnd.groupBy("wp.id");
|
cnd.groupBy("wp.id");
|
||||||
cnd.desc("wp.choiceTimeStart");
|
cnd.desc("wp.choiceTimeStart");
|
||||||
|
|||||||
@@ -321,7 +321,7 @@ public class WelfareProjectMangeController {
|
|||||||
sql.setParam("projectId", projectId);
|
sql.setParam("projectId", projectId);
|
||||||
List<NutMap> userList = listService.listMap(sql);
|
List<NutMap> userList = listService.listMap(sql);
|
||||||
Set<String> loginNameList = userList.stream().map(user -> user.getString("loginname")).collect(Collectors.toSet());
|
Set<String> loginNameList = userList.stream().map(user -> user.getString("loginname")).collect(Collectors.toSet());
|
||||||
String loginNames = loginNameList.stream().collect(Collectors.joining(","));
|
String loginNames = String.join(",", loginNameList);
|
||||||
|
|
||||||
// WelfareProject project = dao.fetch(WelfareProject.class, projectId);
|
// WelfareProject project = dao.fetch(WelfareProject.class, projectId);
|
||||||
String link = Globals.AppDomain + "/mobile/welfare/list/receive?projectId=%s".formatted(projectId);
|
String link = Globals.AppDomain + "/mobile/welfare/list/receive?projectId=%s".formatted(projectId);
|
||||||
|
|||||||
+256
@@ -0,0 +1,256 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.controller.evaluate;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.wizzer.framework.base.Result;
|
||||||
|
import io.v.nutz.base.annontation.ViReturn;
|
||||||
|
import io.v.nutz.base.page.Pagination;
|
||||||
|
import io.v.nutz.base.query.PageForm;
|
||||||
|
import io.v.nutz.base.utils.MsgApi;
|
||||||
|
import io.v.nutz.web.commons.base.Globals;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.WelfareProject;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateActivity;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateOption;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateSubject;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateUserAnswerRecord;
|
||||||
|
import io.v.nutz.zhgh.welfare.service.WelfareEvaluateActivityService;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.ioc.aop.Aop;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:WelfareEvaluateActivityController
|
||||||
|
* @Date 2025/8/11 14:38
|
||||||
|
* @注释 福利评价活动
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@Ok("json:full")
|
||||||
|
@At("/platform/welfare/evaluate/activity")
|
||||||
|
public class WelfareEvaluateActivityController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
@Inject
|
||||||
|
private MsgApi msgApi;
|
||||||
|
@Inject
|
||||||
|
private WelfareEvaluateActivityService welfareEvaluateActivityService;
|
||||||
|
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
@Ok("beetl:/platform/welfare/evaluate/activity/index.html")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
public Result pageData(@Valid PageForm pageForm,
|
||||||
|
@Param(value = "year", required = false) Integer year,
|
||||||
|
@Param(value = "title", required = false) String title,
|
||||||
|
@Param(value = "welfareId", required = false) String welfareId) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
eva.*,
|
||||||
|
wp.`name` AS welfareName
|
||||||
|
FROM
|
||||||
|
welfare_evaluate_activity eva
|
||||||
|
LEFT JOIN welfare_project wp ON wp.id = eva.welfareId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
cnd.andEX("YEAR(eva.startTime)", "=", year);
|
||||||
|
cnd.and(Cnd.likeEX("eva.title",title));
|
||||||
|
cnd.andEX("eva.welfareId", "=", welfareId);
|
||||||
|
cnd.desc("eva.startTime");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
Pagination pagination = welfareEvaluateActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||||
|
return Result.success(pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
public Result save(WelfareEvaluateActivity activity){
|
||||||
|
dao.insertOrUpdate(activity);
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
public Result delete(String id) {
|
||||||
|
dao.clear(WelfareEvaluateActivity.class, Cnd.where("id", "=", id));
|
||||||
|
List<WelfareEvaluateSubject> subjects = dao.query(WelfareEvaluateSubject.class, Cnd.where("activityId", "=", id));
|
||||||
|
List<String> subjectIds = subjects.stream().map(WelfareEvaluateSubject::getId).toList();
|
||||||
|
dao.clear(WelfareEvaluateSubject.class, Cnd.where("activityId", "=", id));
|
||||||
|
if (Lang.isNotEmpty(subjectIds)) {
|
||||||
|
dao.clear(WelfareEvaluateOption.class, Cnd.where("subjectId", "in", subjectIds));
|
||||||
|
}
|
||||||
|
dao.clear(WelfareEvaluateUserAnswerRecord.class, Cnd.where("activityId", "=", id));
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取评价活动
|
||||||
|
* @param id
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
public Result findOne(@Valid String id) {
|
||||||
|
WelfareEvaluateActivity activity = dao.fetch(WelfareEvaluateActivity.class, id);
|
||||||
|
return Result.success(activity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
public Result listSubjects(@Valid String activityId){
|
||||||
|
List<WelfareEvaluateSubject> subjects = dao.query(WelfareEvaluateSubject.class, Cnd.where("activityId", "=", activityId).asc("sortNum"));
|
||||||
|
dao.fetchLinks(subjects, "options",Cnd.NEW().asc("sortNum"));
|
||||||
|
return Result.success(subjects);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@Aop(TransAop.READ_COMMITTED)
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
public Result saveSubjects(@Param("activityId") @Valid String activityId, @Param("subjects") WelfareEvaluateSubject[] evaSubjects){
|
||||||
|
List<WelfareEvaluateSubject> subjects = dao.query(WelfareEvaluateSubject.class, Cnd.where("activityId", "=", activityId));
|
||||||
|
List<String> subjectIds = subjects.stream().map(WelfareEvaluateSubject::getId).toList();
|
||||||
|
|
||||||
|
//新题目
|
||||||
|
List<String> newSubjectIds = Arrays.stream(evaSubjects).map(WelfareEvaluateSubject::getId).toList();
|
||||||
|
|
||||||
|
//过滤出需要删除的题目
|
||||||
|
List<String> deleteSubjectIds = subjectIds.stream().filter(id -> !newSubjectIds.contains(id)).toList();
|
||||||
|
dao.clear(WelfareEvaluateSubject.class, Cnd.where("id", "in", deleteSubjectIds));
|
||||||
|
|
||||||
|
for (int i = 0; i < evaSubjects.length; i++) {
|
||||||
|
WelfareEvaluateSubject evaSubject = evaSubjects[i];
|
||||||
|
evaSubject.setSortNum(i + 1);
|
||||||
|
evaSubject.setActivityId(activityId);
|
||||||
|
//更新或添加题目
|
||||||
|
dao.insertOrUpdate(evaSubject);
|
||||||
|
|
||||||
|
//更新或添加选项
|
||||||
|
List<WelfareEvaluateOption> newOptions = evaSubject.getOptions();
|
||||||
|
List<String> optionIds = newOptions.stream().map(WelfareEvaluateOption::getId).toList();
|
||||||
|
|
||||||
|
List<WelfareEvaluateOption> oldOptions = dao.query(WelfareEvaluateOption.class, Cnd.where("subjectId", "=", evaSubject.getId()));
|
||||||
|
List<String> oldOptionIds = oldOptions.stream().map(WelfareEvaluateOption::getId).toList();
|
||||||
|
|
||||||
|
|
||||||
|
List<String> deleteOptionIds = oldOptionIds.stream().filter(id -> !optionIds.contains(id)).toList();
|
||||||
|
dao.clear(WelfareEvaluateOption.class, Cnd.where("id", "in", deleteOptionIds));
|
||||||
|
|
||||||
|
if ("radio".equals(evaSubject.getType()) || "checkbox".equals(evaSubject.getType())) {
|
||||||
|
for (int i1 = 0; i1 < newOptions.size(); i1++) {
|
||||||
|
newOptions.get(i1).setSortNum(i1 + 1);
|
||||||
|
newOptions.get(i1).setSubjectId(evaSubject.getId());
|
||||||
|
}
|
||||||
|
dao.insertOrUpdate(newOptions);
|
||||||
|
List<String> correctOptionIds = newOptions.stream().filter(WelfareEvaluateOption::getIsCorrect).map(WelfareEvaluateOption::getId).toList();
|
||||||
|
evaSubject.setCorrectAnswer(correctOptionIds);
|
||||||
|
} else {
|
||||||
|
dao.clear(WelfareEvaluateOption.class, Cnd.where("subjectId", "=", evaSubject.getId()));
|
||||||
|
}
|
||||||
|
dao.update(evaSubject);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Result.success();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询福利项目
|
||||||
|
* @param id 如果有Id表明是编辑
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.evaluate.activity")
|
||||||
|
public Result queryProject(String id) {
|
||||||
|
List<WelfareEvaluateActivity> activities = dao.query(WelfareEvaluateActivity.class, Cnd.NEW());
|
||||||
|
List<String> stringList = activities.stream().map(WelfareEvaluateActivity::getWelfareId).toList();
|
||||||
|
|
||||||
|
// 查询福利项目
|
||||||
|
Sql sql = Sqls.create("SELECT id,`name` FROM welfare_project $condition");
|
||||||
|
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
if (Lang.isNotEmpty(stringList)) {
|
||||||
|
if (StrUtil.isNotBlank(id)) {
|
||||||
|
WelfareEvaluateActivity activity = activities.stream().filter(item -> item.getId().equals(id)).findFirst().orElse(null);
|
||||||
|
if (activity != null) {
|
||||||
|
List<String> result = stringList.stream().filter(item -> !item.equals(activity.getWelfareId())).toList();
|
||||||
|
cnd.andEX("id", "not in", result);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
cnd.andEX("id", "not in", stringList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cnd.desc("opAt");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
sql.setCallback(Sqls.callback.maps());
|
||||||
|
dao.execute(sql);
|
||||||
|
List<NutMap> reslutList = (List<NutMap>) sql.getResult();
|
||||||
|
return Result.success(reslutList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.list.mange")
|
||||||
|
public Result sendMsgToNotWelfareUsers(String activityId, String title, String sendMsgValue) {
|
||||||
|
try {
|
||||||
|
WelfareEvaluateActivity activity = dao.fetch(WelfareEvaluateActivity.class, activityId);
|
||||||
|
|
||||||
|
String welfareId = activity.getWelfareId();
|
||||||
|
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
u.loginname
|
||||||
|
FROM
|
||||||
|
welfare_project_user_selection ws
|
||||||
|
LEFT JOIN welfare_list wl ON wl.projectId = @welfareId
|
||||||
|
AND wl.userId = ws.selectUserId
|
||||||
|
LEFT JOIN sys_user u ON u.id = wl.userId
|
||||||
|
WHERE
|
||||||
|
ws.welfareId = @welfareId
|
||||||
|
AND ws.selectUserId NOT IN (SELECT userId FROM welfare_evaluate_user_answer_record WHERE welfareId = @welfareId)
|
||||||
|
""").setParam("welfareId", welfareId);
|
||||||
|
sql.setCallback(Sqls.callback.strList());
|
||||||
|
dao.execute(sql);
|
||||||
|
List<String> loginNames = sql.getList(String.class);
|
||||||
|
|
||||||
|
System.out.println(loginNames);
|
||||||
|
|
||||||
|
String link = Globals.AppDomain + "/platform/h5/welfare/evaluate?activityId=%s".formatted(activityId);
|
||||||
|
// msgApi.sendMsg(List.of("DingTalk"), loginNames, 2, title, sendMsgValue, "", link);
|
||||||
|
return Result.success();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return Result.error();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+273
@@ -0,0 +1,273 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.controller.evaluate;
|
||||||
|
|
||||||
|
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.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONArray;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.wizzer.framework.base.Result;
|
||||||
|
import io.v.nutz.base.annontation.ViReturn;
|
||||||
|
import io.v.nutz.base.page.Pagination;
|
||||||
|
import io.v.nutz.base.query.PageForm;
|
||||||
|
import io.v.nutz.base.service.SimpleService;
|
||||||
|
import io.v.nutz.base.utils.CommonDownloadUtil;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvOption;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvSubject;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.WelfareProjectSubject;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.WelfareProjectSubjectOption;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateActivity;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateOption;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateSubject;
|
||||||
|
import io.v.nutz.zhgh.welfare.service.WelfareEvaluateActivityService;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ClassName WelfareEvaluateStatisticsController
|
||||||
|
* @Description 评价统计
|
||||||
|
* @Author zhf
|
||||||
|
* @Date 2024/5/7 20:02
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@Ok("json:full")
|
||||||
|
@At("/platform/welfare/evaluate/statistics")
|
||||||
|
public class WelfareEvaluateStatisticsController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
@Inject
|
||||||
|
private SimpleService simpleService;
|
||||||
|
@Inject
|
||||||
|
private WelfareEvaluateActivityService welfareEvaluateActivityService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@Ok("beetl:/platform/welfare/evaluate/statistics/index.html")
|
||||||
|
@RequiresPermissions("welfare.evaluate.statistics")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("welfare.evaluate.statistics")
|
||||||
|
public Object pageData(PageForm pageForm, String projectId, String unionId, String unitId, String personType, String userState, String optionId) {
|
||||||
|
WelfareEvaluateActivity evaluate = dao.fetch(WelfareEvaluateActivity.class, Cnd.where("welfareId", "=", projectId));
|
||||||
|
if (Lang.isEmpty(evaluate)) {
|
||||||
|
return Result.error("未找到相应福利");
|
||||||
|
}
|
||||||
|
String activityId = evaluate.getId();
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
record.*,
|
||||||
|
u.mobile,
|
||||||
|
u.userState,
|
||||||
|
u.personType,
|
||||||
|
GROUP_CONCAT( DISTINCT wuso.optionName, IF(wus.selectSpecs is not null, (CONCAT('—规格:', wus.selectSpecs)), ''), '(', wus.selectNum, '份)' ) AS gistList
|
||||||
|
FROM
|
||||||
|
welfare_evaluate_user_answer_record record
|
||||||
|
LEFT JOIN welfare_project wp ON wp.id = record.welfareId
|
||||||
|
LEFT JOIN welfare_project_user_selection wus ON wp.id = wus.welfareId AND wus.selectUserId = record.userId
|
||||||
|
LEFT JOIN welfare_project_subject_option wuso ON wus.selectOptionId = wuso.id
|
||||||
|
LEFT JOIN sys_user u ON u.id = record.userId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
if (StrUtil.isAllNotBlank(pageForm.getSearchName(), pageForm.getSearchKeyword())) {
|
||||||
|
cnd.and(Cnd.likeEX("record." + pageForm.getSearchName(), pageForm.getSearchKeyword()));
|
||||||
|
}
|
||||||
|
|
||||||
|
cnd.and("record.activityId", "=", activityId);
|
||||||
|
cnd.and("record.isFinish", "=", true);
|
||||||
|
cnd.and("record.welfareId", "=", projectId);
|
||||||
|
cnd.andEX("record.unionid", "=", unionId);
|
||||||
|
cnd.andEX("record.unitid", "=", unitId);
|
||||||
|
cnd.andEX("record.personType", "=", personType);
|
||||||
|
cnd.andEX("record.userState", "=", userState);
|
||||||
|
cnd.andEX("wus.selectOptionId", "=", optionId);
|
||||||
|
cnd.groupBy("record.userId");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
// Cnd.where("activityId", "=", activityId)
|
||||||
|
// .and("isFinish", "=", true)
|
||||||
|
Pagination pagination = welfareEvaluateActivityService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||||
|
List<NutMap> answerRecords = pagination.getList();
|
||||||
|
|
||||||
|
// 查询活动题目列表
|
||||||
|
List<WelfareEvaluateSubject> subjects = dao.query(WelfareEvaluateSubject.class, Cnd.where("activityId", "=", activityId).asc("sortNum"));
|
||||||
|
// 将题目列表转换为Map
|
||||||
|
Map<String, WelfareEvaluateSubject> subjectMap = subjects.stream().collect(Collectors.toMap(WelfareEvaluateSubject::getId, v -> v));
|
||||||
|
// 获取题目ID列表
|
||||||
|
List<String> subjectIds = subjects.stream().map(WelfareEvaluateSubject::getId).toList();
|
||||||
|
|
||||||
|
// 查询题目选项列表
|
||||||
|
List<WelfareEvaluateOption> options = dao.query(WelfareEvaluateOption.class, Cnd.where("subjectId", "in", subjectIds).asc("sortNum"));
|
||||||
|
|
||||||
|
// 构建Excel导出实体
|
||||||
|
List<ExcelExportEntity> excelExportEntities = welfareEvaluateActivityService.buildExcelExportEntities(subjects);
|
||||||
|
// 构建答题记录列表
|
||||||
|
List<NutMap> list = answerRecords.stream().map(record -> {
|
||||||
|
JSONObject extJson = record.getAs("extJson", JSONObject.class);
|
||||||
|
if (extJson != null) {
|
||||||
|
NutMap map = NutMap.NEW()
|
||||||
|
.addv("id", record.getString("id"))
|
||||||
|
.addv("loginName", record.getString("loginName"))
|
||||||
|
.addv("userName", record.getString("userName"))
|
||||||
|
.addv("unitName", record.getString("unitName"))
|
||||||
|
.addv("unionName", record.getString("unionName"))
|
||||||
|
.addv("mobile", record.getString("mobile"))
|
||||||
|
.addv("gistList", record.getString("gistList"));
|
||||||
|
|
||||||
|
|
||||||
|
extJson.forEach((k, v) -> {
|
||||||
|
JSONObject jsonVal = (JSONObject) v;
|
||||||
|
|
||||||
|
String type = subjectMap.get(k).getType();
|
||||||
|
if ("text".equals(type)) {
|
||||||
|
map.addv(k, jsonVal.getStr("text"));
|
||||||
|
} else if ("radio".equals(type) || "checkbox".equals(type)) {
|
||||||
|
List<NutMap> optionContents = jsonVal.getBeanList("optionContents", NutMap.class);
|
||||||
|
|
||||||
|
String selectOptionTexts = optionContents.stream().map(item -> {
|
||||||
|
WelfareEvaluateOption eva = options.stream().filter(option -> option.getId().equals(item.getString("optionId"))).findFirst().orElse(new WelfareEvaluateOption());
|
||||||
|
return eva.getText() + (StrUtil.isNotBlank(item.getString("content")) ? ("—" + eva.getContentPrefix() + ":") + item.getString("content") : "");
|
||||||
|
}).collect(Collectors.joining(";"));
|
||||||
|
map.addv(k, selectOptionTexts);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
} else {
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
}).toList();
|
||||||
|
pagination.setList(list);
|
||||||
|
|
||||||
|
// 构建表格列信息
|
||||||
|
List<NutMap> tableColumns = excelExportEntities.stream()
|
||||||
|
.map(v -> NutMap.NEW().addv("prop", v.getKey()).addv("label", v.getName()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
return NutMap.NEW()
|
||||||
|
.addv("tableColumns", tableColumns)
|
||||||
|
.addv("tableData", pagination);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@ViReturn
|
||||||
|
@RequiresPermissions("welfare.evaluate.statistics")
|
||||||
|
public Object welfareOptions(String projectId) {
|
||||||
|
List<WelfareProjectSubject> subjects = dao.query(WelfareProjectSubject.class, Cnd.where("projectId", "=", projectId));
|
||||||
|
List<String> subjectIds = subjects.stream().map(WelfareProjectSubject::getId).collect(Collectors.toList());
|
||||||
|
return dao.query(WelfareProjectSubjectOption.class, Cnd.where("subjectId", "in", subjectIds).asc("optionSort"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.evaluate.statistics")
|
||||||
|
public Result dataReport(String welfareId){
|
||||||
|
WelfareEvaluateActivity activity = dao.fetch(WelfareEvaluateActivity.class, Cnd.where("welfareId", "=", welfareId));
|
||||||
|
List<NutMap> list = welfareEvaluateActivityService.dataReport(activity.getId());
|
||||||
|
return Result.success().addData(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@RequiresPermissions("welfare.evaluate.statistics")
|
||||||
|
public void exportReportXlsx(String welfareId, HttpServletResponse response) {
|
||||||
|
WelfareEvaluateActivity activity = dao.fetch(WelfareEvaluateActivity.class, Cnd.where("welfareId", "=", welfareId));
|
||||||
|
welfareEvaluateActivityService.exportReportXlsx(activity.getId(), response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@Ok("void")
|
||||||
|
@RequiresPermissions("welfare.evaluate.statistics")
|
||||||
|
public void exportXlsx(PageForm pageForm, String projectId, String unionId, String unitId,
|
||||||
|
String personType, String userState, String optionId,
|
||||||
|
HttpServletResponse response) {
|
||||||
|
try {
|
||||||
|
WelfareEvaluateActivity evaluate = dao.fetch(WelfareEvaluateActivity.class, Cnd.where("welfareId", "=", projectId));
|
||||||
|
if (Lang.isEmpty(evaluate)) {
|
||||||
|
throw new RuntimeException("未找到相应福利");
|
||||||
|
}
|
||||||
|
String activityId = evaluate.getId();
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
record.*,
|
||||||
|
u.mobile,
|
||||||
|
u.userState,
|
||||||
|
u.personType,
|
||||||
|
GROUP_CONCAT( DISTINCT wuso.optionName, IF(wus.selectSpecs is not null, (CONCAT('—规格:', wus.selectSpecs)), ''), '(', wus.selectNum, '份)' ) AS gistList
|
||||||
|
FROM
|
||||||
|
welfare_evaluate_user_answer_record record
|
||||||
|
LEFT JOIN welfare_project wp ON wp.id = record.welfareId
|
||||||
|
LEFT JOIN welfare_project_user_selection wus ON wp.id = wus.welfareId AND wus.selectUserId = record.userId
|
||||||
|
LEFT JOIN welfare_project_subject_option wuso ON wus.selectOptionId = wuso.id
|
||||||
|
LEFT JOIN sys_user u ON u.id = record.userId
|
||||||
|
$condition
|
||||||
|
""");
|
||||||
|
|
||||||
|
Cnd cnd = Cnd.NEW();
|
||||||
|
if (StrUtil.isAllNotBlank(pageForm.getSearchName(), pageForm.getSearchKeyword())) {
|
||||||
|
cnd.and(Cnd.likeEX("record." + pageForm.getSearchName(), pageForm.getSearchKeyword()));
|
||||||
|
}
|
||||||
|
|
||||||
|
cnd.and("record.activityId", "=", activityId);
|
||||||
|
cnd.and("record.isFinish", "=", true);
|
||||||
|
cnd.and("record.welfareId", "=", projectId);
|
||||||
|
cnd.andEX("record.unionid", "=", unionId);
|
||||||
|
cnd.andEX("record.unitid", "=", unitId);
|
||||||
|
cnd.andEX("record.personType", "=", personType);
|
||||||
|
cnd.andEX("record.userState", "=", userState);
|
||||||
|
cnd.andEX("wus.selectOptionId", "=", optionId);
|
||||||
|
cnd.groupBy("record.userId");
|
||||||
|
sql.setCondition(cnd);
|
||||||
|
// Cnd.where("activityId", "=", activityId)
|
||||||
|
// .and("isFinish", "=", true)
|
||||||
|
List<NutMap> answerRecords = welfareEvaluateActivityService.listMap(sql);
|
||||||
|
// 查询活动题目列表
|
||||||
|
List<WelfareEvaluateSubject> subjects = dao.query(WelfareEvaluateSubject.class, Cnd.where("activityId", "=", activityId).asc("sortNum"));
|
||||||
|
// 将题目列表转换为Map
|
||||||
|
Map<String, WelfareEvaluateSubject> subjectMap = subjects.stream().collect(Collectors.toMap(WelfareEvaluateSubject::getId, v -> v));
|
||||||
|
// 获取题目ID列表
|
||||||
|
List<String> subjectIds = subjects.stream().map(WelfareEvaluateSubject::getId).toList();
|
||||||
|
|
||||||
|
// 查询题目选项列表
|
||||||
|
List<WelfareEvaluateOption> options = dao.query(WelfareEvaluateOption.class, Cnd.where("subjectId", "in", subjectIds).asc("sortNum"));
|
||||||
|
|
||||||
|
// 构建Excel导出实体
|
||||||
|
List<ExcelExportEntity> excelExportEntities = welfareEvaluateActivityService.buildExcelExportEntities(subjects);
|
||||||
|
|
||||||
|
List<NutMap> list = welfareEvaluateActivityService.buildAnswerRecords(answerRecords, subjectMap, options);
|
||||||
|
|
||||||
|
// 导出Excel并下载
|
||||||
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, excelExportEntities, list);
|
||||||
|
CommonDownloadUtil.download(evaluate.getTitle() + "记录" + ".xlsx", workbook, response);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.h5controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.wizzer.framework.base.Result;
|
||||||
|
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||||
|
import io.v.nutz.zhgh.activity.models.ActivityUserScope;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvActivity;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvSubject;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvUserAnswerRecord;
|
||||||
|
import io.v.nutz.zhgh.qsv.param.QsvAnswerParam;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.WelfareUserSelection;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateActivity;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateSubject;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateUserAnswerRecord;
|
||||||
|
import io.v.nutz.zhgh.welfare.param.WelfareEvaluateAnswerParam;
|
||||||
|
import io.v.nutz.zhgh.welfare.service.WelfareEvaluateActivityService;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresAuthentication;
|
||||||
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.ioc.loader.annotation.Inject;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
import org.nutz.mvc.annotation.At;
|
||||||
|
import org.nutz.mvc.annotation.Ok;
|
||||||
|
import org.nutz.mvc.annotation.Param;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:H5WelfareEvaluateController
|
||||||
|
* @Date 2025/8/12 8:55
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@IocBean
|
||||||
|
@Ok("json:full")
|
||||||
|
@At("/platform/h5/welfare/evaluate")
|
||||||
|
public class H5WelfareEvaluateController {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private Dao dao;
|
||||||
|
@Inject
|
||||||
|
private WelfareEvaluateActivityService welfareEvaluateActivityService;
|
||||||
|
|
||||||
|
@At("")
|
||||||
|
@RequiresPermissions("welfare.mine")
|
||||||
|
@Ok("beetl:/mobile/welfare/evaluate/index.html")
|
||||||
|
public void index() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.mine")
|
||||||
|
public Result subjects(String activityId) {
|
||||||
|
WelfareEvaluateActivity activity = dao.fetch(WelfareEvaluateActivity.class, activityId);
|
||||||
|
|
||||||
|
if (activity == null) {
|
||||||
|
return Result.error("调查不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = dao.count(WelfareUserSelection.class, Cnd.where("welfareId", "=", activity.getWelfareId()).and("selectUserId", "=", ShiroUtil.getUserId()));
|
||||||
|
if (count != 1) {
|
||||||
|
return Result.error("您无需参加此次投票,感谢您的关注!");
|
||||||
|
}
|
||||||
|
|
||||||
|
String answerRecordId = null;
|
||||||
|
|
||||||
|
WelfareEvaluateUserAnswerRecord answerRecord = dao.fetch(WelfareEvaluateUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
|
||||||
|
.and("userId", "=", ShiroUtil.getUserId()));
|
||||||
|
if (answerRecord == null) {
|
||||||
|
List<WelfareEvaluateSubject> subjects = dao.query(WelfareEvaluateSubject.class,
|
||||||
|
Cnd.where("activityId", "=", activityId).asc("sortNum"));
|
||||||
|
welfareEvaluateActivityService.insertRecord(activityId, subjects.stream().map(WelfareEvaluateSubject::getId).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
WelfareEvaluateUserAnswerRecord answerRecord2 = dao.fetch(WelfareEvaluateUserAnswerRecord.class,
|
||||||
|
Cnd.where("activityId", "=", activityId)
|
||||||
|
.and("userId", "=", ShiroUtil.getUserId()));
|
||||||
|
|
||||||
|
answerRecordId = answerRecord2.getId();
|
||||||
|
|
||||||
|
List<WelfareEvaluateSubject> subjects = dao.query(WelfareEvaluateSubject.class,
|
||||||
|
Cnd.where("id", "in", answerRecord2.getSubjectIds()).asc("sortNum"));
|
||||||
|
dao.fetchLinks(subjects, "options", Cnd.NEW().asc("sortNum"));
|
||||||
|
|
||||||
|
for (WelfareEvaluateSubject subject : subjects) {
|
||||||
|
if (subject.getUserSelectOptionIds() == null) {
|
||||||
|
subject.setUserSelectOptionIds(new ArrayList<>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NutMap result = NutMap.NEW().addv("subjects", subjects).addv("answerRecordId", answerRecordId).addv("activity", activity);
|
||||||
|
return Result.success(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.mine")
|
||||||
|
public Result answerRecord(@Valid String answerRecordId) {
|
||||||
|
WelfareEvaluateUserAnswerRecord record = dao.fetch(WelfareEvaluateUserAnswerRecord.class, answerRecordId);
|
||||||
|
return Result.success(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
@At
|
||||||
|
@RequiresPermissions("welfare.mine")
|
||||||
|
public Result submitAnswer(@Valid @Param("answer") WelfareEvaluateAnswerParam qsvAnswerParam) {
|
||||||
|
WelfareEvaluateActivity activity = dao.fetch(WelfareEvaluateActivity.class, qsvAnswerParam.getActivityId());
|
||||||
|
WelfareEvaluateUserAnswerRecord answerRecord = dao.fetch(WelfareEvaluateUserAnswerRecord.class, qsvAnswerParam.getAnswerRecordId());
|
||||||
|
JSONObject extJson = answerRecord.getExtJson();
|
||||||
|
|
||||||
|
for (WelfareEvaluateAnswerParam.Subject subject : qsvAnswerParam.getSubjects()) {
|
||||||
|
JSONObject entries = extJson.get(subject.getId(), JSONObject.class);
|
||||||
|
if (ObjectUtil.isNotEmpty(entries)) {
|
||||||
|
entries.set("optionIds", subject.getUserSelectOptionIds());
|
||||||
|
entries.set("optionContents", subject.getUserSelectOptionContent());
|
||||||
|
entries.set("text", subject.getUserFillContent());
|
||||||
|
}
|
||||||
|
extJson.set(subject.getId(), entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
answerRecord.setWelfareId(activity.getWelfareId());
|
||||||
|
answerRecord.setAttemptDate(new Date());
|
||||||
|
answerRecord.setSubmitTime(new Date());
|
||||||
|
answerRecord.setIsFinish(true);
|
||||||
|
dao.update(answerRecord);
|
||||||
|
|
||||||
|
return Result.success("提交成功");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.model.eavluate;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:WelfareEvaluateActivity
|
||||||
|
* @Date 2025/8/11 14:18
|
||||||
|
* @注释 福利评价
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Table
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WelfareEvaluateActivity extends BaseModel {
|
||||||
|
|
||||||
|
@Name
|
||||||
|
@Comment("ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("福利Id")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String welfareId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("所属模块(quiz, survey, vote)")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("标题")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("描述")
|
||||||
|
@ColDefine(type = ColType.TEXT)
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("尾行内容")
|
||||||
|
@ColDefine(type = ColType.TEXT)
|
||||||
|
private String lastContent;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("活动开始时间")
|
||||||
|
@ColDefine(type = ColType.DATETIME)
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("活动结束时间")
|
||||||
|
@ColDefine(type = ColType.DATETIME)
|
||||||
|
private Date endTime;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("模式:定时定题模式(scheduled)或常规模式(regular)")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String mode;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("是否可重复答题")
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
@Default("0")
|
||||||
|
private Boolean repeatable;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("最大答题次数(0表示不限制)")
|
||||||
|
@ColDefine(type = ColType.INT, width = 1)
|
||||||
|
private Integer maxAttempts;
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.model.eavluate;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:WelfareEvaluateOption
|
||||||
|
* @Date 2025/8/11 14:27
|
||||||
|
* @注释 福利评价选项表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Table
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WelfareEvaluateOption extends BaseModel {
|
||||||
|
|
||||||
|
@Name
|
||||||
|
@Comment("ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("题目表")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String subjectId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("选项内容")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Default("0")
|
||||||
|
@Comment("是否为正确答案(仅答题模块使用)")
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
private Boolean isCorrect;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Default("0")
|
||||||
|
@Comment("是否开启内容填写")
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
private Boolean isOpenContent;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("内容前缀")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 100)
|
||||||
|
private String contentPrefix;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("详情")
|
||||||
|
@ColDefine(customType = "longtext")
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("排序")
|
||||||
|
@ColDefine(type = ColType.INT)
|
||||||
|
private Integer sortNum;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.model.eavluate;
|
||||||
|
|
||||||
|
import io.v.nutz.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:WelfareEvaluateSubject
|
||||||
|
* @Date 2025/8/11 14:27
|
||||||
|
* @注释 福利评价题目表
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Table
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WelfareEvaluateSubject extends BaseModel {
|
||||||
|
|
||||||
|
@Name
|
||||||
|
@Comment("ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("活动ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String activityId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("题目标题")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 255)
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("题目类型(single, multi, judge, fill)")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("正确答案")
|
||||||
|
@ColDefine(type = ColType.MYSQL_JSON)
|
||||||
|
private List<String> correctAnswer;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("题目分数(仅答题模块使用)")
|
||||||
|
@ColDefine(type = ColType.INT, width = 1)
|
||||||
|
private Integer score;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("显示时间")
|
||||||
|
@ColDefine(type = ColType.DATE)
|
||||||
|
private Date displayDate;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("多选,最多选几个")
|
||||||
|
@ColDefine(type = ColType.INT, width = 1)
|
||||||
|
private Integer maxMulti;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("排序")
|
||||||
|
@ColDefine(type = ColType.INT, width = 1)
|
||||||
|
private Integer sortNum;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选项
|
||||||
|
*/
|
||||||
|
@Many(target = WelfareEvaluateOption.class, field = "subjectId")
|
||||||
|
private List<WelfareEvaluateOption> options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户选择的选项(选择题)
|
||||||
|
*/
|
||||||
|
private List<String> userSelectOptionIds;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户填写的内容(填空题)
|
||||||
|
*/
|
||||||
|
private String userFillContent;
|
||||||
|
|
||||||
|
}
|
||||||
+134
@@ -0,0 +1,134 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.model.eavluate;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.wizzer.framework.base.model.BaseModel;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import org.nutz.dao.entity.annotation.*;
|
||||||
|
import org.nutz.dao.interceptor.annotation.PrevInsert;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:WelfareEvaluateUserAnswerRecord
|
||||||
|
* @Date 2025/8/12 9:19
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Table
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
public class WelfareEvaluateUserAnswerRecord extends BaseModel {
|
||||||
|
|
||||||
|
@Name
|
||||||
|
@Comment("ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
@PrevInsert(uu32 = true)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("用户ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String userId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("工号")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 200)
|
||||||
|
private String loginName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("姓名")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 200)
|
||||||
|
private String userName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("分工会")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||||
|
private String unionName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("分工会ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String unionId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("单位")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 200)
|
||||||
|
private String unitName;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("单位ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String unitId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("活动ID")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String activityId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("福利Id")
|
||||||
|
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||||
|
private String welfareId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("扩展字段")
|
||||||
|
@ColDefine(type = ColType.MYSQL_JSON)
|
||||||
|
private JSONObject extJson;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("题目ID")
|
||||||
|
@ColDefine(type = ColType.MYSQL_JSON)
|
||||||
|
private List<String> subjectIds;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("答题得分(仅答题模块使用)")
|
||||||
|
@ColDefine(type = ColType.FLOAT)
|
||||||
|
private Float totalScore;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("随机次数(仅答题模块使用随机抽取模式)")
|
||||||
|
@ColDefine(type = ColType.INT, width = 1)
|
||||||
|
private Integer randomNumber;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("答题次数(仅答题模块使用)")
|
||||||
|
@ColDefine(type = ColType.INT, width = 1)
|
||||||
|
private Integer attemptNumber;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("答题日期(用于统计某一天的答题次数)")
|
||||||
|
@ColDefine(type = ColType.DATE)
|
||||||
|
private Date attemptDate;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("是否为最新得分(仅答题模块使用)")
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
@Default("0")
|
||||||
|
private Boolean isLatestScore;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("是否为最高得分(仅答题模块使用)")
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
@Default("0")
|
||||||
|
private Boolean isHighestScore;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("是否完成")
|
||||||
|
@ColDefine(type = ColType.BOOLEAN)
|
||||||
|
@Default("0")
|
||||||
|
private Boolean isFinish;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("提交时间")
|
||||||
|
@ColDefine(type = ColType.DATETIME)
|
||||||
|
private Date submitTime;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
@Comment("答题用时")
|
||||||
|
@ColDefine(type = ColType.INT)
|
||||||
|
private Integer answerTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.param;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WelfareEvaluateAnswerParam {
|
||||||
|
|
||||||
|
private String activityId;
|
||||||
|
|
||||||
|
private String answerRecordId;
|
||||||
|
|
||||||
|
private List<Subject> subjects;
|
||||||
|
|
||||||
|
private Integer answerTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Subject{
|
||||||
|
private String id;
|
||||||
|
private List<String> userSelectOptionIds;
|
||||||
|
private List<NutMap> userSelectOptionContent;
|
||||||
|
private String userFillContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.service;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
|
import io.v.nutz.base.service.BaseService;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvOption;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvSubject;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvUserAnswerRecord;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateActivity;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateOption;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateSubject;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateUserAnswerRecord;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:WelfareEvaluateActivityService
|
||||||
|
* @Date 2025/8/11 15:14
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
public interface WelfareEvaluateActivityService extends BaseService<WelfareEvaluateActivity> {
|
||||||
|
|
||||||
|
|
||||||
|
WelfareEvaluateUserAnswerRecord insertRecord(String activityId, List<String> subjectIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据报告
|
||||||
|
* @param activityId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<NutMap> dataReport(String activityId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建导出实体
|
||||||
|
* @param subjects
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<ExcelExportEntity> buildExcelExportEntities(List<WelfareEvaluateSubject> subjects);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建用户答案记录
|
||||||
|
* @param answerRecords
|
||||||
|
* @param subjectMap
|
||||||
|
* @param options
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
List<NutMap> buildAnswerRecords(List<NutMap> answerRecords,
|
||||||
|
Map<String, WelfareEvaluateSubject> subjectMap,
|
||||||
|
List<WelfareEvaluateOption> options);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出数据报告
|
||||||
|
* @param activityId
|
||||||
|
* @param response
|
||||||
|
*/
|
||||||
|
void exportReportXlsx(String activityId, HttpServletResponse response);
|
||||||
|
}
|
||||||
+275
@@ -0,0 +1,275 @@
|
|||||||
|
package io.v.nutz.zhgh.welfare.service.impl;
|
||||||
|
|
||||||
|
import cn.afterturn.easypoi.excel.entity.ExportParams;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
|
||||||
|
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||||
|
import cn.afterturn.easypoi.excel.export.ExcelExportService;
|
||||||
|
import cn.hutool.core.lang.Dict;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONArray;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import io.v.nutz.base.service.impl.BaseServiceImpl;
|
||||||
|
import io.v.nutz.base.utils.CommonDownloadUtil;
|
||||||
|
import io.v.nutz.sys.models.User;
|
||||||
|
import io.v.nutz.web.commons.utils.ShiroUtil;
|
||||||
|
import io.v.nutz.zhgh.qsv.models.QsvOption;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateActivity;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateOption;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateSubject;
|
||||||
|
import io.v.nutz.zhgh.welfare.model.eavluate.WelfareEvaluateUserAnswerRecord;
|
||||||
|
import io.v.nutz.zhgh.welfare.service.WelfareEvaluateActivityService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
|
import org.nutz.dao.Cnd;
|
||||||
|
import org.nutz.dao.Dao;
|
||||||
|
import org.nutz.dao.Sqls;
|
||||||
|
import org.nutz.dao.sql.Sql;
|
||||||
|
import org.nutz.ioc.loader.annotation.IocBean;
|
||||||
|
import org.nutz.lang.Lang;
|
||||||
|
import org.nutz.lang.util.NutMap;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @version 1.0
|
||||||
|
* @Author zzr
|
||||||
|
* @name:WelfareEvaluateActivityServiceImpl
|
||||||
|
* @Date 2025/8/11 15:14
|
||||||
|
* @注释
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@IocBean(args = {"refer:dao"})
|
||||||
|
public class WelfareEvaluateActivityServiceImpl extends BaseServiceImpl<WelfareEvaluateActivity> implements WelfareEvaluateActivityService {
|
||||||
|
public WelfareEvaluateActivityServiceImpl(Dao dao) {
|
||||||
|
super(dao);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WelfareEvaluateUserAnswerRecord insertRecord(String activityId, List<String> subjectIds) {
|
||||||
|
WelfareEvaluateUserAnswerRecord record = new WelfareEvaluateUserAnswerRecord();
|
||||||
|
record.setActivityId(activityId);
|
||||||
|
record.setUserId(ShiroUtil.getUserId());
|
||||||
|
record.setSubjectIds(subjectIds);
|
||||||
|
|
||||||
|
JSONObject extJson = new JSONObject();
|
||||||
|
for (String subjectId : subjectIds) {
|
||||||
|
extJson.set(subjectId, Dict.create()
|
||||||
|
.set("optionIds", new ArrayList<>())
|
||||||
|
.set("text", null)
|
||||||
|
.set("isCorrect", null)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
record.setExtJson(extJson);
|
||||||
|
|
||||||
|
User user = dao().fetch(User.class, Cnd.where("id", "=", ShiroUtil.getUserId()));
|
||||||
|
record.setLoginName(user.getLoginname());
|
||||||
|
record.setUserName(user.getUsername());
|
||||||
|
record.setUnitId(user.getUnitid());
|
||||||
|
record.setUnitName(user.getUnitname());
|
||||||
|
record.setUnionId(user.getUnionid());
|
||||||
|
record.setUnionName(user.getUnionname());
|
||||||
|
|
||||||
|
dao().insert(record);
|
||||||
|
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> dataReport(String activityId) {
|
||||||
|
// 检查活动ID是否为空
|
||||||
|
if (activityId == null || activityId.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("活动ID不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 查询用户答题记录
|
||||||
|
List<WelfareEvaluateUserAnswerRecord> answerRecords = dao().query(WelfareEvaluateUserAnswerRecord.class, Cnd.where("activityId", "=", activityId)
|
||||||
|
.and("isFinish", "=", true));
|
||||||
|
// 将答题记录的扩展JSON转换为JSONObject列表
|
||||||
|
List<JSONObject> answerExtList = answerRecords.stream().map(WelfareEvaluateUserAnswerRecord::getExtJson).toList();
|
||||||
|
|
||||||
|
// 查询活动题目列表
|
||||||
|
List<NutMap> subjects = querySubjects(activityId);
|
||||||
|
// 获取题目ID列表
|
||||||
|
List<String> subjectIds = subjects.stream().map(v -> v.getString("id")).toList();
|
||||||
|
|
||||||
|
// 查询题目选项列表
|
||||||
|
List<WelfareEvaluateOption> options = dao().query(WelfareEvaluateOption.class, Cnd.where("subjectId", "in", subjectIds).asc("sortNum"));
|
||||||
|
// 按题目ID分组选项
|
||||||
|
Map<String, List<WelfareEvaluateOption>> optionsGroup = options.stream().collect(Collectors.groupingBy(WelfareEvaluateOption::getSubjectId));
|
||||||
|
|
||||||
|
// 处理每个题目
|
||||||
|
for (NutMap subject : subjects) {
|
||||||
|
// 获取当前题目的选项列表
|
||||||
|
List<NutMap> subjectOptions = Lang.collection2list(optionsGroup.get(subject.getString("id")), NutMap.class);
|
||||||
|
|
||||||
|
// 获取题目类型
|
||||||
|
String subjectType = subject.getString("type");
|
||||||
|
|
||||||
|
// 处理文本类型题目
|
||||||
|
if ("text".equals(subjectType)) {
|
||||||
|
List<String> texts = answerExtList.stream()
|
||||||
|
.filter(ext -> ObjectUtil.isNotNull(ext.get(subject.getString("id"), JSONObject.class)))
|
||||||
|
.map(ext -> ext.get(subject.getString("id"), JSONObject.class).getStr("text"))
|
||||||
|
.toList();
|
||||||
|
subject.put("texts", texts);
|
||||||
|
}
|
||||||
|
// 处理单选类型题目 处理多选类型题目
|
||||||
|
else if ("radio".equals(subjectType) || "checkbox".equals(subjectType)) {
|
||||||
|
long selectTotal = answerExtList.stream()
|
||||||
|
.filter(ext -> ext.containsKey(subject.getString("id")))
|
||||||
|
.count();
|
||||||
|
|
||||||
|
subjectOptions.forEach(subjectOption -> {
|
||||||
|
long selectCount = answerExtList.stream()
|
||||||
|
.filter(ext ->
|
||||||
|
{
|
||||||
|
JSONObject jsonObject = ext.get(subject.getString("id"), JSONObject.class);
|
||||||
|
return jsonObject != null
|
||||||
|
&& jsonObject.getJSONArray("optionIds") != null
|
||||||
|
&& jsonObject.getJSONArray("optionIds").contains(subjectOption.getString("id"));
|
||||||
|
})
|
||||||
|
.count();
|
||||||
|
long round = Math.round((double) selectCount / selectTotal * 100);
|
||||||
|
subjectOption.put("selectPercent", round + "%");
|
||||||
|
subjectOption.put("selectCount", selectCount);
|
||||||
|
});
|
||||||
|
|
||||||
|
subjectOptions.sort((o1, o2) -> {
|
||||||
|
int count1 = o1.getInt("selectCount");
|
||||||
|
int count2 = o2.getInt("selectCount");
|
||||||
|
if (count1 == count2) {
|
||||||
|
return Integer.compare(o1.getInt("sortNum"), o2.getInt("sortNum"));
|
||||||
|
}
|
||||||
|
return Integer.compare(count2, count1);
|
||||||
|
});
|
||||||
|
|
||||||
|
subject.put("selectTotal", selectTotal);
|
||||||
|
}
|
||||||
|
// 添加选项到题目中
|
||||||
|
subject.addv("options", subjectOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
return subjects;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("报告生成失败", e);
|
||||||
|
throw new RuntimeException("报告生成失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ExcelExportEntity> buildExcelExportEntities(List<WelfareEvaluateSubject> subjects) {
|
||||||
|
List<ExcelExportEntity> excelExportEntities = new ArrayList<>();
|
||||||
|
excelExportEntities.add(new ExcelExportEntity("工号", "loginName", 20));
|
||||||
|
excelExportEntities.add(new ExcelExportEntity("姓名", "userName", 20));
|
||||||
|
excelExportEntities.add(new ExcelExportEntity("单位", "unitName", 20));
|
||||||
|
excelExportEntities.add(new ExcelExportEntity("分工会", "unionName", 20));
|
||||||
|
excelExportEntities.add(new ExcelExportEntity("联系方式", "mobile", 20));
|
||||||
|
excelExportEntities.add(new ExcelExportEntity("所选福利", "gistList", 20));
|
||||||
|
for (WelfareEvaluateSubject subject : subjects) {
|
||||||
|
excelExportEntities.add(new ExcelExportEntity(subject.getTitle(), subject.getId(), 20));
|
||||||
|
}
|
||||||
|
return excelExportEntities;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<NutMap> buildAnswerRecords(List<NutMap> answerRecords,
|
||||||
|
Map<String, WelfareEvaluateSubject> subjectMap,
|
||||||
|
List<WelfareEvaluateOption> options) {
|
||||||
|
return answerRecords.stream().map(record -> {
|
||||||
|
NutMap map = NutMap.NEW()
|
||||||
|
.addv("loginName", record.getString("loginName"))
|
||||||
|
.addv("userName", record.getString("userName"))
|
||||||
|
.addv("unitName", record.getString("unitName"))
|
||||||
|
.addv("unionName", record.getString("unionName"))
|
||||||
|
.addv("mobile", record.getString("mobile"))
|
||||||
|
.addv("gistList", record.getString("gistList"));
|
||||||
|
JSONObject extJson = record.getAs("extJson", JSONObject.class);
|
||||||
|
if (extJson == null) {
|
||||||
|
extJson = new JSONObject();
|
||||||
|
}
|
||||||
|
extJson.forEach((k, v) -> {
|
||||||
|
// JSONObject jsonVal = (JSONObject) v;
|
||||||
|
//
|
||||||
|
// String type = subjectMap.get(k).getType();
|
||||||
|
// if ("text".equals(type)) {
|
||||||
|
// map.addv(k, jsonVal.getStr("text"));
|
||||||
|
// } else if ("radio".equals(type) || "checkbox".equals(type)) {
|
||||||
|
// JSONArray optionIds = jsonVal.getJSONArray("optionIds");
|
||||||
|
// String selectOptionTexts = options.stream().filter(option -> optionIds.contains(option.getId()))
|
||||||
|
// .map(WelfareEvaluateOption::getText).collect(Collectors.joining(";"));
|
||||||
|
// map.addv(k, selectOptionTexts);
|
||||||
|
// }
|
||||||
|
JSONObject jsonVal = (JSONObject) v;
|
||||||
|
|
||||||
|
String type = subjectMap.get(k).getType();
|
||||||
|
if ("text".equals(type)) {
|
||||||
|
map.addv(k, jsonVal.getStr("text"));
|
||||||
|
} else if ("radio".equals(type) || "checkbox".equals(type)) {
|
||||||
|
List<NutMap> optionContents = jsonVal.getBeanList("optionContents", NutMap.class);
|
||||||
|
|
||||||
|
String selectOptionTexts = optionContents.stream().map(item -> {
|
||||||
|
WelfareEvaluateOption eva = options.stream().filter(option -> option.getId().equals(item.getString("optionId"))).findFirst().orElse(new WelfareEvaluateOption());
|
||||||
|
return eva.getText() + (StrUtil.isNotBlank(item.getString("content")) ? ("—" + eva.getContentPrefix() + ":") + item.getString("content") : "");
|
||||||
|
}).collect(Collectors.joining(";"));
|
||||||
|
map.addv(k, selectOptionTexts);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return map;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exportReportXlsx(String activityId, HttpServletResponse response) {
|
||||||
|
List<NutMap> report = dataReport(activityId);
|
||||||
|
|
||||||
|
List<ExcelExportEntity> exportEntities = new ArrayList<>();
|
||||||
|
exportEntities.add(new ExcelExportEntity("选项名称", "text", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("选择人数", "selectCount", 20));
|
||||||
|
exportEntities.add(new ExcelExportEntity("选择比例", "selectPercent", 20));
|
||||||
|
|
||||||
|
Map<String, List<NutMap>> listMap = report.stream().collect(Collectors.groupingBy(v -> v.getString("id")));
|
||||||
|
Workbook workbook = new XSSFWorkbook();
|
||||||
|
listMap.forEach((k, v) -> {
|
||||||
|
NutMap nutMap = v.get(0);
|
||||||
|
ExcelExportService service = new ExcelExportService();
|
||||||
|
ExportParams exportParams = new ExportParams();
|
||||||
|
exportParams.setTitle(nutMap.getString("title"));
|
||||||
|
exportParams.setSheetName(nutMap.getString("title"));
|
||||||
|
exportParams.setType(ExcelType.XSSF);
|
||||||
|
service.createSheetForMap(workbook, exportParams, exportEntities, nutMap.getList("options", NutMap.class));
|
||||||
|
});
|
||||||
|
|
||||||
|
CommonDownloadUtil.download("满意度分析.xlsx", workbook, response);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<NutMap> querySubjects(String activityId) {
|
||||||
|
Sql sql = Sqls.create("""
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
sortNum
|
||||||
|
FROM
|
||||||
|
welfare_evaluate_subject
|
||||||
|
WHERE
|
||||||
|
activityId = @activityId
|
||||||
|
ORDER BY
|
||||||
|
sortNum ASC
|
||||||
|
""");
|
||||||
|
sql.setParam("activityId", activityId);
|
||||||
|
sql.setCallback(Sqls.callback.maps());
|
||||||
|
dao().execute(sql);
|
||||||
|
return (List<NutMap>) sql.getResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
</el-descriptions-item>-->
|
</el-descriptions-item>-->
|
||||||
|
|
||||||
<el-descriptions-item label="报名时间">{{ viewData.signingUptime }}</el-descriptions-item>
|
<el-descriptions-item label="报名时间">{{ viewData.signingUptime }}</el-descriptions-item>
|
||||||
<el-descriptions-item label="参加活动时间">{{
|
<el-descriptions-item label="预出行时间">{{
|
||||||
viewData.specificTime ? viewData.specificTime : "暂未更新"
|
viewData.specificTime ? viewData.specificTime : "暂未更新"
|
||||||
}}
|
}}
|
||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
@@ -35,8 +35,14 @@
|
|||||||
</el-descriptions-item>
|
</el-descriptions-item>
|
||||||
|
|
||||||
|
|
||||||
<el-descriptions-item label="线路名称">{{ viewData.lineName }}</el-descriptions-item>
|
<template v-if="viewData.takePartInBaseManagementId">
|
||||||
<el-descriptions-item label="旅行社名称">{{ viewData.travelAgencyName }}</el-descriptions-item>
|
<el-descriptions-item label="定点名称">{{ viewData.baseName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="旅行社名称">{{ viewData.baseTravelAgencyName }}</el-descriptions-item>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<el-descriptions-item label="线路名称">{{ viewData.lineName }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="旅行社名称">{{ viewData.travelAgencyName }}</el-descriptions-item>
|
||||||
|
</template>
|
||||||
<el-descriptions-item label="是否含随行人">
|
<el-descriptions-item label="是否含随行人">
|
||||||
<span class="label label-primary">
|
<span class="label label-primary">
|
||||||
{{ (viewData.companionList && viewData.companionList.length > 0) ? "携带" : "未携带" }}
|
{{ (viewData.companionList && viewData.companionList.length > 0) ? "携带" : "未携带" }}
|
||||||
|
|||||||
@@ -152,6 +152,14 @@
|
|||||||
Vue.prototype.$axios = commonUtil.axiosService()
|
Vue.prototype.$axios = commonUtil.axiosService()
|
||||||
Vue.prototype.$downLoad = commonUtil.downLoadService
|
Vue.prototype.$downLoad = commonUtil.downLoadService
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
if (window.innerWidth < 768 && location.pathname === '/platform/home') {
|
||||||
|
window.location.replace('/mobile/index');
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="gallery-loader" style="background-color:transparent;">
|
<div class="gallery-loader" style="background-color:transparent;">
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ layout("/mobile/platform.html"){
|
|||||||
}
|
}
|
||||||
|
|
||||||
.swiper {
|
.swiper {
|
||||||
height: 200px;
|
height: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.swiper img {
|
.swiper img {
|
||||||
height: 200px;
|
height: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.module {
|
.module {
|
||||||
@@ -172,7 +172,7 @@ layout("/mobile/platform.html"){
|
|||||||
|
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<!--首页-->
|
<!--首页-->
|
||||||
<div style="margin-bottom: 60px" v-if="active === 0">
|
<div style="margin-bottom: 60px;max-height: calc(100vh - 60px);overflow-y: auto" v-if="active === 0">
|
||||||
<!--轮播图-->
|
<!--轮播图-->
|
||||||
<van-swipe :autoplay="3000" class="swiper">
|
<van-swipe :autoplay="3000" class="swiper">
|
||||||
<van-swipe-item :key="index" v-for="(image, index) in images">
|
<van-swipe-item :key="index" v-for="(image, index) in images">
|
||||||
@@ -724,8 +724,8 @@ layout("/mobile/platform.html"){
|
|||||||
const active = sessionStorage.getItem("zhgh-mobile-home-active")
|
const active = sessionStorage.getItem("zhgh-mobile-home-active")
|
||||||
this.active = active ? parseInt(active) : 0
|
this.active = active ? parseInt(active) : 0
|
||||||
|
|
||||||
// this.clickIndex = 2
|
this.clickIndex = 2
|
||||||
// this.clickMenu = this.moduleMenus.find(o => o.moduleName === '日常办公')
|
this.clickMenu = this.moduleMenus.find(o => o.moduleName === '职工权益')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ layout("/mobile/platform.html"){
|
|||||||
</div>
|
</div>
|
||||||
<div style="text-indent: 2.1rem">
|
<div style="text-indent: 2.1rem">
|
||||||
<span :style="'color:' + (formData.isVoluntary ? '#1989fa' : '#F56C6C') ">
|
<span :style="'color:' + (formData.isVoluntary ? '#1989fa' : '#F56C6C') ">
|
||||||
我将严格遵守工会章程 ,认真执行工会决议,积极参与工会活动,主动融入“杭医健康幸福家”建设,为营造温暖、和谐、奋进的校园氛围贡献力量,以实际行动助力学校各项事业发展。
|
我将严格遵守工会章程,认真执行工会决议,积极参与工会活动,主动融入“杭医健康幸福家”建设,为营造温暖、和谐、奋进的校园氛围贡献力量,以实际行动助力学校各项事业发展。
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</van-checkbox>
|
</van-checkbox>
|
||||||
|
|||||||
@@ -125,7 +125,6 @@
|
|||||||
async flushCache() {
|
async flushCache() {
|
||||||
const day = moment().format('YYYY-MM-DD')
|
const day = moment().format('YYYY-MM-DD')
|
||||||
if (window.localStorage.getItem('flushCache') !== day) {
|
if (window.localStorage.getItem('flushCache') !== day) {
|
||||||
debugger
|
|
||||||
const { code, msg } = await $.post('/platform/home/clearCache')
|
const { code, msg } = await $.post('/platform/home/clearCache')
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
location.reload()
|
location.reload()
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ layout("/mobile/platform.html"){
|
|||||||
<span>联系方式:</span>{{o.baseContactNumber}}
|
<span>联系方式:</span>{{o.baseContactNumber}}
|
||||||
</div>
|
</div>
|
||||||
<div class="mobile">
|
<div class="mobile">
|
||||||
<span>已报人数:</span>{{o.signUpUserNum}}
|
<span>出行时间:</span>{{o.specificTime}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,424 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/mobile/platform.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
background: #ffffff;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .title {
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px;
|
||||||
|
background: #ffffff;
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .card {
|
||||||
|
padding: 10px;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description, .last-content {
|
||||||
|
background: rgb(255, 255, 255);
|
||||||
|
padding: 5px 20px;
|
||||||
|
margin: -15px 0 10px 0;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject {
|
||||||
|
background: #fff;
|
||||||
|
padding: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
/*border-top: 2px solid rgba(24, 103, 176, 0.6);*/
|
||||||
|
border-bottom: 2px solid rgba(24, 103, 176, 0.6);
|
||||||
|
/*box-shadow: 0 2px 4px rgba(24, 103, 176, 0.6);*/
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.first-box {
|
||||||
|
border-top: 2px solid rgba(24, 103, 176, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject p {
|
||||||
|
font-size: 16px;
|
||||||
|
margin: 20px 0 10px 0;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject .tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-control {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 20px;
|
||||||
|
display: flex;
|
||||||
|
column-gap: 20px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-checkbox__icon--checked .van-icon {
|
||||||
|
color: #fff !important;
|
||||||
|
background-color: var(--color-primary) !important;
|
||||||
|
border-color: var(--color-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.van-checkbox__icon--disabled .van-icon {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-input-box {
|
||||||
|
border: 1px solid #e3e3e3;
|
||||||
|
margin: 5px 0;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-input-box input {
|
||||||
|
background-color: #fff;
|
||||||
|
border: none !important;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 18px;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
resize: none;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc-content{
|
||||||
|
width: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc-content *{
|
||||||
|
max-width: 100%!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div id="app" v-cloak>
|
||||||
|
<van-nav-bar title="满意度调查" left-arrow @click-left="doBack" placeholder fixed></van-nav-bar>
|
||||||
|
<div class="container" :style="{'padding-bottom': answerRecord.isFinish ? 0 : '84px'}">
|
||||||
|
<h2 class="title">{{ activity.title }}</h2>
|
||||||
|
<div class="description" v-if="activity.description">
|
||||||
|
<div v-html="activity.description"></div>
|
||||||
|
</div>
|
||||||
|
<div v-if="!isFinished">
|
||||||
|
<div v-for="(subject, index) in subjects" :key="index" class="subject" :class="{ 'first-box': index === 0 }">
|
||||||
|
<p>{{index+1}}、{{ subject.title }}</p>
|
||||||
|
<div class="tag">
|
||||||
|
<van-tag v-if="subject.type === 'checkbox'" type="primary" size="large">多选</van-tag>
|
||||||
|
<van-tag v-if="subject.type === 'radio'" type="primary" size="large">单选</van-tag>
|
||||||
|
<van-tag v-if="subject.type === 'text'" type="primary" size="large">填空</van-tag>
|
||||||
|
<van-tag v-if="subject.score" type="primary" size="large">{{subject.score}}分</van-tag>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--单选、多选-->
|
||||||
|
<van-checkbox-group
|
||||||
|
v-model="subject.userSelectOptionIds"
|
||||||
|
:ref="'subject'+subject.id"
|
||||||
|
:max="subject.maxMulti ? subject.maxMulti : 0"
|
||||||
|
v-if="['radio','checkbox'].includes(subject.type)"
|
||||||
|
>
|
||||||
|
<van-cell-group>
|
||||||
|
|
||||||
|
<div v-for="(option,index) in subject.options">
|
||||||
|
|
||||||
|
<van-cell :title="option.text" :key="option.id" clickable @click="cellToggle(subject,option.id)">
|
||||||
|
<template #icon>
|
||||||
|
<van-checkbox :name="option.id" :ref="'option'+option.id"
|
||||||
|
:disabled="answerRecord.isFinish"
|
||||||
|
style="margin-right: 10px"></van-checkbox>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<img
|
||||||
|
slot="right-icon"
|
||||||
|
v-if="option.imgUrl"
|
||||||
|
:src="option.imgUrl"
|
||||||
|
alt=""
|
||||||
|
style="width: 40px; height: 40px"
|
||||||
|
@click.stop="previewOptionImg(option.imgUrl)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div slot="extra">
|
||||||
|
<div v-if="option.description" style="color: #0a84ff" @click.stop="openDesc(option)">
|
||||||
|
查看详情
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</van-cell>
|
||||||
|
|
||||||
|
<div v-if="option.isOpenContent==true && selectOptionIds.includes(option.id)">
|
||||||
|
<van-field v-model="option.content" :label="option.contentPrefix"
|
||||||
|
:placeholder="'请填写' + (option.contentPrefix ? option.contentPrefix : '')"
|
||||||
|
:disabled="answerRecord.isFinish"></van-field>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</van-cell-group>
|
||||||
|
</van-checkbox-group>
|
||||||
|
|
||||||
|
<!--填空题-->
|
||||||
|
<div class="ui-input-box" v-if="subject.type==='text'">
|
||||||
|
<input type="text" v-model="subject.userFillContent" :readonly="answerRecord.isFinish" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="last-content" style="margin-top: 0px" v-if="activity.lastContent">
|
||||||
|
<div v-html="activity.lastContent"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="button-control" v-if="!answerRecord.isFinish">
|
||||||
|
<van-button type="primary" style="background-color: #0a84ff;border: 1px solid #0a84ff"
|
||||||
|
@click="onSubmit" block :disabled="isEnd">{{isEnd ? '已结束' : '提交'}}</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<van-action-sheet v-model="descShow" title="详情">
|
||||||
|
<div class="desc-content" v-html="optionDesc" @click="descClick">
|
||||||
|
</div>
|
||||||
|
</van-action-sheet>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const vue = new Vue({
|
||||||
|
el: "#app",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
pjaxType: '',
|
||||||
|
list: [],
|
||||||
|
id: null,
|
||||||
|
subjects: [],
|
||||||
|
activity: {},
|
||||||
|
remainingTime: 0,
|
||||||
|
isFinished: false,
|
||||||
|
answerRecord: {},
|
||||||
|
answerRecordId: null,
|
||||||
|
|
||||||
|
descShow:false,
|
||||||
|
optionDesc:null,
|
||||||
|
|
||||||
|
selectOptionIds: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
isEnd() {
|
||||||
|
if (this.activity) {
|
||||||
|
return this.$moment().unix() > this.$moment(this.activity.endTime).unix()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
//获取活动、题目
|
||||||
|
listSubjects() {
|
||||||
|
$.post("/platform/h5/welfare/evaluate/subjects", { activityId: this.id }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.activity = res.data.activity
|
||||||
|
this.subjects = res.data.subjects
|
||||||
|
this.answerRecordId = res.data.answerRecordId
|
||||||
|
this.getAnswerRecord()
|
||||||
|
} else {
|
||||||
|
vant.Dialog.alert({
|
||||||
|
title: '温馨提示',
|
||||||
|
message: res.msg,
|
||||||
|
}).then(() => {
|
||||||
|
pjaxReplace("/mobile/index")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//获取回答记录
|
||||||
|
getAnswerRecord() {
|
||||||
|
$.post("/platform/h5/welfare/evaluate/answerRecord", { answerRecordId: this.answerRecordId }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.answerRecord = res.data
|
||||||
|
if (this.answerRecord.isFinish) {
|
||||||
|
vant.Dialog.alert({
|
||||||
|
title: '温馨提示',
|
||||||
|
message: '您已完成该调查,感谢您的参与!',
|
||||||
|
}).then(() => {
|
||||||
|
// on close
|
||||||
|
});
|
||||||
|
// this.$toast.success("您已完成该调查")
|
||||||
|
}
|
||||||
|
this.initAnswer()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//答案回显
|
||||||
|
initAnswer() {
|
||||||
|
this.subjects.forEach((subject, subjectIndex) => {
|
||||||
|
const answer = this.answerRecord.extJson[subject.id]
|
||||||
|
|
||||||
|
if (["radio", "checkbox"].includes(subject.type)) {
|
||||||
|
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||||
|
answer?.optionIds.forEach((optionId) => {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs["option" + optionId][0].toggle()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (answer.optionContents && answer.optionContents.length > 0) {
|
||||||
|
answer.optionContents.forEach((data) => {
|
||||||
|
if (data.content) {
|
||||||
|
this.selectOptionIds.push(data.optionId)
|
||||||
|
const option = subject.options.find(option => option.id === data.optionId)
|
||||||
|
option.content = data.content
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (subject.type === "text") {
|
||||||
|
subject.userFillContent = answer?.text
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//选项点击
|
||||||
|
cellToggle(subject, optionId) {
|
||||||
|
if (this.answerRecord.isFinish) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subject.type === "radio") {
|
||||||
|
this.$refs["subject" + subject.id][0].toggleAll(false)
|
||||||
|
const option = subject.options.find(option => option.id === optionId)
|
||||||
|
this.selectOptionIds = this.selectOptionIds.filter(item => item !== optionId)
|
||||||
|
if (option.isOpenContent == true) {
|
||||||
|
this.selectOptionIds.push(optionId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.$refs["option" + optionId][0].toggle()
|
||||||
|
},
|
||||||
|
|
||||||
|
//预览图片
|
||||||
|
previewOptionImg(img) {
|
||||||
|
vant.ImagePreview([img])
|
||||||
|
},
|
||||||
|
|
||||||
|
//查看详情
|
||||||
|
openDesc(option){
|
||||||
|
this.descShow = true
|
||||||
|
this.optionDesc = option.description
|
||||||
|
},
|
||||||
|
|
||||||
|
//详情点击
|
||||||
|
descClick(event){
|
||||||
|
//如果点击的是图片
|
||||||
|
if(event.target.tagName === 'IMG'){
|
||||||
|
vant.ImagePreview([event.target.src])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//手动提交
|
||||||
|
onSubmit() {
|
||||||
|
if (this.isEnd) {
|
||||||
|
this.$toast("调查已结束")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//提示那些题没有作答
|
||||||
|
for (let i = 0; i < this.subjects.length; i++) {
|
||||||
|
const subject = this.subjects[i]
|
||||||
|
if (["radio", "checkbox"].includes(subject.type)) {
|
||||||
|
if (!subject.userSelectOptionIds || subject.userSelectOptionIds.length === 0) {
|
||||||
|
this.$toast.fail("第" + (i + 1) + "题未做答")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else if ("text" === subject.type) {
|
||||||
|
if (!subject.userFillContent) {
|
||||||
|
this.$toast.fail("第" + (i + 1) + "题未作答")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提示确定提交吗
|
||||||
|
vant.Dialog.confirm({
|
||||||
|
title: '温馨提示',
|
||||||
|
message: '提交后不可修改哦,确定要提交吗?',
|
||||||
|
}).then(() => {
|
||||||
|
this.autoSubmit()
|
||||||
|
}).catch(() => {
|
||||||
|
// on cancel
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
//自动提交
|
||||||
|
autoSubmit(loading = null) {
|
||||||
|
$.post("/platform/h5/welfare/evaluate/submitAnswer", {
|
||||||
|
answer: JSON.stringify({
|
||||||
|
activityId: this.id,
|
||||||
|
answerRecordId: this.answerRecordId,
|
||||||
|
subjects: this.subjects.map((subject) => {
|
||||||
|
const isChoiceType = ["checkbox", "radio"].includes(subject.type);
|
||||||
|
const userSelectOptions = isChoiceType ? subject.userSelectOptionIds.map((optionId) => {
|
||||||
|
const option = subject.options.find((option) => option.id === optionId);
|
||||||
|
return option ? {
|
||||||
|
optionId: option.id,
|
||||||
|
content: option.content
|
||||||
|
} : '';
|
||||||
|
}) : [];
|
||||||
|
const userFillContent = subject.type === "text" ? subject.userFillContent : null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: subject.id,
|
||||||
|
userSelectOptionIds: isChoiceType ? subject.userSelectOptionIds : [],
|
||||||
|
userSelectOptionContent: userSelectOptions,
|
||||||
|
userFillContent
|
||||||
|
};
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$toast.success(res.msg)
|
||||||
|
this.getAnswerRecord()
|
||||||
|
}
|
||||||
|
if (loading) {
|
||||||
|
loading.clear()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
doBack() {
|
||||||
|
if (this.pjaxType === "welfare") {
|
||||||
|
pjaxReplace('/mobile/welfare/mine/myWelfare')
|
||||||
|
} else {
|
||||||
|
pjaxReplace('/mobile/index')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
const id = GetQueryString("id")
|
||||||
|
this.pjaxType = GetQueryString("type")
|
||||||
|
if (id) {
|
||||||
|
this.id = id
|
||||||
|
this.listSubjects()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -110,7 +110,7 @@ layout("/mobile/platform.html"){
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div slot="footer" style="margin-top: 10px;">
|
<div slot="footer" style="margin-top: 10px;">
|
||||||
<van-button @click="openEvaluate(item)" plain round size="small">评价商品
|
<van-button v-if="item.evaId" @click="openEvaluate(item)" plain round size="small">评价商品
|
||||||
</van-button>
|
</van-button>
|
||||||
<van-button @click="openExpress(item)" plain round size="small"
|
<van-button @click="openExpress(item)" plain round size="small"
|
||||||
v-if="item.provideMode==3">
|
v-if="item.provideMode==3">
|
||||||
@@ -424,17 +424,18 @@ layout("/mobile/platform.html"){
|
|||||||
|
|
||||||
//打开评价
|
//打开评价
|
||||||
async openEvaluate(item) {
|
async openEvaluate(item) {
|
||||||
if (item.isChoose !== 1) {
|
pjaxReplace('/platform/h5/welfare/evaluate?id=' + item.evaId + '&type=welfare')
|
||||||
this.$modal.msg("选择后才能评价")
|
// if (item.isChoose !== 1) {
|
||||||
return
|
// this.$modal.msg("选择后才能评价")
|
||||||
}
|
// return
|
||||||
|
// }
|
||||||
const resp = await this.getUserSelection(item.projectId)
|
//
|
||||||
this.selectedOptions = resp.data
|
// const resp = await this.getUserSelection(item.projectId)
|
||||||
if (this.selectedOptions && this.selectedOptions.length > 0) {
|
// this.selectedOptions = resp.data
|
||||||
await this.finOneWelfareEvaluate(item.id, this.selectedOptions[0].selectOptionId)
|
// if (this.selectedOptions && this.selectedOptions.length > 0) {
|
||||||
}
|
// await this.finOneWelfareEvaluate(item.id, this.selectedOptions[0].selectOptionId)
|
||||||
this.evaluatePopup = true
|
// }
|
||||||
|
// this.evaluatePopup = true
|
||||||
},
|
},
|
||||||
async finOneWelfareEvaluate(projectId, optionId) {
|
async finOneWelfareEvaluate(projectId, optionId) {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'sex', label: '性别', sortable: true, width: '100px'},
|
{prop: 'sex', label: '性别', sortable: true, width: '100px'},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true},
|
||||||
{prop: 'optionName', label: '所选套餐', width: "100px"},
|
{prop: 'optionName', label: '所选套餐', width: "100px"},
|
||||||
// {prop: 'userSign', label: '签字', width: "100px"},
|
// {prop: 'userSign', label: '签字', width: "100px"},
|
||||||
|
|||||||
@@ -360,7 +360,7 @@
|
|||||||
{prop: 'mobile', label: '联系电话'},
|
{prop: 'mobile', label: '联系电话'},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
{prop: 'applyDate', label: '申请时间', sortable: true},
|
{prop: 'applyDate', label: '申请时间', sortable: true},
|
||||||
{prop: 'stateId', label: '状态', sortable: true},
|
{prop: 'stateId', label: '状态', sortable: true},
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ layout("/layouts/platform.html"){
|
|||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span style="flex: 1; word-wrap: break-word; word-break: break-all; white-space: normal;">
|
<span style="flex: 1; word-wrap: break-word; word-break: break-all; white-space: normal;">
|
||||||
我将严格遵守工会章程 ,认真执行工会决议,积极参与工会活动,主动融入“杭医健康幸福家”建设,为营造温暖、和谐、奋进的校园氛围贡献力量,以实际行动助力学校各项事业发展。
|
我将严格遵守工会章程,认真执行工会决议,积极参与工会活动,主动融入“杭医健康幸福家”建设,为营造温暖、和谐、奋进的校园氛围贡献力量,以实际行动助力学校各项事业发展。
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
|
|||||||
@@ -615,7 +615,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'preparedBy', label: '人员性质', sortable: true},
|
{prop: 'preparedBy', label: '人员性质', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
// {prop: 'campusName', label: '所属校区', sortable: true},
|
// {prop: 'campusName', label: '所属校区', sortable: true},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -606,7 +606,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'preparedBy', label: '人员性质', sortable: true},
|
{prop: 'preparedBy', label: '人员性质', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
// {prop: 'campusName', label: '所属校区', sortable: true},
|
// {prop: 'campusName', label: '所属校区', sortable: true},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -261,7 +261,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'userState', label: '在职状态', sortable: true},
|
{prop: 'userState', label: '在职状态', sortable: true},
|
||||||
// {prop: 'unionname', label: '所属工会', sortable: true},
|
// {prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
// {prop: 'campusName', label: '所属校区', sortable: true},
|
// {prop: 'campusName', label: '所属校区', sortable: true},
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -300,7 +300,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'political', label: '政治面貌', sortable: true},
|
{prop: 'political', label: '政治面貌', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
||||||
{prop: 'marriage', label: '婚否', checked: 0},
|
{prop: 'marriage', label: '婚否', checked: 0},
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'userState', label: '在职状态', sortable: true},
|
{prop: 'userState', label: '在职状态', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
],
|
],
|
||||||
isThreeUnit: false,
|
isThreeUnit: false,
|
||||||
|
|||||||
@@ -373,7 +373,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'preparedBy', label: '人员性质', sortable: true},
|
{prop: 'preparedBy', label: '人员性质', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
{prop: 'member', label: '是否会员', sortable: true},
|
{prop: 'member', label: '是否会员', sortable: true},
|
||||||
{prop: 'welfareMember', label: '是否福利会员', sortable: true},
|
{prop: 'welfareMember', label: '是否福利会员', sortable: true},
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'userState', label: '在职状态', sortable: true},
|
{prop: 'userState', label: '在职状态', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
],
|
],
|
||||||
userId: null,
|
userId: null,
|
||||||
|
|||||||
@@ -470,16 +470,18 @@ layout("/layouts/platform.html"){
|
|||||||
v-loading="tableLoading">
|
v-loading="tableLoading">
|
||||||
|
|
||||||
<el-table-column align="center" header-align="center" type="index"
|
<el-table-column align="center" header-align="center" type="index"
|
||||||
:index="indexMethod" label="序号"
|
:index="indexMethod" label="序号" fixed
|
||||||
width="80px"></el-table-column>
|
width="50px"></el-table-column>
|
||||||
|
|
||||||
<el-table-column
|
<el-table-column
|
||||||
align="center"
|
align="center"
|
||||||
header-align="center"
|
header-align="center"
|
||||||
v-for="column in tableColumns"
|
v-for="column in tableColumns"
|
||||||
|
:width="column.width"
|
||||||
show-overflow-tooltip
|
show-overflow-tooltip
|
||||||
:label="column.label"
|
:label="column.label"
|
||||||
:prop="column.prop"
|
:prop="column.prop"
|
||||||
|
:fixed="column.fixed"
|
||||||
:sortable="column.sortable"
|
:sortable="column.sortable"
|
||||||
>
|
>
|
||||||
<template v-if="column.prop==='unitname'" scope="{row}">
|
<template v-if="column.prop==='unitname'" scope="{row}">
|
||||||
@@ -493,7 +495,7 @@ layout("/layouts/platform.html"){
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
<el-table-column align="center" header-align="center" label="操作" width="100px">
|
<el-table-column align="center" header-align="center" fixed="right" label="操作" width="100px">
|
||||||
<template scope="{row:{id}}">
|
<template scope="{row:{id}}">
|
||||||
<el-button size="small" @click="openView(id)">查看</el-button>
|
<el-button size="small" @click="openView(id)">查看</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -605,21 +607,21 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
tableColumns: [
|
tableColumns: [
|
||||||
{prop: 'loginname', label: '工号'},
|
{prop: 'loginname', label: '工号', width: 100, fixed: true},
|
||||||
{prop: 'username', label: '姓名'},
|
{prop: 'username', label: '姓名', width: 100, fixed: true},
|
||||||
{prop: 'sex', label: '性别'},
|
{prop: 'sex', label: '性别', width: 55},
|
||||||
{prop: 'birthday', label: '出生年月', sortable: true},
|
{prop: 'birthday', label: '出生年月', sortable: true, width: 100},
|
||||||
{prop: 'mobile', label: '联系电话'},
|
{prop: 'mobile', label: '联系电话', width: 110},
|
||||||
{prop: 'idcard', label: '身份证号', width: 170},
|
{prop: 'idcard', label: '身份证号', width: 170},
|
||||||
{prop: 'position', label: '职务', sortable: true, checked: 0},
|
{prop: 'position', label: '职务', sortable: true, checked: 0},
|
||||||
{prop: 'jobTitle', label: '职称', sortable: true, checked: 0},
|
{prop: 'jobTitle', label: '职称', sortable: true, checked: 0},
|
||||||
{prop: 'userState', label: '在职状态', sortable: true},
|
{prop: 'userState', label: '在职状态', width: 100, sortable: true},
|
||||||
{prop: 'personType', label: '人员类型', sortable: true},
|
{prop: 'personType', label: '人员类型', width: 100, sortable: true},
|
||||||
{prop: 'preparedBy', label: '人员性质', sortable: true},
|
{prop: 'preparedBy', label: '人员性质', width: 100, sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', width: 170, sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', width: 170, sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true},
|
{prop: 'unionGroupName', label: '工会小组', width: 150, sortable: true},
|
||||||
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
||||||
{prop: 'marriage', label: '婚否', checked: 0},
|
{prop: 'marriage', label: '婚否', checked: 0},
|
||||||
{prop: 'education', label: '学历', checked: 0},
|
{prop: 'education', label: '学历', checked: 0},
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'userState', label: '在职状态', sortable: true},
|
{prop: 'userState', label: '在职状态', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true},
|
||||||
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
||||||
{prop: 'nation', label: '民族', checked: 0},
|
{prop: 'nation', label: '民族', checked: 0},
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'userState', label: '在职状态', sortable: true},
|
{prop: 'userState', label: '在职状态', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true},
|
||||||
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
{prop: 'campusName', label: '所属校区', sortable: true, checked: 0},
|
||||||
{prop: 'nation', label: '民族', checked: 0},
|
{prop: 'nation', label: '民族', checked: 0},
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'political', label: '政治面貌'},
|
{prop: 'political', label: '政治面貌'},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
{prop: 'retiredGroupName', label: '退休小组', sortable: true},
|
{prop: 'retiredGroupName', label: '退休小组', sortable: true},
|
||||||
{prop: 'retiredPartyBranchName', label: '退休党支部', sortable: true},
|
{prop: 'retiredPartyBranchName', label: '退休党支部', sortable: true},
|
||||||
@@ -193,4 +193,4 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<!--#
|
<!--#
|
||||||
}
|
}
|
||||||
#-->
|
#-->
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'political', label: '政治面貌'},
|
{prop: 'political', label: '政治面貌'},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
{prop: 'retiredGroupName', label: '退休小组', sortable: true},
|
{prop: 'retiredGroupName', label: '退休小组', sortable: true},
|
||||||
{prop: 'retiredPartyBranchName', label: '退休党支部', sortable: true},
|
{prop: 'retiredPartyBranchName', label: '退休党支部', sortable: true},
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'political', label: '政治面貌'},
|
{prop: 'political', label: '政治面貌'},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
{prop: 'retiredGroupName', label: '退休小组', sortable: true},
|
{prop: 'retiredGroupName', label: '退休小组', sortable: true},
|
||||||
{prop: 'retiredPartyBranchName', label: '退休党支部', sortable: true},
|
{prop: 'retiredPartyBranchName', label: '退休党支部', sortable: true},
|
||||||
@@ -196,4 +196,4 @@ layout("/layouts/platform.html"){
|
|||||||
|
|
||||||
<!--#
|
<!--#
|
||||||
}
|
}
|
||||||
#-->
|
#-->
|
||||||
|
|||||||
@@ -371,7 +371,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'education', label: '学历', sortable: true},
|
{prop: 'education', label: '学历', sortable: true},
|
||||||
{prop: 'maritalStatus', label: '单身状况', sortable: true},
|
{prop: 'maritalStatus', label: '单身状况', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
],
|
],
|
||||||
personTypeOptions: [],
|
personTypeOptions: [],
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ layout("/layouts/platform.html"){
|
|||||||
label="联系方式" prop="baseContactNumber">
|
label="联系方式" prop="baseContactNumber">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column align="center" header-align="center"
|
<el-table-column align="center" header-align="center"
|
||||||
label="已报人数" prop="signUpUserNum">
|
label="出行时间" prop="specificTime">
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="pageForm.theRapyRecuperationType!=3">
|
<template v-if="pageForm.theRapyRecuperationType!=3">
|
||||||
|
|||||||
@@ -0,0 +1,110 @@
|
|||||||
|
const basicForm = {
|
||||||
|
template: /*language=HTML*/ `
|
||||||
|
<el-dialog :visible.sync="dialogVisible" title="基础设置" :close-on-click-modal="false">
|
||||||
|
<div style="overflow-y: auto">
|
||||||
|
<el-form :model="formData" ref="formRef" :rules="formRules" label-width="150px">
|
||||||
|
<el-form-item label="类型" prop="category">
|
||||||
|
<el-radio-group v-model="formData.category" size="small">
|
||||||
|
<el-radio label="SURVEY" border>调查</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="所属福利" prop="welfareId">
|
||||||
|
<el-select filterable="true" placeholder="福利项目"
|
||||||
|
style="width: 99%" v-model="formData.welfareId">
|
||||||
|
<el-option :label="item.name" :value="item.id"
|
||||||
|
v-for="item in welfareProjectList"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="标题" prop="title">
|
||||||
|
<el-input v-model="formData.title" placeholder="请输入标题" maxlength="50"
|
||||||
|
show-word-limit></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="描述" prop="description">
|
||||||
|
<text-editor v-model="formData.description" :height="150"></text-editor>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="尾行内容" prop="lastContent">
|
||||||
|
<text-editor v-model="formData.lastContent" :height="150"></text-editor>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="开始时间" prop="startTime">
|
||||||
|
<el-date-picker v-model="formData.startTime" type="datetime" placeholder="选择日期时间"
|
||||||
|
style="width: 100%"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="结束时间" prop="endTime">
|
||||||
|
<el-date-picker v-model="formData.endTime" type="datetime" placeholder="选择日期时间"
|
||||||
|
style="width: 100%"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"></el-date-picker>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="onSubmit">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
`,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
formData: {
|
||||||
|
category: ''
|
||||||
|
},
|
||||||
|
formRules: {
|
||||||
|
category: [{ required: true, message: "请选择类型", trigger: "change" }],
|
||||||
|
title: [{ required: true, message: "请输入标题", trigger: "change" }],
|
||||||
|
startTime: [{ required: true, message: "请选择开始时间", trigger: "change" }],
|
||||||
|
endTime: [{ required: true, message: "请选择结束时间", trigger: "change" }],
|
||||||
|
},
|
||||||
|
welfareProjectList: [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onOpen(id) {
|
||||||
|
this.dialogVisible = true
|
||||||
|
if (id) {
|
||||||
|
$.post("/platform/welfare/evaluate/activity/findOne", { id }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.formData = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.formData = {}
|
||||||
|
}
|
||||||
|
this.queryWelfareProject(id)
|
||||||
|
},
|
||||||
|
onSubmit() {
|
||||||
|
this.$refs.formRef.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
$.post("/platform/welfare/evaluate/activity/save", this.formData).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success(res.msg)
|
||||||
|
this.dialogVisible = false
|
||||||
|
this.$emit("refresh", null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
queryWelfareProject(id){
|
||||||
|
$.post("/platform/welfare/evaluate/activity/queryProject", {
|
||||||
|
id: id
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.welfareProjectList = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,212 @@
|
|||||||
|
<!--#
|
||||||
|
layout("/layouts/platform.html"){
|
||||||
|
#-->
|
||||||
|
|
||||||
|
<div id="app">
|
||||||
|
<guava ref="guava">
|
||||||
|
<el-card shadow="never">
|
||||||
|
<div class="search">
|
||||||
|
<div class="search-item">
|
||||||
|
<div class="search-item-label">年度:</div>
|
||||||
|
<div class="search-item-option">
|
||||||
|
<el-date-picker placeholder="年度" style="width: 100%" type="year" v-model="pageForm.year" value-format="yyyy"></el-date-picker>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search-item">
|
||||||
|
<div class="search-item-label">标题:</div>
|
||||||
|
<div class="search-item-option">
|
||||||
|
<el-input placeholder="标题" v-model="pageForm.title" clearable></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search-item">
|
||||||
|
<div class="search-item-label">福利项目:</div>
|
||||||
|
<div class="search-item-option">
|
||||||
|
<el-select @change="doSearch" filterable="true"
|
||||||
|
placeholder="福利项目"
|
||||||
|
style="width: 100%;"
|
||||||
|
v-model="pageForm.projectId">
|
||||||
|
<el-option :label="item.name" :value="item.id"
|
||||||
|
v-for="item in welfareProjectList"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="search-query">
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<el-card shadow="never" class="mt10">
|
||||||
|
<table-tool :app="this" label="评价列表">
|
||||||
|
<template #func>
|
||||||
|
<el-button @click="$refs.basicFormRef.onOpen()" size="small" type="primary" class="mr5">新增</el-button>
|
||||||
|
</template>
|
||||||
|
</table-tool>
|
||||||
|
|
||||||
|
<el-table :data="tableData" ref="tableRef" @sort-change="pageOrder">
|
||||||
|
<el-table-column label="序号" width="50" type="index" :index="indexMethod"></el-table-column>
|
||||||
|
<el-table-column label="标题" prop="title" sortable></el-table-column>
|
||||||
|
<el-table-column label="所属福利" prop="welfareName" sortable></el-table-column>
|
||||||
|
<el-table-column label="类型" prop="category" sortable width="200">
|
||||||
|
<template scope="{row}">
|
||||||
|
<dict-tag :options="dict.type.ACTIVITY_QSV_CATEGORY" :value="row.category"></dict-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="开始时间" prop="startTime" sortable></el-table-column>
|
||||||
|
<el-table-column label="结束时间" prop="endTime" sortable></el-table-column>
|
||||||
|
<el-table-column label="操作" fixed="right" width="350px">
|
||||||
|
<template scope="{row}">
|
||||||
|
<el-button size="mini" type="primary" @click="openEdit(row)">编辑</el-button>
|
||||||
|
<el-button size="mini" type="primary" @click="openSendMsg(row)">推送通知</el-button>
|
||||||
|
<el-button size="mini" type="primary" @click="openSubject(row.id)">题目设置</el-button>
|
||||||
|
<el-button size="mini" type="danger" @click="onDelete(row.id)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!--#include("/layouts/pagination.html"){}#-->
|
||||||
|
</el-card>
|
||||||
|
|
||||||
|
<template #edit>
|
||||||
|
<subject-form ref="subjectFormRef" @refresh="$refs.guava.index();pageData()"></subject-form>
|
||||||
|
</template>
|
||||||
|
</guava>
|
||||||
|
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
:close-on-click-modal="false"
|
||||||
|
:visible.sync="sendMsgDialogVisible"
|
||||||
|
title="请在下方填写需要发送的内容"
|
||||||
|
width="50%"
|
||||||
|
>
|
||||||
|
<el-form :model="formData" label-width="80px" ref="sendForm">
|
||||||
|
|
||||||
|
<!-- <el-form-item
|
||||||
|
:rules="[{required: true, message: '请选择发送方式', trigger: ['blur', 'change']}]"
|
||||||
|
label="发送方式"
|
||||||
|
prop="sendTypes">
|
||||||
|
<el-checkbox-group size="medium" v-model="formData.sendTypes">
|
||||||
|
<el-checkbox border label="SMS">短信发送</el-checkbox>
|
||||||
|
<el-checkbox border label="WeChat">微信发送</el-checkbox>
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
-->
|
||||||
|
<el-form-item
|
||||||
|
:rules="[{required: true, message: '请输入发送标题', trigger: ['blur', 'change']}]"
|
||||||
|
label="发送标题"
|
||||||
|
prop="title">
|
||||||
|
<el-input
|
||||||
|
:rows="6"
|
||||||
|
placeholder="请输入发送标题"
|
||||||
|
v-model="formData.title">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item
|
||||||
|
:rules="[{required: true, message: '请选择发送内容', trigger: ['blur', 'change']}]"
|
||||||
|
label="发送内容"
|
||||||
|
prop="content">
|
||||||
|
<el-input
|
||||||
|
:rows="6"
|
||||||
|
placeholder="请输入内容"
|
||||||
|
type="textarea"
|
||||||
|
v-model="formData.content">
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<span class="dialog-footer" slot="footer">
|
||||||
|
<el-button @click="sendMsgDialogVisible = false">取 消</el-button>
|
||||||
|
<el-button @click="sendMsgToNotWelfareUsers" type="primary">确 定</el-button>
|
||||||
|
</span>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<basic-form ref="basicFormRef" @refresh="pageData"></basic-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
<!--#include('basicForm.js'){}#-->
|
||||||
|
<!--#include('subjectForm.js'){}#-->
|
||||||
|
new Vue({
|
||||||
|
el: "#app",
|
||||||
|
dicts: ["ACTIVITY_QSV_CATEGORY"],
|
||||||
|
mixins: [initTableMixins],
|
||||||
|
components: {
|
||||||
|
"basic-form": basicForm,
|
||||||
|
"subject-form": subjectForm
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
welfareProjectList: [],
|
||||||
|
sendMsgDialogVisible: false,
|
||||||
|
formData: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
openSendMsg(row){
|
||||||
|
this.$set(this.formData, "content", "校工会邀您参加《" + row.title + "》")
|
||||||
|
this.$set(this.formData, "id", row.id)
|
||||||
|
this.sendMsgDialogVisible = true
|
||||||
|
},
|
||||||
|
async sendMsgToNotWelfareUsers() {
|
||||||
|
const valid = await this.$refs['sendForm'].validate()
|
||||||
|
if (!valid) return
|
||||||
|
const confirm = await this.$confirm('您确定要向未参与的人员发送信息吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonTest: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
})
|
||||||
|
if (confirm === "confirm") {
|
||||||
|
const resp = await $.post('/platform/welfare/evaluate/activity/sendMsgToNotWelfareUsers', {
|
||||||
|
title: this.formData.title,
|
||||||
|
activityId: this.formData.id,
|
||||||
|
sendMsgValue: this.formData.content
|
||||||
|
})
|
||||||
|
if (resp.code === 0) {
|
||||||
|
this.sendMsgDialogVisible = false
|
||||||
|
this.$message.success(resp.msg)
|
||||||
|
} else {
|
||||||
|
this.$message.warning(resp.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openEdit(row) {
|
||||||
|
this.$refs.basicFormRef.onOpen(row.id)
|
||||||
|
},
|
||||||
|
openSubject(id) {
|
||||||
|
this.$refs.guava.edit()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.subjectFormRef.onOpen(id)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onDelete(id) {
|
||||||
|
this.$confirm("该操作将删除该评价下所有数据,您确认删除吗?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
}).then(() => {
|
||||||
|
$.post("/platform/welfare/evaluate/activity/delete", { id }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success("删除成功")
|
||||||
|
this.pageData()
|
||||||
|
} else {
|
||||||
|
this.$message.warning(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
async getWelfareProjectList() {
|
||||||
|
const resp = await $.get('/platform/welfare/project/statistics/single/welfareProjectList', {year: this.pageForm.year})
|
||||||
|
this.welfareProjectList = resp.data
|
||||||
|
},
|
||||||
|
},
|
||||||
|
async created() {
|
||||||
|
await this.getWelfareProjectList()
|
||||||
|
this.pageData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!--#
|
||||||
|
}
|
||||||
|
#-->
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
const optionImg = {
|
||||||
|
template: /*language=HTML*/ `
|
||||||
|
<el-dialog :visible="visible" title="设置图片" append-to-body width="700px">
|
||||||
|
<div style="background: #f7f8f9;text-align: center;border: solid 1px #d7d8d9;border-radius: 4px;">
|
||||||
|
<el-upload
|
||||||
|
action="/file_server/uploadFile"
|
||||||
|
:show-file-list="false"
|
||||||
|
:on-success="handleSuccess"
|
||||||
|
:before-upload="beforeUpload">
|
||||||
|
<img v-if="img" :src="img" class="avatar">
|
||||||
|
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
<div style="padding: 10px 0">
|
||||||
|
请上传图片
|
||||||
|
</div>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="onConfirm">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
`,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
visible: false,
|
||||||
|
img: null,
|
||||||
|
ext: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onOpen(img = null, ext) {
|
||||||
|
this.img = img
|
||||||
|
this.ext = ext
|
||||||
|
this.visible = true
|
||||||
|
},
|
||||||
|
handleSuccess(response, file, fileList) {
|
||||||
|
console.log(response)
|
||||||
|
console.log(file)
|
||||||
|
console.log(fileList)
|
||||||
|
if (response.code === 0) {
|
||||||
|
this.img = FILE_STREAM_PREVIEW_ADDRESS + "?id=" + response.data.filepath
|
||||||
|
// this.img = "/platform/sys/file/download?id=t38dmq4beuhrupqb54prl52t4u"
|
||||||
|
this.$message.success("图片上传成功")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeUpload(file) {},
|
||||||
|
onConfirm() {
|
||||||
|
this.$emit("confirm", {
|
||||||
|
img: this.img,
|
||||||
|
ext: this.ext
|
||||||
|
})
|
||||||
|
this.visible = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: /*language=CSS*/ `
|
||||||
|
.avatar-uploader .el-upload {
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader .el-upload:hover {
|
||||||
|
border-color: #409EFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #8c939d;
|
||||||
|
width: 178px;
|
||||||
|
height: 178px;
|
||||||
|
line-height: 178px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 178px;
|
||||||
|
height: 178px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
const setting = {
|
||||||
|
template:/*language=HTML*/`
|
||||||
|
<el-dialog :title="title" :visible.sync="visible" append-to-body width="50%">
|
||||||
|
<el-form :model="formData" label-width="80px">
|
||||||
|
<el-form-item label="链接" prop="link">
|
||||||
|
<el-input maxlength="255" placeholder="" v-model="formData.link"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="详情" prop="description">
|
||||||
|
<text-editor v-model="formData.description"></text-editor>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="visible = false">取 消</el-button>
|
||||||
|
<el-button type="primary" @click="onConfirm">确 定</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
`,
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
title: '设置',
|
||||||
|
visible: false,
|
||||||
|
formData:{},
|
||||||
|
ext: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
onOpen(option,ext){
|
||||||
|
console.log(option)
|
||||||
|
this.formData = { ...option }
|
||||||
|
this.ext = ext
|
||||||
|
this.visible = true
|
||||||
|
},
|
||||||
|
onConfirm(){
|
||||||
|
this.$emit('confirm', { option:this.formData,ext:this.ext })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,469 @@
|
|||||||
|
<!--#include('optionImg.js'){}#-->
|
||||||
|
<!--#include('setting.js'){}#-->
|
||||||
|
|
||||||
|
const subjectForm = {
|
||||||
|
template: /*language=HTML*/ `
|
||||||
|
<div class="subject-form-dialog">
|
||||||
|
<el-form ref="form" :model="formData" :rules="formRules" label-width="120px">
|
||||||
|
<div style="min-height:50vh;overflow-y: auto">
|
||||||
|
<draggable v-model="subjects" handle=".drag-handler">
|
||||||
|
<transition-group>
|
||||||
|
<div v-for="(subject, subjectIndex) in subjects" :key="subject.id" class="subject-item">
|
||||||
|
<div class="subject-header">
|
||||||
|
<div style="display: flex; align-items: center;">
|
||||||
|
<i class="el-icon-rank drag-handler"></i>
|
||||||
|
<span style="font-weight: bold; margin-right: 10px;">第 {{subjectIndex + 1}} 题</span>
|
||||||
|
<el-input
|
||||||
|
v-model="subject.title"
|
||||||
|
placeholder="请输入题目"
|
||||||
|
style="flex: 1">
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="subject-meta">
|
||||||
|
<div>
|
||||||
|
题目类型:
|
||||||
|
<el-select
|
||||||
|
v-model="subject.type"
|
||||||
|
@change="subjectTypeChange(subject, subjectIndex)"
|
||||||
|
placeholder="请选择题目类型"
|
||||||
|
style="width: 200px;">
|
||||||
|
<el-option label="单选题" value="radio">
|
||||||
|
<i class="el-icon-circle-check subject-type-icon"></i>单选题
|
||||||
|
</el-option>
|
||||||
|
<el-option label="多选题" value="checkbox">
|
||||||
|
<i class="el-icon-check subject-type-icon"></i>多选题
|
||||||
|
</el-option>
|
||||||
|
<el-option label="填空题" value="text" v-if="activity.category!=='QUIZ'">
|
||||||
|
<i class="el-icon-edit subject-type-icon"></i>填空题
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div v-if="subject.type === 'checkbox'">
|
||||||
|
最大选择数:
|
||||||
|
<el-input-number v-model="subject.maxMulti" placeholder="最多可选数量"></el-input>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<draggable v-model="subject.options" handle=".option-drag-handle"
|
||||||
|
v-if="subject.type !== 'text'">
|
||||||
|
<transition-group>
|
||||||
|
<div v-for="(option, optionIndex) in subject.options"
|
||||||
|
:key="option.id"
|
||||||
|
class="option-item">
|
||||||
|
<i class="el-icon-rank option-drag-handle"></i>
|
||||||
|
<div class="option-content">
|
||||||
|
<el-input
|
||||||
|
v-model="option.text"
|
||||||
|
:placeholder="'选项'+optionIndex + 1">
|
||||||
|
<template slot="prepend">选项{{optionIndex + 1}}</template>
|
||||||
|
</el-input>
|
||||||
|
<div v-if="option.imageUrl" style="margin-top: 10px;">
|
||||||
|
<img :src="option.imageUrl" class="image-preview" alt="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="option-tools">
|
||||||
|
<template v-if="activity.category!=='QUIZ'">
|
||||||
|
<div class="option-img-box" v-if="option.imgUrl">
|
||||||
|
<i class="el-icon-remove"
|
||||||
|
@click="removeOptionImg(subjectIndex,optionIndex)"></i>
|
||||||
|
<img :src="option.imgUrl" alt=""
|
||||||
|
@click="openOptionImg(subjectIndex,optionIndex,option)">
|
||||||
|
</div>
|
||||||
|
<i v-if="!option.imgUrl" class="el-icon-picture-outline"
|
||||||
|
style="font-size: 40px;cursor: pointer;" title="上传图片"
|
||||||
|
@click="openOptionImg(subjectIndex,optionIndex,option)"></i>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-switch
|
||||||
|
v-if="subject.type=='radio'"
|
||||||
|
v-model="option.isOpenContent"
|
||||||
|
active-text="内容填写">
|
||||||
|
</el-switch>
|
||||||
|
|
||||||
|
<template v-if="option.isOpenContent == true">
|
||||||
|
<el-tooltip class="item" effect="dark" content="您的其他建议:(前缀就是指这一段文字)" placement="top-start">
|
||||||
|
<el-input
|
||||||
|
style="width: 200px"
|
||||||
|
v-model="option.contentPrefix"
|
||||||
|
placeholder="内容前缀">
|
||||||
|
</el-input>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-setting"
|
||||||
|
size="mini"
|
||||||
|
@click="openSetting(subjectIndex,optionIndex,option)">
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="mini"
|
||||||
|
@click="removeOption(subject, optionIndex)">
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</transition-group>
|
||||||
|
</draggable>
|
||||||
|
<div class="subject-toolbar">
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
v-if="subject.type !== 'text'"
|
||||||
|
type="primary"
|
||||||
|
icon="el-icon-plus"
|
||||||
|
size="small"
|
||||||
|
@click="addOption(subject)">
|
||||||
|
添加选项
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<el-button
|
||||||
|
type="danger"
|
||||||
|
icon="el-icon-delete"
|
||||||
|
size="small"
|
||||||
|
@click="removeSubject(subjectIndex)">
|
||||||
|
删除题目
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</transition-group>
|
||||||
|
</draggable>
|
||||||
|
<el-empty description="描述文字" v-if="subjects.length===0"></el-empty>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<div style="border-top: 1px solid var(--border-color-lighter);padding: 12px;text-align: right;">
|
||||||
|
<el-button type="primary" icon="el-icon-plus" @click="addSubject">
|
||||||
|
添加题目
|
||||||
|
</el-button>
|
||||||
|
<el-button type="primary" icon="el-icon-check" @click="saveQuestionnaire">
|
||||||
|
保存题目
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<option-img ref="optionImgRef" @confirm="onOptionImgConfirm"></option-img>
|
||||||
|
<setting ref="settingRef" @confirm="onSettingConfirm"></setting>
|
||||||
|
</div>
|
||||||
|
`,
|
||||||
|
components: {
|
||||||
|
'option-img': optionImg,
|
||||||
|
'setting': setting
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
id: null,
|
||||||
|
visible: false,
|
||||||
|
formData: {},
|
||||||
|
subjects: [],
|
||||||
|
previewDialogVisible: false,
|
||||||
|
activity: {},
|
||||||
|
formRules: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onOpen(id) {
|
||||||
|
this.visible = true
|
||||||
|
if (id) {
|
||||||
|
this.id = id
|
||||||
|
$.post("/platform/welfare/evaluate/activity/findOne", {id}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.activity = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
$.post("/platform/welfare/evaluate/activity/listSubjects", {activityId: id}).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.subjects = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//生成随机id
|
||||||
|
generateId() {
|
||||||
|
return Date.now() + Math.random().toString(36).substr(2, 9)
|
||||||
|
},
|
||||||
|
|
||||||
|
//添加题目
|
||||||
|
addSubject() {
|
||||||
|
this.subjects.push({
|
||||||
|
id: this.generateId(),
|
||||||
|
title: "",
|
||||||
|
hint: "",
|
||||||
|
type: "radio",
|
||||||
|
score: 0,
|
||||||
|
displayDate: "",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
id: this.generateId(),
|
||||||
|
text: "选项1",
|
||||||
|
hint: "",
|
||||||
|
imgUrl: null,
|
||||||
|
isCorrect: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: this.generateId(),
|
||||||
|
text: "选项2",
|
||||||
|
hint: "",
|
||||||
|
imgUrl: null,
|
||||||
|
isCorrect: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//题目类型切换
|
||||||
|
subjectTypeChange(subject, subjectIndex){
|
||||||
|
if(subject.type==='text'){
|
||||||
|
subject.options = []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
//删除题目
|
||||||
|
removeSubject(index) {
|
||||||
|
this.$confirm("确认删除该题目?", "提示", {
|
||||||
|
confirmButtonText: "确定",
|
||||||
|
cancelButtonText: "取消",
|
||||||
|
type: "warning"
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.subjects.splice(index, 1)
|
||||||
|
this.$message.success("删除成功")
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//添加选项
|
||||||
|
addOption(subject) {
|
||||||
|
subject.options.push({
|
||||||
|
id: this.generateId(),
|
||||||
|
text: "选项" + subject.options.length + 1,
|
||||||
|
hint: "",
|
||||||
|
imgUrl: null,
|
||||||
|
isCorrect: false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//删除选项
|
||||||
|
removeOption(subject, optionIndex) {
|
||||||
|
subject.options.splice(optionIndex, 1)
|
||||||
|
},
|
||||||
|
|
||||||
|
//打开选项上传图片
|
||||||
|
openOptionImg(subjectIndex, optionIndex, option) {
|
||||||
|
this.$refs.optionImgRef.onOpen(option.imgUrl, {
|
||||||
|
subjectIndex,
|
||||||
|
optionIndex
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//选项图片上传成功回调
|
||||||
|
onOptionImgConfirm({img, ext}) {
|
||||||
|
this.$set(this.subjects[ext.subjectIndex].options[ext.optionIndex], "imgUrl", img)
|
||||||
|
},
|
||||||
|
|
||||||
|
//删除选项图片
|
||||||
|
removeOptionImg(subjectIndex, optionIndex){
|
||||||
|
this.$set(this.subjects[subjectIndex].options[optionIndex], "imgUrl", null)
|
||||||
|
console.log(this.subjects[subjectIndex])
|
||||||
|
},
|
||||||
|
|
||||||
|
//打开选项设置
|
||||||
|
openSetting(subjectIndex, optionIndex, option){
|
||||||
|
this.$refs.settingRef.onOpen(option, {
|
||||||
|
subjectIndex,
|
||||||
|
optionIndex
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
//选项设置确认
|
||||||
|
onSettingConfirm({option, ext}){
|
||||||
|
this.subjects[ext.subjectIndex].options[ext.optionIndex] = option
|
||||||
|
},
|
||||||
|
|
||||||
|
//保存
|
||||||
|
saveQuestionnaire() {
|
||||||
|
$
|
||||||
|
.post("/platform/welfare/evaluate/activity/saveSubjects", {
|
||||||
|
activityId: this.id,
|
||||||
|
subjects: JSON.stringify(this.subjects)
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.visible = false
|
||||||
|
this.$message.success(res.msg)
|
||||||
|
this.$emit("refresh", null)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: /*language=CSS*/ `
|
||||||
|
/*.subject-form-dialog,.subject-form-dialog .el-dialog__body {*/
|
||||||
|
/* background: rgb(248, 249, 250);*/
|
||||||
|
/*}*/
|
||||||
|
|
||||||
|
.questionnaire-editor {
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-header {
|
||||||
|
background: white;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject-item {
|
||||||
|
background: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 25px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject-item:hover {
|
||||||
|
box-shadow: 0 4px 20px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
/*transform: translateY(-1px);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject-header {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 15px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject-toolbar {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 15px;
|
||||||
|
padding-top: 15px;
|
||||||
|
border-top: 1px solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
background: white;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toolbar-btn {
|
||||||
|
margin: 5px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-drag-handle {
|
||||||
|
cursor: move;
|
||||||
|
margin-right: 10px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-content {
|
||||||
|
flex-grow: 1;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-tools {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.preview-dialog {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.date-visible {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 15px;
|
||||||
|
margin-top: 15px;
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.image-preview {
|
||||||
|
max-width: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
margin-top: 10px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.drag-handler {
|
||||||
|
cursor: move;
|
||||||
|
color: #909399;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-info {
|
||||||
|
color: #909399;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subject-type-icon {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.option-img-box{
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-img-box:hover .el-icon-remove {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-img-box img{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-img-box .el-icon-remove{
|
||||||
|
position: absolute;
|
||||||
|
top: -7px;
|
||||||
|
right: -7px;
|
||||||
|
color: red;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-img-box .el-icon-remove:hover{
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
`
|
||||||
|
}
|
||||||
+55
-93
@@ -35,6 +35,18 @@ layout("/layouts/platform.html"){
|
|||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="search-item">
|
||||||
|
<div class="search-item-label">套餐:</div>
|
||||||
|
<div class="search-item-option">
|
||||||
|
<el-select clearable placeholder="请选择所选福利" style="width: 100%"
|
||||||
|
v-model="pageForm.optionId">
|
||||||
|
<el-option :label="item.optionName" :value="item.id"
|
||||||
|
v-for="item in welfareOptions"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="search-item">
|
<div class="search-item">
|
||||||
<div class="search-item-label">职工信息:</div>
|
<div class="search-item-label">职工信息:</div>
|
||||||
<div class="search-item-option">
|
<div class="search-item-option">
|
||||||
@@ -42,8 +54,8 @@ layout("/layouts/platform.html"){
|
|||||||
style="width: 100%" v-model="pageForm.searchKeyword">
|
style="width: 100%" v-model="pageForm.searchKeyword">
|
||||||
<el-select slot="prepend" style="width: 80px;"
|
<el-select slot="prepend" style="width: 80px;"
|
||||||
v-model="pageForm.searchName">
|
v-model="pageForm.searchName">
|
||||||
<el-option label="姓名" value="we.userName"></el-option>
|
<el-option label="姓名" value="username"></el-option>
|
||||||
<el-option label="工号" value="we.loginName"></el-option>
|
<el-option label="工号" value="loginname"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
@@ -79,46 +91,19 @@ layout("/layouts/platform.html"){
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="search-item">
|
|
||||||
<div class="search-item-label">评分:</div>
|
|
||||||
<div class="search-item-option">
|
|
||||||
<el-select clearable filterable placeholder="请选择"
|
|
||||||
style="width: 100%"
|
|
||||||
v-model="pageForm.evaluateScore">
|
|
||||||
<el-option
|
|
||||||
:key="item.code"
|
|
||||||
:label="item.name"
|
|
||||||
:value="item.code"
|
|
||||||
v-for="item in evaluateScores">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="search-item">
|
|
||||||
<div class="search-item-label">套餐:</div>
|
|
||||||
<div class="search-item-option">
|
|
||||||
<el-select clearable placeholder="请选择所选福利" style="width: 100%"
|
|
||||||
v-model="pageForm.optionId">
|
|
||||||
<el-option :label="item.optionName" :value="item.id"
|
|
||||||
v-for="item in welfareOptions"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="search-query">
|
<div class="search-query">
|
||||||
<el-button @click="doSearch" icon="el-icon-search" type="primary">搜索
|
<el-button @click="doSearch" icon="el-icon-search" type="primary">搜索
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="mt10" shadow="never">
|
<el-card class="mt10" shadow="never">
|
||||||
<table-tool :app="this" label="福利项目">
|
<table-tool :app="this" label="福利项目">
|
||||||
<template #func>
|
<template #func>
|
||||||
|
<el-button @click="exportXlsx" size="small" type="primary">导出xlsx</el-button>
|
||||||
|
<el-button @click="dataReport" size="small" type="primary">查看分析</el-button>
|
||||||
</template>
|
</template>
|
||||||
</table-tool>
|
</table-tool>
|
||||||
|
|
||||||
@@ -140,59 +125,31 @@ layout("/layouts/platform.html"){
|
|||||||
header-align="center"
|
header-align="center"
|
||||||
min-width="100px" show-overflow-tooltip
|
min-width="100px" show-overflow-tooltip
|
||||||
v-for="column in tableColumns">
|
v-for="column in tableColumns">
|
||||||
<template scope="{row}" v-if="column.prop=='evaluateScore'">
|
|
||||||
{{ row.evaluateScore }}分
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column align="center" header-align="center" label="操作"
|
|
||||||
prop="userOnline" width="150px">
|
|
||||||
<template scope="{row}">
|
|
||||||
<el-button @click="openEvaluate(row)" size="mini" type="primary">查看评价
|
|
||||||
</el-button>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<!-- <el-table-column align="center" header-align="center" label="操作"-->
|
||||||
|
<!-- prop="userOnline" width="150px">-->
|
||||||
|
<!-- <template scope="{row}">-->
|
||||||
|
<!-- <el-button @click="openEvaluate(row)" size="mini" type="primary">查看评价</el-button>-->
|
||||||
|
<!-- </template>-->
|
||||||
|
<!-- </el-table-column>-->
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
|
<!--#include("/layouts/pagination.html"){}#-->
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #edit>
|
||||||
|
|
||||||
|
</template>
|
||||||
</guava>
|
</guava>
|
||||||
|
|
||||||
<el-dialog
|
<report ref="reportRef"></report>
|
||||||
:close-on-click-modal="false"
|
|
||||||
:visible.sync="evaluateDialogVisible"
|
|
||||||
title="评分内容"
|
|
||||||
width="30%">
|
|
||||||
<el-form :model="formData" label-width="80px" ref="form">
|
|
||||||
<el-form-item :rules="[{ required: true, message: ''}]" label="评分">
|
|
||||||
<div style="position: absolute; top: 20%;">
|
|
||||||
<el-rate disabled
|
|
||||||
show-score text-color="#ff9900"
|
|
||||||
v-model="viewData.evaluateScore"></el-rate>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="评价">
|
|
||||||
<el-input disabled
|
|
||||||
maxlength="100"
|
|
||||||
placeholder="请输入评价"
|
|
||||||
rows="5"
|
|
||||||
show-word-limit
|
|
||||||
type="textarea"
|
|
||||||
v-model="viewData.evaluateText"
|
|
||||||
>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<span class="dialog-footer" slot="footer">
|
|
||||||
<el-button @click="evaluateDialogVisible = false" type="primary">关 闭</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
<!--#include('report.js'){}#-->
|
||||||
|
|
||||||
const vue = new Vue({
|
const vue = new Vue({
|
||||||
el: '#app',
|
el: '#app',
|
||||||
mixins: [initTableMixins],
|
mixins: [initTableMixins],
|
||||||
@@ -202,32 +159,25 @@ layout("/layouts/platform.html"){
|
|||||||
units: [],
|
units: [],
|
||||||
evaluateDialogVisible: false,
|
evaluateDialogVisible: false,
|
||||||
welfareProjectList: [],
|
welfareProjectList: [],
|
||||||
tableColumns: [
|
tableColumns: [],
|
||||||
{prop: 'loginName', label: '工号'},
|
|
||||||
{prop: 'userName', label: '姓名'},
|
|
||||||
{prop: 'unitname', label: '单位'},
|
|
||||||
{prop: 'unionname', label: '工会'},
|
|
||||||
{prop: 'userState', label: '在职状态'},
|
|
||||||
{prop: 'personType', label: '人员类型'},
|
|
||||||
{prop: 'evaluateScore', label: '评分', sortable: true},
|
|
||||||
{prop: 'evaluateText', label: '评价'},
|
|
||||||
],
|
|
||||||
pageForm: {
|
pageForm: {
|
||||||
searchName: "we.userName",
|
searchName: "username",
|
||||||
year: new Date().getFullYear().toString()
|
year: new Date().getFullYear().toString()
|
||||||
},
|
},
|
||||||
viewData: {},
|
viewData: {},
|
||||||
evaluateScores: [
|
|
||||||
{name: "1分", code: 1},
|
|
||||||
{name: "2分", code: 2},
|
|
||||||
{name: "3分", code: 3},
|
|
||||||
{name: "4分", code: 4},
|
|
||||||
{name: "5分", code: 5},
|
|
||||||
],
|
|
||||||
welfareOptions: [],
|
welfareOptions: [],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
report
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
dataReport(){
|
||||||
|
this.$refs.reportRef.onOpen(this.pageForm.projectId)
|
||||||
|
},
|
||||||
|
async exportXlsx() {
|
||||||
|
this.$downLoad("/platform/welfare/evaluate/statistics/exportXlsx", this.pageForm)
|
||||||
|
},
|
||||||
openEvaluate(row) {
|
openEvaluate(row) {
|
||||||
this.viewData = {
|
this.viewData = {
|
||||||
projectId: row.id,
|
projectId: row.id,
|
||||||
@@ -264,7 +214,19 @@ layout("/layouts/platform.html"){
|
|||||||
const resp = await $.post(loc() + '/welfareOptions', {projectId: this.pageForm.projectId})
|
const resp = await $.post(loc() + '/welfareOptions', {projectId: this.pageForm.projectId})
|
||||||
this.welfareOptions = resp.data
|
this.welfareOptions = resp.data
|
||||||
},
|
},
|
||||||
|
pageData() {
|
||||||
|
$.post("/platform/welfare/evaluate/statistics/pageData", this.pageForm).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.tableColumns = res.data.tableColumns
|
||||||
|
this.tableData = res.data.tableData.list
|
||||||
|
this.pageForm.totalCount = res.data.tableData.totalCount
|
||||||
|
} else {
|
||||||
|
this.tableColumns = []
|
||||||
|
this.tableData = []
|
||||||
|
this.pageForm.totalCount = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
await this.getWelfareProjectList()
|
await this.getWelfareProjectList()
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
const report = {
|
||||||
|
/*language=HTML*/
|
||||||
|
template: `
|
||||||
|
<el-dialog title="分析报告" :visible.sync="dialogVisible" width="50%">
|
||||||
|
<el-row type="flex" justify="end" class="mb10">
|
||||||
|
<el-button type="primary" size="small" icon="el-icon-download" @click="exportReportXlsx">导出xlsx</el-button>
|
||||||
|
</el-row>
|
||||||
|
<div v-for="(subject,subjectIndex) in subjects" class="subject">
|
||||||
|
<div>
|
||||||
|
<div class="title">
|
||||||
|
第{{subjectIndex+1}}题: {{subject.title}}
|
||||||
|
<span class="type" v-if="subject.type==='text'">[填空题]
|
||||||
|
<el-button type="text" @click="openDetailText(subject.id)">详情</el-button>
|
||||||
|
</span>
|
||||||
|
<span class="type" v-else-if="subject.type==='radio'">[单选题]</span>
|
||||||
|
<span class="type" v-else-if="subject.type==='text'">[多选题]</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="subject.type==='text'">
|
||||||
|
{{subject.texts.join('、')}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-else-if="subject.type==='radio' || subject.type==='checkbox'">
|
||||||
|
<el-table :data="subject.options" size="small">
|
||||||
|
<el-table-column label="选项" prop="text"></el-table-column>
|
||||||
|
<el-table-column label="小计" prop="selectCount" width="100"></el-table-column>
|
||||||
|
<el-table-column label="比例" width="500">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-progress
|
||||||
|
:percentage="Math.round(scope.row.selectCount / subject.selectTotal * 100)"></el-progress>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="详情" width="100px">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-button type="text" @click="openDetail(subject.id,row.id)">详情</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-dialog title="选择详情" :visible.sync="optionVisible" width="50%" append-to-body>
|
||||||
|
<el-table :data="optionUsers" size="small">
|
||||||
|
<el-table-column label="姓名" prop="userName"></el-table-column>
|
||||||
|
<el-table-column label="工号" prop="loginName"></el-table-column>
|
||||||
|
<el-table-column label="单位" prop="unitName"></el-table-column>
|
||||||
|
<el-table-column label="分工会" prop="unionName"></el-table-column>
|
||||||
|
<el-table-column label="选择时间" prop="attemptDate"></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
</el-dialog>
|
||||||
|
`,
|
||||||
|
dicts: ["ACTIVITY_QSV_CATEGORY"],
|
||||||
|
mixins: [initTableMixins],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
dialogVisible: false,
|
||||||
|
activityId: null,
|
||||||
|
report: null,
|
||||||
|
subjects: [],
|
||||||
|
optionVisible: false,
|
||||||
|
optionUsers: [],
|
||||||
|
welfareId: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onOpen(welfareId) {
|
||||||
|
this.welfareId = welfareId
|
||||||
|
this.dialogVisible = true
|
||||||
|
$.post("/platform/welfare/evaluate/statistics/dataReport", { welfareId }).then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
debugger
|
||||||
|
this.subjects = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
openDetailText(id){
|
||||||
|
|
||||||
|
},
|
||||||
|
openDetail(subjectId, optionId) {
|
||||||
|
console.log(subjectId)
|
||||||
|
console.log(optionId)
|
||||||
|
$.post("/platform/qsv/survey/selectOptionUsers", {
|
||||||
|
activityId: this.activityId,
|
||||||
|
subjectId,
|
||||||
|
optionId
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.optionVisible = true
|
||||||
|
this.optionUsers = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
exportReportXlsx(){
|
||||||
|
this.$downLoad("/platform/welfare/evaluate/statistics/exportReportXlsx", { welfareId: this.welfareId })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
style: /*language=CSS*/ `
|
||||||
|
.subject{
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.subject .title{
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
.subject .type{
|
||||||
|
color: #a6a6a6;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
@@ -110,7 +110,7 @@ let commonColumns = [
|
|||||||
{prop: 'userState', label: '在职状态', sortable: true, width: "100"},
|
{prop: 'userState', label: '在职状态', sortable: true, width: "100"},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0},
|
||||||
// {prop: 'isReceive', label: '是否领取', sortable: true}
|
// {prop: 'isReceive', label: '是否领取', sortable: true}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ layout("/layouts/platform.html"){
|
|||||||
{prop: 'userState', label: '在职状态', sortable: true},
|
{prop: 'userState', label: '在职状态', sortable: true},
|
||||||
{prop: 'unionname', label: '所属工会', sortable: true},
|
{prop: 'unionname', label: '所属工会', sortable: true},
|
||||||
{prop: 'unitname', label: '所属单位', sortable: true},
|
{prop: 'unitname', label: '所属单位', sortable: true},
|
||||||
{prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
// {prop: 'threeUnitName', label: '所在科室', sortable: true, checked: 0},
|
||||||
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0}
|
{prop: 'unionGroupName', label: '工会小组', sortable: true, checked: 0}
|
||||||
],
|
],
|
||||||
welfareUnits: [],
|
welfareUnits: [],
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ layout("/layouts/platform.html"){
|
|||||||
type="primary">
|
type="primary">
|
||||||
查看物流
|
查看物流
|
||||||
</el-button>-->
|
</el-button>-->
|
||||||
<el-button :disabled="!row.courierNumber" @click="openEvaluate(row)"
|
<el-button v-if="row.evaId" @click="openEvaluate(row)"
|
||||||
size="mini"
|
size="mini"
|
||||||
type="primary">
|
type="primary">
|
||||||
评价
|
评价
|
||||||
@@ -354,8 +354,11 @@ layout("/layouts/platform.html"){
|
|||||||
</el-card>
|
</el-card>
|
||||||
</el-drawer>
|
</el-drawer>
|
||||||
|
|
||||||
<!--快递物流信息-->
|
<!-- 快递物流信息 -->
|
||||||
<courier-number-info ref="courierNumberInfo"></courier-number-info>
|
<courier-number-info ref="courierNumberInfo"></courier-number-info>
|
||||||
|
|
||||||
|
<!-- qrcode -->
|
||||||
|
<open-qr-code :url="activityH5Url" ref="openQRCode"></open-qr-code>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
const vue = new Vue({
|
const vue = new Vue({
|
||||||
@@ -400,10 +403,12 @@ layout("/layouts/platform.html"){
|
|||||||
expressDrawer: false,
|
expressDrawer: false,
|
||||||
logisticsTrace: {},
|
logisticsTrace: {},
|
||||||
|
|
||||||
|
activityH5Url: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'courier-number-info': httpVueLoader('/components/welfare/CourierNumberInfo.vue?v=' + new Date().getTime())
|
'courier-number-info': httpVueLoader('/components/welfare/CourierNumberInfo.vue?v=' + new Date().getTime()),
|
||||||
|
"open-qr-code": httpVueLoader("/components/plugins/OpenQRCode.vue?v=" + new Date().getTime())
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
//查看快递单号
|
//查看快递单号
|
||||||
@@ -468,12 +473,13 @@ layout("/layouts/platform.html"){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
async openEvaluate(row) {
|
async openEvaluate(row) {
|
||||||
await this.getUserSelection(row.id)
|
this.$refs.openQRCode.openCode("/platform/h5/welfare/evaluate?id=" + row.evaId, "该评价只支持手机端,请使用钉钉扫描二维码!")
|
||||||
if (this.userSelection && this.userSelection.length > 0) {
|
// await this.getUserSelection(row.id)
|
||||||
await this.finOneWelfareEvaluate(row.id, this.userSelection[0].selectOptionId)
|
// if (this.userSelection && this.userSelection.length > 0) {
|
||||||
}
|
// await this.finOneWelfareEvaluate(row.id, this.userSelection[0].selectOptionId)
|
||||||
|
// }
|
||||||
this.evaluateDialogVisible = true
|
//
|
||||||
|
// this.evaluateDialogVisible = true
|
||||||
},
|
},
|
||||||
async getProjectInfo(id) {
|
async getProjectInfo(id) {
|
||||||
const resp = await $.get('/platform/welfare/common/findOne', {projectId: id})
|
const resp = await $.get('/platform/welfare/common/findOne', {projectId: id})
|
||||||
|
|||||||
Reference in New Issue
Block a user