查询的时间段改成两个字段;会员数据更新记录增加导出;场地预约增加单位预约和审核流程
This commit is contained in:
@@ -56,6 +56,11 @@ public class ActivitySiteReserve extends BaseModel {
|
||||
@ColDefine(type = ColType.VARCHAR, width = 50)
|
||||
private String reserve_person_unit;
|
||||
|
||||
@Column
|
||||
@Comment("申请时所属单位ID,单位预约审核按此快照匹配负责人")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 32)
|
||||
private String reserveUnitId;
|
||||
|
||||
@Column
|
||||
@Comment("预约人联系方式")
|
||||
@ColDefine(type = ColType.VARCHAR, width = 20)
|
||||
@@ -137,7 +142,7 @@ public class ActivitySiteReserve extends BaseModel {
|
||||
private String joinUser;
|
||||
|
||||
@Column
|
||||
@Comment("预约类型(1.个人预约,2.分工会预约,3.协会预约)")
|
||||
@Comment("预约类型(1.个人预约,2.分工会预约,3.协会预约,4.单位预约)")
|
||||
@ColDefine(type = ColType.INT, width = 10)
|
||||
private Integer reserve_type;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
||||
*/
|
||||
@IocBean(args = {"refer:dao"})
|
||||
public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
public static final int UNION = 4000, CLUB = 4010, SCHOOL = 4020, PASS = 4030, REJECT = 4040, CANCEL = 4050;
|
||||
public static final int UNION = 4000, CLUB = 4010, SCHOOL = 4020, PASS = 4030, REJECT = 4040, CANCEL = 4050, UNIT = 4060;
|
||||
/** 校工会节点统一按专属场地管理员角色分配待办和校验审核资格。 */
|
||||
private static final String SCHOOL_REVIEW_ROLE = "SchoolUnionActivityVenueAdmin";
|
||||
/** 兼容现有日历组件的状态字段;名称统一读取 state,不再读取 audit_state。 */
|
||||
@@ -52,24 +52,25 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
+ "order by c.name").setParam("uid", uid()));
|
||||
}
|
||||
|
||||
/** 无入参,返回当前申请人的id/name所属分工会;采用与提交相同的user视图组织来源,未配置时返回空字符串。 */
|
||||
/** 无入参,返回当前申请人的id/name所属分工会及unitId/unitName所属单位;采用与提交相同的user视图组织来源,未配置时返回空字符串。 */
|
||||
public NutMap myBookingUnion() {
|
||||
List<NutMap> rows=listMap(Sqls.create("select u.unionid id,un.unionname name from `user` u left join sys_union un on un.id=u.unionid where u.id=@id")
|
||||
List<NutMap> rows=listMap(Sqls.create("select u.unionid id,un.unionname name,u.unitid unitId,u.unitname unitName from `user` u left join sys_union un on un.id=u.unionid where u.id=@id")
|
||||
.setParam("id",uid()));
|
||||
return rows.isEmpty() ? NutMap.NEW().setv("id","").setv("name","") : rows.get(0);
|
||||
return rows.isEmpty() ? NutMap.NEW().setv("id","").setv("name","").setv("unitId","").setv("unitName","") : rows.get(0);
|
||||
}
|
||||
|
||||
/** 预约类型 1 历史个人、2 分工会、3 协会,返回应进入的首个状态 ID。 */
|
||||
/** 预约类型 1 历史个人、2 分工会、3 协会、4 单位,返回应进入的首个状态 ID。 */
|
||||
public int firstState(Integer type) {
|
||||
if (Integer.valueOf(1).equals(type)) return UNION;
|
||||
if (Integer.valueOf(2).equals(type)) return UNION;
|
||||
if (Integer.valueOf(3).equals(type)) return CLUB;
|
||||
if (Integer.valueOf(4).equals(type)) return UNIT;
|
||||
throw new IllegalArgumentException("请选择有效的预约类型");
|
||||
}
|
||||
|
||||
/** 按节点角色及组织范围查实际审核人;不允许空组织退化为全校范围。 */
|
||||
private List<NutMap> reviewers(int node, ActivitySiteReserve booking) {
|
||||
String role = node == UNION ? "gh01" : node == CLUB ? "club01" : SCHOOL_REVIEW_ROLE;
|
||||
String role = node == UNION ? "gh01" : node == CLUB ? "club01" : node == UNIT ? "unit_manger" : SCHOOL_REVIEW_ROLE;
|
||||
String filter = "";
|
||||
if (node == UNION) {
|
||||
if (Strings.isBlank(booking.getReserve_person_unionid())) throw new IllegalArgumentException("申请人未关联分工会,请先完善所属分工会");
|
||||
@@ -77,11 +78,15 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
} else if (node == CLUB) {
|
||||
if (Strings.isBlank(booking.getClubId())) throw new IllegalArgumentException("请选择所属协会");
|
||||
filter = " and ur.stid=@org";
|
||||
} else if (node == UNIT) {
|
||||
// 负责人必须绑定申请时的单位,不能使用其任职单位或仅凭角色放行。
|
||||
if (Strings.isBlank(booking.getReserveUnitId())) throw new IllegalArgumentException("申请人未关联单位,请先完善所属单位");
|
||||
filter = " and ur.unitid=@org and coalesce(r.disabled,0)=0";
|
||||
} else if (node != SCHOOL) throw new IllegalArgumentException("当前节点不允许审核");
|
||||
return listMap(Sqls.create("select distinct u.id,u.loginname from sys_user_role ur join sys_role r on r.id=ur.roleId "
|
||||
+ "join sys_user u on u.id=ur.userId where r.code=@role and coalesce(u.disabled,0)=0 "
|
||||
+ "and coalesce(u.delFlag,0)=0" + filter).setParam("role", role)
|
||||
.setParam("org", node == UNION ? booking.getReserve_person_unionid() : booking.getClubId()));
|
||||
.setParam("org", node == UNION ? booking.getReserve_person_unionid() : node == UNIT ? booking.getReserveUnitId() : booking.getClubId()));
|
||||
}
|
||||
|
||||
/** 返回非空审核人工号名单,缺少节点负责人时中止事务并提示具体节点。 */
|
||||
@@ -89,20 +94,21 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
List<String> names = reviewers(node, booking).stream().map(v -> v.getString("loginname"))
|
||||
.filter(Strings::isNotBlank).distinct().collect(Collectors.toList());
|
||||
if (names.isEmpty()) throw new IllegalArgumentException(node == UNION ? "所属分工会未配置可用的分工会主席"
|
||||
: node == CLUB ? "所选协会未配置可用的协会会长" : "未配置可用的校工会场地管理员");
|
||||
: node == CLUB ? "所选协会未配置可用的协会会长" : node == UNIT ? "所属单位未配置可用的二级单位负责人" : "未配置可用的校工会场地管理员");
|
||||
return names;
|
||||
}
|
||||
|
||||
/** stages 是后端固定入口 union/club/school,返回节点 ID,禁止任意传入状态码。 */
|
||||
/** stages 是后端固定入口 union/club/unit/school,返回节点 ID,禁止任意传入状态码。 */
|
||||
public int node(String stage) {
|
||||
if ("union".equals(stage)) return UNION;
|
||||
if ("club".equals(stage)) return CLUB;
|
||||
if ("school".equals(stage)) return SCHOOL;
|
||||
if ("unit".equals(stage)) return UNIT;
|
||||
throw new IllegalArgumentException("无效的审核入口");
|
||||
}
|
||||
|
||||
private String stage(int node) { return node == UNION ? "union" : node == CLUB ? "club" : "school"; }
|
||||
private String title(int node) { return node == UNION ? "分工会审核" : node == CLUB ? "协会审核" : "校工会审核"; }
|
||||
private String stage(int node) { return node == UNION ? "union" : node == CLUB ? "club" : node == UNIT ? "unit" : "school"; }
|
||||
private String title(int node) { return node == UNION ? "分工会审核" : node == CLUB ? "协会审核" : node == UNIT ? "单位审核" : "校工会审核"; }
|
||||
private String process(ActivitySiteReserve b) { return "activity_site@" + b.getSqid(); }
|
||||
|
||||
/**
|
||||
@@ -128,9 +134,11 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
form.setReserve_person_phone(user.getMobile());
|
||||
// user 视图按特殊人员工会关系、所属单位计算有效分工会;原表 unionid 可能为空或为历史值。
|
||||
// 提交时保存有效组织快照,后续待办和审核范围均使用该快照匹配主席角色。
|
||||
List<NutMap> profile=listMap(Sqls.create("select unionid,unitname from `user` where id=@id").setParam("id",uid()));
|
||||
List<NutMap> profile=listMap(Sqls.create("select unionid,unitid,unitname from `user` where id=@id").setParam("id",uid()));
|
||||
form.setReserve_person_unionid(profile.isEmpty() ? null : profile.get(0).getString("unionid"));
|
||||
form.setReserve_person_unit(profile.isEmpty() ? "" : profile.get(0).getString("unitname"));
|
||||
// 所属单位由登录人资料生成,不接受客户端指定其他单位。
|
||||
form.setReserveUnitId(profile.isEmpty() ? null : profile.get(0).getString("unitid"));
|
||||
if (first == CLUB && myClubs().stream().noneMatch(v -> v.getString("id").equals(form.getClubId())))
|
||||
throw new IllegalArgumentException("您不是所选协会的有效成员,请重新选择所属协会");
|
||||
if (first != CLUB) form.setClubId(null);
|
||||
@@ -164,9 +172,9 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
List<ActivitySiteReserve> existing = query(Cnd.where("site_id", "=", site.getId()).and("reserve_day", "=", day)
|
||||
.and("start_time", "<", end).and("end_time", ">", start).and("reserve_state", "not in", Arrays.asList(REJECT, CANCEL)));
|
||||
if (existing.stream().anyMatch(v -> uid().equals(v.getReserve_person_id()))) throw new IllegalArgumentException("您已预约该时间段");
|
||||
if (!personal && !existing.isEmpty()) throw new IllegalArgumentException("该时段已有预约,协会或分工会预约需要空闲时段");
|
||||
if (!personal && !existing.isEmpty()) throw new IllegalArgumentException("该时段已有预约,分工会、协会或单位预约需要空闲时段");
|
||||
if (personal && (existing.stream().anyMatch(v -> !Integer.valueOf(1).equals(v.getReserve_type()))
|
||||
|| site.getLimitNum() == null || siteInfoService.occupiedCount(existing,start,end) >= site.getLimitNum())) throw new IllegalArgumentException("该时段预约人数已满或已被分工会/协会预约");
|
||||
|| site.getLimitNum() == null || siteInfoService.occupiedCount(existing,start,end) >= site.getLimitNum())) throw new IllegalArgumentException("该时段预约人数已满或已被分工会、协会、单位预约");
|
||||
}
|
||||
String sqid = UUID.randomUUID().toString().replace("-", "");
|
||||
for (NutMap slot : slots) {
|
||||
@@ -174,7 +182,7 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
row.setSqid(sqid); row.setSite_id(site.getId()); row.setReserve_type(form.getReserve_type());
|
||||
row.setClubId(form.getClubId()); row.setReserve_person_unionid(form.getReserve_person_unionid());
|
||||
row.setReserve_person_id(uid()); row.setReserve_person(user.getUsername());
|
||||
row.setReserve_person_phone(user.getMobile()); row.setReserve_person_unit(form.getReserve_person_unit());
|
||||
row.setReserve_person_phone(user.getMobile()); row.setReserve_person_unit(form.getReserve_person_unit()); row.setReserveUnitId(form.getReserveUnitId());
|
||||
row.setReserve_cause(form.getReserve_cause()); row.setReserve_state(first);
|
||||
row.setReserve_day(slot.getString("day")); row.setStart_time(slot.getString("start_time")); row.setEnd_time(slot.getString("end_time"));
|
||||
dao().insert(row);
|
||||
@@ -240,8 +248,9 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
}
|
||||
}
|
||||
|
||||
/** 返回指定审核入口的数据范围,分工会/协会使用角色关系上的组织字段。 */
|
||||
/** 返回指定审核入口的数据范围,分工会、协会和单位均匹配角色关系上的对应组织字段。 */
|
||||
private String scope(int node) {
|
||||
if (node == UNIT) return "exists(select 1 from sys_user_role ur join sys_role r on r.id=ur.roleId where ur.userId=@uid and r.code='unit_manger' and coalesce(r.disabled,0)=0 and ur.unitid=b.reserveUnitId)";
|
||||
if (node == SCHOOL) return "exists(select 1 from sys_user_role ur join sys_role r on r.id=ur.roleId where ur.userId=@uid and r.code='" + SCHOOL_REVIEW_ROLE + "')";
|
||||
return "exists(select 1 from sys_user_role ur join sys_role r on r.id=ur.roleId where ur.userId=@uid and r.code='"
|
||||
+ (node == UNION ? "gh01" : "club01") + "' and "
|
||||
@@ -362,7 +371,7 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
if (b == null) throw new IllegalArgumentException("预约不存在");
|
||||
boolean allowed = uid().equals(b.getReserve_person_id());
|
||||
for (int node : new java.util.LinkedHashSet<>(Arrays.asList(firstState(b.getReserve_type()), SCHOOL))) {
|
||||
if (node == UNION && Strings.isBlank(b.getReserve_person_unionid()) || node == CLUB && Strings.isBlank(b.getClubId())) continue;
|
||||
if (node == UNION && Strings.isBlank(b.getReserve_person_unionid()) || node == CLUB && Strings.isBlank(b.getClubId()) || node == UNIT && Strings.isBlank(b.getReserveUnitId())) continue;
|
||||
allowed |= reviewers(node,b).stream().anyMatch(v -> uid().equals(v.getString("id")));
|
||||
}
|
||||
List<NutMap> history = b.getAuditList() == null ? new ArrayList<>() : b.getAuditList();
|
||||
@@ -398,7 +407,7 @@ public class SiteBookingService extends BaseServiceImpl<ActivitySiteReserve> {
|
||||
listMap(Sqls.create("select id from activity_site_reserve where sqid=@sqid order by id for update").setParam("sqid",b.getSqid()));
|
||||
b = fetch(id);
|
||||
if (!Integer.valueOf(node).equals(b.getReserve_state())) throw new IllegalArgumentException("申请已处理或不属于当前审核节点,请刷新列表");
|
||||
if (reviewers(node,b).stream().noneMatch(v -> uid().equals(v.getString("id")))) throw new IllegalArgumentException("无权审核该分工会或协会的申请");
|
||||
if (reviewers(node,b).stream().noneMatch(v -> uid().equals(v.getString("id")))) throw new IllegalArgumentException("无权审核该组织的申请");
|
||||
int next = !pass ? REJECT : node == SCHOOL ? PASS : SCHOOL;
|
||||
if (next == SCHOOL) assignments(SCHOOL,b);
|
||||
Audit audit = new Audit();
|
||||
|
||||
@@ -207,7 +207,7 @@ public class SiteInfoMobileController {
|
||||
@At("/getReserve")
|
||||
@Ok("json:full")
|
||||
@ViReturn
|
||||
/** siteId为场地,day为日期,reserveType为1个人/2单位/3协会;返回带code/msg的可预约场次数组。 */
|
||||
/** siteId为场地,day为日期,reserveType为1历史个人/2分工会/3协会/4单位;返回带code/msg的可预约场次数组。 */
|
||||
public Object getReserve(String siteId, String day, Integer reserveType) {
|
||||
return siteInfoService.availableSlots(siteId,day,reserveType);
|
||||
}
|
||||
@@ -215,7 +215,7 @@ public class SiteInfoMobileController {
|
||||
@At("/reserveDo")
|
||||
@Ok("json:full")
|
||||
@ViReturn
|
||||
/** siteId 为场地;times 为 day/start_time/end_time 数组 JSON;message 为事由;reserve_type 为1/2/3,clubId 为协会预约所属协会;返回 sqid。 */
|
||||
/** siteId 为场地;times 为 day/start_time/end_time 数组 JSON;message 为事由;reserve_type 为1历史个人/2分工会/3协会/4单位,clubId 为协会预约所属协会;返回 sqid。 */
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public Object reserveDo(String siteId, String times, String message, Integer reserve_type, String clubId) {
|
||||
ActivitySiteReserve form=new ActivitySiteReserve();
|
||||
|
||||
+17
-67
@@ -1,14 +1,9 @@
|
||||
package io.v.nutz.zhgh.staffmanage.sourcechange.controller;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.wizzer.framework.base.Result;
|
||||
import io.v.nutz.base.annontation.ViReturn;
|
||||
import io.v.nutz.base.utils.PageUtil;
|
||||
import io.v.nutz.sys.models.User;
|
||||
import io.v.nutz.web.commons.slog.annotation.SLog;
|
||||
import io.v.nutz.zhgh.staffmanage.member.constant.MemberChangeType;
|
||||
import io.v.nutz.zhgh.staffmanage.member.service.MemberCommonService;
|
||||
import io.v.nutz.zhgh.staffmanage.sourcechange.model.SourceChangeMiddleTable;
|
||||
import io.v.nutz.zhgh.staffmanage.sourcechange.param.pageform.SourceChangePageForm;
|
||||
import io.v.nutz.zhgh.staffmanage.sourcechange.service.SourceChangeManageService;
|
||||
@@ -16,10 +11,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
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.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.dao.util.cri.Static;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
@@ -29,7 +20,6 @@ import org.nutz.mvc.annotation.Ok;
|
||||
import org.nutz.mvc.annotation.Param;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
@@ -47,8 +37,6 @@ public class SourceChangeManageController {
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private MemberCommonService commonService;
|
||||
@Inject
|
||||
private SourceChangeManageService sourceChangeManageService;
|
||||
|
||||
|
||||
@@ -59,67 +47,29 @@ public class SourceChangeManageController {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param pageForm 列表筛选、排序及分页参数;日期字段为 yyyy-MM-dd,changeTypes 为类型编码集合
|
||||
* @return 分页对象,list 为变更记录,totalCount 为符合条件的记录总数
|
||||
*/
|
||||
@At
|
||||
@ViReturn
|
||||
@RequiresPermissions("sourcechange.manage")
|
||||
public Object pageData(SourceChangePageForm pageForm){
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
scmt.id,
|
||||
scmt.loginname,
|
||||
scmt.username,
|
||||
u.sex,
|
||||
u.unitName,
|
||||
u.unionName,
|
||||
scmt.userState,
|
||||
scmt.personType,
|
||||
scmt.preparedBy,
|
||||
scmt.changeTime,
|
||||
scmt.changeTypes,
|
||||
scmt.changeOrigin,
|
||||
scmt.isOperate,
|
||||
scmt.changeInfosStr,
|
||||
u.id AS userId
|
||||
FROM
|
||||
source_change_middle_table scmt
|
||||
LEFT JOIN `user` u ON scmt.loginname = u.loginname
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if(StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.orLike("u.username",pageForm.getSearchKeyword());
|
||||
seg.orLike("u.loginname",pageForm.getSearchKeyword());
|
||||
cnd.and(seg);
|
||||
}
|
||||
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
|
||||
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
|
||||
} else {
|
||||
cnd.desc("changeTime");
|
||||
}
|
||||
return sourceChangeManageService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(),
|
||||
sourceChangeManageService.buildQuery(pageForm));
|
||||
}
|
||||
|
||||
if (Lang.isNotEmpty(pageForm.getChangeTypes())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
for (String type : pageForm.getChangeTypes()) {
|
||||
seg.or(new Static("JSON_CONTAINS(scmt.changeTypes, JSON_QUOTE('%s'), '$')".formatted(type)));
|
||||
}
|
||||
cnd.and(seg);
|
||||
}
|
||||
|
||||
cnd.andEX("u.unionId", "=", pageForm.getUnionId());
|
||||
cnd.andEX("u.unitId", "=", pageForm.getUnitId());
|
||||
cnd.andEX("u.sex", "=", pageForm.getSex());
|
||||
cnd.andEX("scmt.personType", "=", pageForm.getPersonType());
|
||||
cnd.andEX("scmt.preparedBy", "=", pageForm.getPreparedBy());
|
||||
cnd.andEX("scmt.userState", "=", pageForm.getUserState());
|
||||
cnd.andEX("scmt.isOperate", "=", pageForm.getIsOperate());
|
||||
if (StrUtil.isAllNotBlank(pageForm.getChangeDateBefore(), pageForm.getChangeDateEnd())) {
|
||||
cnd.and(new Static(String.format("Date(changeTime) >= '%s' and Date(changeTime) <= '%s'", pageForm.getChangeDateBefore(), pageForm.getChangeDateEnd())));
|
||||
} else {
|
||||
cnd.and("Date(changeTime)", "=", DateUtil.today());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return commonService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql);
|
||||
/**
|
||||
* 按列表筛选条件导出全部变更记录,不受分页或勾选行限制。
|
||||
* @param pageForm 姓名工号、单位工会、人员属性、变更类型、起止日期和操作状态,与列表参数一致
|
||||
* @param response 输出人员变更记录.xlsx,列为列表展示字段,变更类型使用中文名称
|
||||
*/
|
||||
@At
|
||||
@Ok("void")
|
||||
@RequiresPermissions("sourcechange.manage")
|
||||
public void doExport(SourceChangePageForm pageForm, javax.servlet.http.HttpServletResponse response) {
|
||||
sourceChangeManageService.exportXlsx(pageForm, response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+18
-1
@@ -5,7 +5,9 @@ import io.v.nutz.sys.models.User;
|
||||
import io.v.nutz.zhgh.data.model.UserHistory;
|
||||
import io.v.nutz.zhgh.staffmanage.sourcechange.model.SourceChangeMiddleTable;
|
||||
|
||||
import java.util.Date;
|
||||
import io.v.nutz.zhgh.staffmanage.sourcechange.param.pageform.SourceChangePageForm;
|
||||
import org.nutz.dao.sql.Sql;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @version 1.0
|
||||
@@ -16,6 +18,21 @@ import java.util.Date;
|
||||
*/
|
||||
public interface SourceChangeManageService extends BaseService<SourceChangeMiddleTable> {
|
||||
|
||||
/**
|
||||
* 生成列表及导出共用的查询,保留原有筛选及排序规则。
|
||||
* @param pageForm 人员、日期、类型、操作状态及排序条件;分页参数由列表调用方处理
|
||||
* @return 未设置分页的 SQL,结果包含人员信息、变更类型、明细及变更时间
|
||||
*/
|
||||
Sql buildQuery(SourceChangePageForm pageForm);
|
||||
|
||||
/**
|
||||
* 导出当前条件下的全部变更记录。
|
||||
* @param pageForm 与列表相同的筛选条件,忽略 pageNumber 和 pageSize
|
||||
* @param response 输出 xlsx 文件,列与列表一致,类型编码转换为中文
|
||||
*/
|
||||
void exportXlsx(SourceChangePageForm pageForm, HttpServletResponse response);
|
||||
|
||||
|
||||
/**
|
||||
* 人工变更,做变更
|
||||
* @param middleTable
|
||||
|
||||
+114
@@ -1,6 +1,18 @@
|
||||
package io.v.nutz.zhgh.staffmanage.sourcechange.service.impl;
|
||||
|
||||
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.bean.BeanUtil;
|
||||
import io.v.nutz.base.utils.CommonDownloadUtil;
|
||||
import io.v.nutz.base.utils.PageUtil;
|
||||
import io.v.nutz.zhgh.staffmanage.sourcechange.param.pageform.SourceChangePageForm;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.nutz.dao.util.cri.SqlExpressionGroup;
|
||||
import org.nutz.dao.util.cri.Static;
|
||||
import org.nutz.json.Json;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import cn.hutool.core.date.DateTime;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
@@ -68,6 +80,108 @@ public class SourceChangeManageServiceImpl extends BaseServiceImpl<SourceChangeM
|
||||
private MsgApi msgApi;
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public Sql buildQuery(SourceChangePageForm pageForm) {
|
||||
// 列表和导出使用同一查询;这里不设置分页,避免导出仅包含当前页。
|
||||
Sql sql = Sqls.create("""
|
||||
SELECT
|
||||
scmt.id,
|
||||
scmt.loginname,
|
||||
scmt.username,
|
||||
u.sex,
|
||||
u.unitName,
|
||||
u.unionName,
|
||||
scmt.userState,
|
||||
scmt.personType,
|
||||
scmt.preparedBy,
|
||||
scmt.changeTime,
|
||||
scmt.changeTypes,
|
||||
scmt.changeOrigin,
|
||||
scmt.isOperate,
|
||||
scmt.changeInfosStr,
|
||||
u.id AS userId
|
||||
FROM
|
||||
source_change_middle_table scmt
|
||||
LEFT JOIN `user` u ON scmt.loginname = u.loginname
|
||||
$condition
|
||||
""");
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if(StrUtil.isNotBlank(pageForm.getSearchKeyword())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
seg.orLike("u.username",pageForm.getSearchKeyword());
|
||||
seg.orLike("u.loginname",pageForm.getSearchKeyword());
|
||||
cnd.and(seg);
|
||||
}
|
||||
if (StrUtil.isAllNotBlank(pageForm.getPageOrderName(), pageForm.getPageOrderBy())) {
|
||||
cnd.orderBy(pageForm.getPageOrderName(), PageUtil.getOrder(pageForm.getPageOrderBy()));
|
||||
} else {
|
||||
cnd.desc("changeTime");
|
||||
}
|
||||
|
||||
if (Lang.isNotEmpty(pageForm.getChangeTypes())) {
|
||||
SqlExpressionGroup seg = new SqlExpressionGroup();
|
||||
for (String type : pageForm.getChangeTypes()) {
|
||||
seg.or(new Static("JSON_CONTAINS(scmt.changeTypes, JSON_QUOTE('%s'), '$')".formatted(type)));
|
||||
}
|
||||
cnd.and(seg);
|
||||
}
|
||||
|
||||
cnd.andEX("u.unionId", "=", pageForm.getUnionId());
|
||||
cnd.andEX("u.unitId", "=", pageForm.getUnitId());
|
||||
cnd.andEX("u.sex", "=", pageForm.getSex());
|
||||
cnd.andEX("scmt.personType", "=", pageForm.getPersonType());
|
||||
cnd.andEX("scmt.preparedBy", "=", pageForm.getPreparedBy());
|
||||
cnd.andEX("scmt.userState", "=", pageForm.getUserState());
|
||||
cnd.andEX("scmt.isOperate", "=", pageForm.getIsOperate());
|
||||
if (StrUtil.isAllNotBlank(pageForm.getChangeDateBefore(), pageForm.getChangeDateEnd())) {
|
||||
cnd.and(new Static(String.format("Date(changeTime) >= '%s' and Date(changeTime) <= '%s'", pageForm.getChangeDateBefore(), pageForm.getChangeDateEnd())));
|
||||
} else {
|
||||
cnd.and("Date(changeTime)", "=", DateUtil.today());
|
||||
}
|
||||
sql.setCondition(cnd);
|
||||
return sql;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
public void exportXlsx(SourceChangePageForm pageForm, HttpServletResponse response) {
|
||||
List<NutMap> rows = listMap(buildQuery(pageForm));
|
||||
Map<String, String> typeNames = Arrays.stream(MemberChangeType.values())
|
||||
.collect(Collectors.toMap(MemberChangeType::getType, MemberChangeType::getChangeTypeName));
|
||||
for (NutMap row : rows) {
|
||||
// 空类型保持空白;历史未知编码保留原值,避免导出丢失已有信息。
|
||||
String rawTypes = row.getString("changeTypes");
|
||||
List<String> types = StrUtil.isBlank(rawTypes) ? Collections.emptyList()
|
||||
: Json.fromJsonAsList(String.class, rawTypes);
|
||||
row.put("changeTypes", types == null ? "" : types.stream()
|
||||
.map(type -> typeNames.getOrDefault(type, type)).collect(Collectors.joining(",")));
|
||||
Object changeTime = row.get("changeTime");
|
||||
if (changeTime instanceof Date) {
|
||||
row.put("changeTime", DateUtil.format((Date) changeTime, "yyyy-MM-dd HH:mm:ss"));
|
||||
}
|
||||
}
|
||||
List<ExcelExportEntity> columns = new ArrayList<>();
|
||||
columns.add(new ExcelExportEntity("工号", "loginname", 20));
|
||||
columns.add(new ExcelExportEntity("姓名", "username", 15));
|
||||
columns.add(new ExcelExportEntity("在职状态", "userState", 15));
|
||||
columns.add(new ExcelExportEntity("人员类型", "personType", 20));
|
||||
// JDBC 返回的列名为 unionname,与列表字段一致;Excel 按键名取值时区分大小写。
|
||||
columns.add(new ExcelExportEntity("所属工会", "unionname", 25));
|
||||
columns.add(new ExcelExportEntity("变更详细信息", "changeInfosStr", 80));
|
||||
columns.add(new ExcelExportEntity("变更类型", "changeTypes", 30));
|
||||
columns.add(new ExcelExportEntity("变更时间", "changeTime", 25));
|
||||
ExportParams exportParams = new ExportParams();
|
||||
exportParams.setType(ExcelType.XSSF);
|
||||
// 即使没有匹配记录也生成包含表头的文件,保持下载行为一致。
|
||||
try (Workbook workbook = ExcelExportUtil.exportExcel(exportParams, columns, rows)) {
|
||||
CommonDownloadUtil.download("人员变更记录.xlsx", workbook, response);
|
||||
} catch (Exception e) {
|
||||
log.error("导出人员变更记录失败", e);
|
||||
throw new RuntimeException("导出人员变更记录失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
public void doSourceChange(SourceChangeMiddleTable middleTable) {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
<el-tab-pane label="预约基本信息" name="2">
|
||||
<el-descriptions class="margin-top" :column="3" border>
|
||||
<el-descriptions-item label="预约类型">{{ {1:'个人预约',2:'分工会预约',3:'协会预约'}[viewData.reserve_type] }}</el-descriptions-item>
|
||||
<el-descriptions-item label="预约类型">{{ {1:'个人预约',2:'分工会预约',3:'协会预约',4:'单位预约'}[viewData.reserve_type] }}</el-descriptions-item>
|
||||
<el-descriptions-item label="所属协会">{{viewData.club_name || '—'}}</el-descriptions-item>
|
||||
<el-descriptions-item label="预约人">{{ viewData.reserve_person }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="场地名称"> {{ viewData.site_name }}</el-descriptions-item>
|
||||
|
||||
@@ -150,12 +150,12 @@
|
||||
this.clearPopupHistory(() => pjaxReplace('/mobile/index'))
|
||||
}
|
||||
},
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约'}[type] || '—' },
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约',4:'单位预约'}[type] || '—' },
|
||||
filterOpened() { this.$set(this, 'filterShow', true) },
|
||||
filterClosed() { this.$set(this, 'filterShow', false) },
|
||||
canReview(row) {
|
||||
const stage = this.reviewApi.substring(this.reviewApi.lastIndexOf('/') + 1)
|
||||
return Number(row.reserve_state) === {union:4000,club:4010,school:4020}[stage]
|
||||
return Number(row.reserve_state) === {union:4000,club:4010,unit:4060,school:4020}[stage]
|
||||
},
|
||||
search() {
|
||||
// 筛选变更使旧响应失效,避免未审核和已审核数据混入同一列表。
|
||||
|
||||
@@ -46,7 +46,7 @@ const SITE_AUDIT_INFO = {
|
||||
props: {reviewApi: {type: String, required: true}},
|
||||
data() { return {viewData: {}, activeName: 'basic', expanded: true, detailLoading: false, requestId: 0} },
|
||||
methods: {
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约'}[type] || '—' },
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约',4:'单位预约'}[type] || '—' },
|
||||
toggleExpanded() { this.$set(this, 'expanded', !this.expanded) },
|
||||
// id 为预约记录主键;返回预约字段及 auditListTable 历史,loaded 通知父页核验可审核状态。
|
||||
onOpen(id) {
|
||||
|
||||
@@ -270,8 +270,9 @@ layout("/mobile/platform.html"){
|
||||
</van-cell>
|
||||
<van-cell title="预约地点">{{site.name}}</van-cell>
|
||||
<van-cell title="预约类型" required :value="reserveTypeName" is-link class="reserve-choice" @click="openOptions('type')"></van-cell>
|
||||
<!-- 分工会使用后端查询的当前组织,只读显示;协会仅在协会预约时选择。 -->
|
||||
<!-- 分工会和单位使用后端查询的当前组织,只读显示;协会仅在协会预约时选择。 -->
|
||||
<van-cell title="所属分工会" v-if="reserve_type===2" :value="unionLoading ? '加载中...' : bookingUnionName || '未配置所属分工会'"></van-cell>
|
||||
<van-cell title="所属单位" v-if="reserve_type===4" :value="unionLoading ? '加载中...' : bookingUnitName || '未配置所属单位'"></van-cell>
|
||||
<van-cell title="所属协会" v-if="reserve_type===3" class="reserve-choice"
|
||||
:value="reserve_type===3 ? selectedClubName : myClubs.map(club=>club.name).join('、')"
|
||||
:is-link="reserve_type===3" @click="openOptions('club')"></van-cell>
|
||||
@@ -342,9 +343,9 @@ layout("/mobile/platform.html"){
|
||||
return {
|
||||
historyPopupKeys: ['show','calendarVisible','optionsShow'],
|
||||
optionsShow: false, optionKind: 'type',
|
||||
// 新申请仅开放分工会和协会,个人类型保留用于历史数据。
|
||||
reserveTypeOptions: [{text:'分工会预约',value:2},{text:'协会预约',value:3}],
|
||||
bookingUnionName:'', unionLoading:false,
|
||||
// 新申请开放分工会、协会和单位,个人类型保留用于历史数据。
|
||||
reserveTypeOptions: [{text:'分工会预约',value:2},{text:'协会预约',value:3},{text:'单位预约',value:4}],
|
||||
bookingUnionName:'', bookingUnitName:'', unionLoading:false,
|
||||
myClubs: [], clubId: '', formLoading: false,
|
||||
// 新预约须主动选择类型,初始不选中任何选项。
|
||||
reserve_type: null,
|
||||
@@ -492,7 +493,10 @@ layout("/mobile/platform.html"){
|
||||
this.$set(this,'unionLoading',true)
|
||||
$.post('/platform/activity/site/reserve/myUnion').then(res=>{
|
||||
if(this._isDestroyed || this._isBeingDestroyed)return
|
||||
if(res && res.code===0)this.$set(this,'bookingUnionName',res.data && res.data.name || '')
|
||||
if(res && res.code===0) {
|
||||
this.$set(this,'bookingUnionName',res.data && res.data.name || '')
|
||||
this.$set(this,'bookingUnitName',res.data && res.data.unitName || '')
|
||||
}
|
||||
else vant.Toast(res && res.msg || '所属分工会加载失败')
|
||||
},()=>{if(!this._isDestroyed && !this._isBeingDestroyed)vant.Toast('所属分工会加载失败,请重新进入')}).always(()=>{
|
||||
if(!this._isDestroyed && !this._isBeingDestroyed)this.$set(this,'unionLoading',false)
|
||||
|
||||
@@ -3,4 +3,5 @@
|
||||
<!--# if(@shiro.hasPermission('activity.site.review.union')){ #--><p><a href="/platform/activity/site/review/union">分工会审核</a> · <a href="/mobile/activity/site/audit/union">手机端</a></p><!--# } #-->
|
||||
<!--# if(@shiro.hasPermission('activity.site.review.club')){ #--><p><a href="/platform/activity/site/review/club">协会审核</a> · <a href="/mobile/activity/site/audit/club">手机端</a></p><!--# } #-->
|
||||
<!--# if(@shiro.hasPermission('activity.site.review.school')){ #--><p><a href="/platform/activity/site/review/school">校工会审核</a> · <a href="/mobile/activity/site/audit/school">手机端</a></p><!--# } #-->
|
||||
<!--# if(@shiro.hasPermission('activity.site.review.unit')){ #--><p><a href="/platform/activity/site/review/unit">单位审核</a> · <a href="/mobile/activity/site/audit/unit">手机端</a></p><!--# } #-->
|
||||
</body></html>
|
||||
|
||||
@@ -498,12 +498,17 @@ layout("/layouts/platform.html"){
|
||||
<!--<el-radio-button :label="1">个人预约</el-radio-button>-->
|
||||
<el-radio-button :label="2">分工会预约</el-radio-button>
|
||||
<el-radio-button :label="3">协会预约</el-radio-button>
|
||||
<el-radio-button :label="4">单位预约</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<!-- 分工会由后端按当前申请人解析,只读展示,不接受前端指定组织。 -->
|
||||
<el-form-item label="所属分工会" v-if="formData.reserve_type===2">
|
||||
<el-input :value="bookingUnionName" readonly :placeholder="unionLoading ? '正在加载所属分工会' : '未配置所属分工会'"></el-input>
|
||||
</el-form-item>
|
||||
<!-- 单位取当前登录人资料,实际审核归属由后端保存单位快照。 -->
|
||||
<el-form-item label="所属单位" v-if="formData.reserve_type===4">
|
||||
<el-input :value="bookingUnitName" readonly :placeholder="unionLoading ? '正在加载所属单位' : '未配置所属单位'"></el-input>
|
||||
</el-form-item>
|
||||
<!-- 所属协会仅用于协会预约。 -->
|
||||
<el-form-item label="所属协会" v-if="formData.reserve_type===3">
|
||||
<el-select v-model="formData.clubId" placeholder="请选择所属协会" style="width:100%">
|
||||
@@ -546,7 +551,7 @@ layout("/layouts/platform.html"){
|
||||
max: 24,
|
||||
min: 0,
|
||||
myClubs: [],
|
||||
bookingUnionName:'', unionLoading:false, unionRequestVersion:0,
|
||||
bookingUnionName:'', bookingUnitName:'', unionLoading:false, unionRequestVersion:0,
|
||||
bookingSlots:[], slotsLoading:false, slotsVersion:0,
|
||||
bookingTab:'time', bookingRangeStart:'', bookingRangeEnd:'', slotsLoadFailed:false,
|
||||
formLoading: false,
|
||||
@@ -718,10 +723,14 @@ layout("/layouts/platform.html"){
|
||||
const version=this.unionRequestVersion+1
|
||||
this.$set(this,'unionRequestVersion',version)
|
||||
this.$set(this,'bookingUnionName','')
|
||||
this.$set(this,'bookingUnitName','')
|
||||
this.$set(this,'unionLoading',true)
|
||||
$.post('/platform/activity/site/reserve/myUnion').then(res=>{
|
||||
if(version!==this.unionRequestVersion)return
|
||||
if(res && res.code===0)this.$set(this,'bookingUnionName',res.data && res.data.name || '')
|
||||
if(res && res.code===0) {
|
||||
this.$set(this,'bookingUnionName',res.data && res.data.name || '')
|
||||
this.$set(this,'bookingUnitName',res.data && res.data.unitName || '')
|
||||
}
|
||||
else this.$message.error(res && res.msg || '所属分工会加载失败')
|
||||
},()=>{if(version===this.unionRequestVersion)this.$message.error('所属分工会加载失败,请重新打开表单')}).always(()=>{
|
||||
if(version===this.unionRequestVersion)this.$set(this,'unionLoading',false)
|
||||
|
||||
@@ -151,11 +151,11 @@
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约'}[type] || '—' },
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约',4:'单位预约'}[type] || '—' },
|
||||
// 以申请实际节点决定审核入口,已流转的申请只允许查看。
|
||||
canReview(row) {
|
||||
const stage = this.reviewApi.substring(this.reviewApi.lastIndexOf('/') + 1)
|
||||
return Number(row.reserve_state) === {union:4000,club:4010,school:4020}[stage]
|
||||
return Number(row.reserve_state) === {union:4000,club:4010,unit:4060,school:4020}[stage]
|
||||
},
|
||||
openView(row) {
|
||||
this.$refs.guava.view()
|
||||
|
||||
@@ -45,7 +45,7 @@ const info = {
|
||||
return {viewData: {}, activeName: 'info', detailLoading: false, requestId: 0}
|
||||
},
|
||||
methods: {
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约'}[type] || '—' },
|
||||
typeName(type) { return {1:'个人预约',2:'分工会预约',3:'协会预约',4:'单位预约'}[type] || '—' },
|
||||
// id 为预约记录主键,activeName 为申请信息或审核标签;结果含预约字段及 auditListTable 审核历史。
|
||||
onOpen(id, activeName = 'info') {
|
||||
const requestId = this.requestId + 1
|
||||
|
||||
@@ -32,18 +32,19 @@ layout("/layouts/platform.html"){
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">日期范围:</div>
|
||||
<div class="search-item-label">日期开始</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker
|
||||
end-placeholder="结束日期"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
style="width: 100%"
|
||||
@change="activityDateChange"
|
||||
value-format="yyyy-MM-dd"
|
||||
v-model="pageForm.activityDate">
|
||||
</el-date-picker>
|
||||
<el-date-picker clearable type="date" style="width: 100%"
|
||||
placeholder="日期开始" v-model="dateStart"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">日期结束</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker clearable type="date" style="width: 100%"
|
||||
placeholder="日期结束" v-model="dateEnd"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -128,6 +129,8 @@ layout("/layouts/platform.html"){
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
dateStart: "",
|
||||
dateEnd: "",
|
||||
tableColumns: [
|
||||
{label: '姓名', prop: 'username'},
|
||||
{label: '工号', prop: 'loginname'},
|
||||
@@ -157,7 +160,24 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 两个日期框合成为原接口的起止数组;两端清空表示不限定日期,单端或倒置时停止查询。
|
||||
syncDateRange() {
|
||||
const start = this.dateStart
|
||||
const end = this.dateEnd
|
||||
if ((!start && end) || (start && !end)) {
|
||||
this.$message.warning('请选择完整的日期开始和日期结束')
|
||||
return false
|
||||
}
|
||||
if (start && end && start > end) {
|
||||
this.$message.warning('日期开始不能晚于日期结束')
|
||||
return false
|
||||
}
|
||||
this.$set(this.pageForm, 'activityDate', start && end ? [start, end] : [])
|
||||
return true
|
||||
},
|
||||
|
||||
exportExcel() {
|
||||
if (!this.syncDateRange()) return
|
||||
const {activityId, unionId, unitId, activityDate} = this.pageForm
|
||||
let activityDate1 = []
|
||||
if (activityDate && activityDate.length > 0) {
|
||||
@@ -165,9 +185,6 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
window.open(loc() + '/exportExcel?activityId=' + activityId + '&unionId=' + unionId + '&unitId=' + unitId + '&activityDate=' + activityDate1)
|
||||
},
|
||||
activityDateChange() {
|
||||
// this.$set(this.pageForm, "activityDate", [])
|
||||
},
|
||||
async unionChange(val) {
|
||||
this.pageForm.unitId = null
|
||||
this.unitOptions = await getUnits(val)
|
||||
@@ -184,22 +201,25 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
pageData() {
|
||||
if (!this.syncDateRange()) return
|
||||
sublime.showLoadingbar();
|
||||
this.tableLoading = true
|
||||
this.$set(this, "tableLoading", true)
|
||||
let pageForm = clone(this.pageForm)
|
||||
if (pageForm.activityDate && pageForm.activityDate.length > 0) {
|
||||
pageForm.activityDate = JSON.stringify(pageForm.activityDate)
|
||||
}
|
||||
$.post(loc() + "/pageData", pageForm, (data) => {
|
||||
sublime.closeLoadingbar();
|
||||
this.tableLoading = false
|
||||
return $.post(loc() + "/pageData", pageForm).then((data) => {
|
||||
if (data.code === 0) {
|
||||
this.tableData = data.data.list;
|
||||
this.pageForm.totalCount = data.data.totalCount;
|
||||
this.$set(this, "tableData", data.data.list);
|
||||
this.$set(this.pageForm, "totalCount", data.data.totalCount);
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
}, "json");
|
||||
}).always(() => {
|
||||
// 成功或失败均释放查询状态,避免日期筛选请求异常后界面一直等待。
|
||||
sublime.closeLoadingbar();
|
||||
this.$set(this, "tableLoading", false)
|
||||
});
|
||||
},
|
||||
|
||||
async getActivityById(){
|
||||
|
||||
@@ -12,19 +12,18 @@ layout("/layouts/platform.html"){
|
||||
<template>
|
||||
<el-card class="mt10" shadow="never">
|
||||
<div class="btn-group tool-button mr10">
|
||||
<el-date-picker @change="getMeetingList(pageForm.meetingTime)" clearable
|
||||
end-placeholder="结束日期"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
v-model="pageForm.meetingTime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss">
|
||||
</el-date-picker>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="会议开始" v-model="dateStart"
|
||||
value-format="yyyy-MM-dd HH:mm:ss" @change="changeMeetingDate"></el-date-picker>
|
||||
<span class="mr5">至</span>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="会议结束" v-model="dateEnd"
|
||||
value-format="yyyy-MM-dd HH:mm:ss" @change="changeMeetingDate"></el-date-picker>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="btn-group tool-button mr10">
|
||||
<el-select @change="doSearch" clearable
|
||||
<el-select :loading="meetingListLoading" @change="doSearch" clearable
|
||||
filterable="true"
|
||||
placeholder="请输入会议名称"
|
||||
style="width: 100%;" v-model="pageForm.meetingId">
|
||||
@@ -183,6 +182,9 @@ layout("/layouts/platform.html"){
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
meetingListLoading: false,
|
||||
dateStart: "",
|
||||
dateEnd: "",
|
||||
meetingTypeList: [],
|
||||
unions: [],
|
||||
units: [],
|
||||
@@ -222,6 +224,22 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 两个日期框合成为原接口的起止数组;两端清空表示不限定日期,单端或倒置时停止查询。
|
||||
syncDateRange() {
|
||||
const start = this.dateStart
|
||||
const end = this.dateEnd
|
||||
if ((!start && end) || (start && !end)) {
|
||||
this.$message.warning('请选择完整的会议开始和会议结束')
|
||||
return false
|
||||
}
|
||||
if (start && end && start > end) {
|
||||
this.$message.warning('会议开始不能晚于会议结束')
|
||||
return false
|
||||
}
|
||||
this.$set(this.pageForm, 'meetingTime', start && end ? [start, end] : [])
|
||||
return true
|
||||
},
|
||||
|
||||
proportionNum(joinNum, total) {
|
||||
console.log(joinNum, total)
|
||||
return ((joinNum ? joinNum : 0) / total * 100).toFixed(2) + "%"
|
||||
@@ -242,9 +260,24 @@ layout("/layouts/platform.html"){
|
||||
this.pageFormUser.pageSize = val;
|
||||
this.getUserData(this.meetingTimeData, this.meetingNumType)
|
||||
},
|
||||
async getMeetingList(meetingTime) {
|
||||
const {data} = await $.post(loc() + "/getMeetingList", {meetingTime: JSON.stringify(meetingTime)})
|
||||
this.meetingList = data
|
||||
// 修改完整日期范围后刷新可选会议,并清除旧会议筛选,避免沿用范围外的会议。
|
||||
changeMeetingDate() {
|
||||
if (!this.syncDateRange()) return
|
||||
this.$set(this.pageForm, 'meetingId', '')
|
||||
return this.getMeetingList(this.pageForm.meetingTime).then(() => this.doSearch())
|
||||
},
|
||||
pageData() {
|
||||
if (!this.syncDateRange()) return
|
||||
return initTableMixins.methods.pageData.call(this)
|
||||
},
|
||||
getMeetingList(meetingTime) {
|
||||
this.$set(this, "meetingListLoading", true)
|
||||
// meetingTime 为原接口的起止时间数组,返回 data 为会议选项列表。
|
||||
return $.post(loc() + "/getMeetingList", {meetingTime: JSON.stringify(meetingTime)}).then((res) => {
|
||||
this.$set(this, 'meetingList', res.data)
|
||||
}).always(() => {
|
||||
this.$set(this, 'meetingListLoading', false)
|
||||
})
|
||||
/*if (this.meetingList.length > 0) {
|
||||
this.$set(this.pageForm, "meetingId", this.meetingList[0].id)
|
||||
this.pageData()
|
||||
@@ -285,7 +318,10 @@ layout("/layouts/platform.html"){
|
||||
this.meetingTypeList = await meetUtil.getAllMeetingType()
|
||||
let format = moment().add(-1, 'year').format('YYYY-MM-DD HH:mm:ss');
|
||||
let format1 = moment().format('YYYY-MM-DD HH:mm:ss');
|
||||
this.$set(this.pageForm, "meetingTime", [format, format1])
|
||||
// 保留最近一年默认范围,并让两个日期框与首次请求使用相同值。
|
||||
this.$set(this, 'dateStart', format)
|
||||
this.$set(this, 'dateEnd', format1)
|
||||
this.syncDateRange()
|
||||
await this.getMeetingList(this.pageForm.meetingTime)
|
||||
await this.pageData()
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ layout("/layouts/platform.html"){
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="btn-group tool-button mr10">
|
||||
<el-date-picker clearable end-placeholder="结束日期"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
v-model="pageForm.dateRange"
|
||||
value-format="yyyy-MM-dd">
|
||||
</el-date-picker>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="创建开始" v-model="dateStart"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
<span class="mr5">至</span>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="创建结束" v-model="dateEnd"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
|
||||
</div>
|
||||
<div class="btn-group tool-button mr10">
|
||||
@@ -89,6 +89,8 @@ layout("/layouts/platform.html"){
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
dateStart: "",
|
||||
dateEnd: "",
|
||||
unions: [],
|
||||
units: [],
|
||||
pageForm: {
|
||||
@@ -107,6 +109,22 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 两个日期框合成为原接口的起止数组;两端清空表示不限定日期,单端或倒置时停止查询。
|
||||
syncDateRange() {
|
||||
const start = this.dateStart
|
||||
const end = this.dateEnd
|
||||
if ((!start && end) || (start && !end)) {
|
||||
this.$message.warning('请选择完整的创建开始和创建结束')
|
||||
return false
|
||||
}
|
||||
if (start && end && start > end) {
|
||||
this.$message.warning('创建开始不能晚于创建结束')
|
||||
return false
|
||||
}
|
||||
this.$set(this.pageForm, 'dateRange', start && end ? [start, end] : [])
|
||||
return true
|
||||
},
|
||||
|
||||
async doSend(row) {
|
||||
const confirm = await this.$confirm('您确定要发送消息吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
@@ -151,16 +169,15 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
pageData() {
|
||||
if (!this.syncDateRange()) return
|
||||
sublime.showLoadingbar();
|
||||
this.tableLoading = true
|
||||
this.$set(this, "tableLoading", true)
|
||||
|
||||
const pageForm = clone(this.pageForm)
|
||||
pageForm.sendTypes = JSON.stringify(pageForm.sendTypes)
|
||||
pageForm.dateRange = JSON.stringify(pageForm.dateRange)
|
||||
|
||||
$.post(loc() + "/pageData", pageForm, (data) => {
|
||||
sublime.closeLoadingbar();
|
||||
this.tableLoading = false
|
||||
return $.post(loc() + "/pageData", pageForm).then((data) => {
|
||||
if (data.code === 0) {
|
||||
data.data.list.forEach(v => {
|
||||
if (v.sendTypes) {
|
||||
@@ -177,12 +194,16 @@ layout("/layouts/platform.html"){
|
||||
v.sendTypesName = "钉钉"
|
||||
}
|
||||
})
|
||||
this.tableData = data.data.list;
|
||||
this.pageForm.totalCount = data.data.totalCount;
|
||||
this.$set(this, "tableData", data.data.list);
|
||||
this.$set(this.pageForm, "totalCount", data.data.totalCount);
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
}, "json");
|
||||
}).always(() => {
|
||||
// 成功或失败均释放查询状态,避免日期筛选请求异常后界面一直等待。
|
||||
sublime.closeLoadingbar();
|
||||
this.$set(this, "tableLoading", false)
|
||||
});
|
||||
},
|
||||
async openEdit(row) {
|
||||
/* const {data} = await $.post(loc() + "/getMeetingByMsgId", {id: row.id})
|
||||
|
||||
@@ -8,19 +8,18 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never">
|
||||
|
||||
<div class="btn-group tool-button mr10">
|
||||
<el-date-picker clearable end-placeholder="结束日期"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
@change="getTitleList(pageForm.dateRange)"
|
||||
v-model="pageForm.dateRange"
|
||||
value-format="yyyy-MM-dd">
|
||||
</el-date-picker>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="发送开始" v-model="dateStart"
|
||||
value-format="yyyy-MM-dd" @change="changeMessageDate"></el-date-picker>
|
||||
<span class="mr5">至</span>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="发送结束" v-model="dateEnd"
|
||||
value-format="yyyy-MM-dd" @change="changeMessageDate"></el-date-picker>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="btn-group tool-button mr10">
|
||||
<el-select placeholder="消息列表" v-model="pageForm.titleId" style="width: 100%;"
|
||||
<el-select :loading="titleListLoading" placeholder="消息列表" v-model="pageForm.titleId" style="width: 100%;"
|
||||
clearable="true"
|
||||
filterable="true">
|
||||
<el-option v-for="item in titleList" :label="item.title" :value="item.id"></el-option>
|
||||
@@ -98,6 +97,9 @@ layout("/layouts/platform.html"){
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
titleListLoading: false,
|
||||
dateStart: "",
|
||||
dateEnd: "",
|
||||
unions: [],
|
||||
units: [],
|
||||
titleList: [],
|
||||
@@ -119,9 +121,36 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async getTitleList(dateRange) {
|
||||
const {data} = await $.post(loc() + "/getTitleList", {dateRange: JSON.stringify(dateRange)})
|
||||
this.titleList = data
|
||||
// 两个日期框合成为原接口的起止数组;两端清空表示不限定日期,单端或倒置时停止查询。
|
||||
syncDateRange() {
|
||||
const start = this.dateStart
|
||||
const end = this.dateEnd
|
||||
if ((!start && end) || (start && !end)) {
|
||||
this.$message.warning('请选择完整的发送开始和发送结束')
|
||||
return false
|
||||
}
|
||||
if (start && end && start > end) {
|
||||
this.$message.warning('发送开始不能晚于发送结束')
|
||||
return false
|
||||
}
|
||||
this.$set(this.pageForm, 'dateRange', start && end ? [start, end] : [])
|
||||
return true
|
||||
},
|
||||
|
||||
// 日期完整后同步消息选项;清空旧标题,避免保留范围外的消息筛选。
|
||||
changeMessageDate() {
|
||||
if (!this.syncDateRange()) return
|
||||
this.$set(this.pageForm, 'titleId', '')
|
||||
return this.getTitleList(this.pageForm.dateRange)
|
||||
},
|
||||
getTitleList(dateRange) {
|
||||
this.$set(this, "titleListLoading", true)
|
||||
// dateRange 为原接口的日期数组,返回 data 为可选消息标题列表。
|
||||
return $.post(loc() + "/getTitleList", {dateRange: JSON.stringify(dateRange)}).then((res) => {
|
||||
this.$set(this, 'titleList', res.data)
|
||||
}).always(() => {
|
||||
this.$set(this, 'titleListLoading', false)
|
||||
})
|
||||
},
|
||||
async flushUnits() {
|
||||
this.$set(this.pageForm, "unitId", "")
|
||||
@@ -132,16 +161,15 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
pageData() {
|
||||
if (!this.syncDateRange()) return
|
||||
sublime.showLoadingbar();
|
||||
this.tableLoading = true
|
||||
this.$set(this, "tableLoading", true)
|
||||
|
||||
const pageForm = clone(this.pageForm)
|
||||
pageForm.sendTypes = JSON.stringify(pageForm.sendTypes)
|
||||
pageForm.dateRange = JSON.stringify(pageForm.dateRange)
|
||||
|
||||
$.post(loc() + "/pageData", pageForm, (data) => {
|
||||
sublime.closeLoadingbar();
|
||||
this.tableLoading = false
|
||||
return $.post(loc() + "/pageData", pageForm).then((data) => {
|
||||
if (data.code == 0) {
|
||||
data.data.list.forEach(v => {
|
||||
if (v.sendTypes) {
|
||||
@@ -155,12 +183,16 @@ layout("/layouts/platform.html"){
|
||||
v.sendTypesName = "钉钉"
|
||||
}
|
||||
})
|
||||
this.tableData = data.data.list;
|
||||
this.pageForm.totalCount = data.data.totalCount;
|
||||
this.$set(this, "tableData", data.data.list);
|
||||
this.$set(this.pageForm, "totalCount", data.data.totalCount);
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
}, "json");
|
||||
}).always(() => {
|
||||
// 成功或失败均释放查询状态,避免日期筛选请求异常后界面一直等待。
|
||||
sublime.closeLoadingbar();
|
||||
this.$set(this, "tableLoading", false)
|
||||
});
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
|
||||
@@ -10,13 +10,19 @@ layout("/layouts/platform.html"){
|
||||
<el-card shadow="never">
|
||||
<div class="search">
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">报销时间:</div>
|
||||
<div class="search-item-label">报销开始</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker type="daterange" style="width: 100%" range-separator="——"
|
||||
v-model="pageForm.reimbursementDate"
|
||||
value-format="yyyy-MM-dd" format="yyyy-MM-dd"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"></el-date-picker>
|
||||
<el-date-picker clearable type="date" style="width: 100%"
|
||||
placeholder="报销开始" v-model="dateStart"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">报销结束</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker clearable type="date" style="width: 100%"
|
||||
placeholder="报销结束" v-model="dateEnd"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -171,6 +177,8 @@ layout("/layouts/platform.html"){
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
dateStart: "",
|
||||
dateEnd: "",
|
||||
unions: [],
|
||||
units: [],
|
||||
formData: {},
|
||||
@@ -203,6 +211,22 @@ layout("/layouts/platform.html"){
|
||||
'reimbursement-new': httpVueLoader('/components/reimbursement/reimbursementNew.vue'),
|
||||
},
|
||||
methods: {
|
||||
// 两个日期框合成为原接口的起止数组;两端清空表示不限定日期,单端或倒置时停止查询。
|
||||
syncDateRange() {
|
||||
const start = this.dateStart
|
||||
const end = this.dateEnd
|
||||
if ((!start && end) || (start && !end)) {
|
||||
this.$message.warning('请选择完整的报销开始和报销结束')
|
||||
return false
|
||||
}
|
||||
if (start && end && start > end) {
|
||||
this.$message.warning('报销开始不能晚于报销结束')
|
||||
return false
|
||||
}
|
||||
this.$set(this.pageForm, 'reimbursementDate', start && end ? [start, end] : [])
|
||||
return true
|
||||
},
|
||||
|
||||
getSummaries(param) {
|
||||
const {columns, data} = param;
|
||||
const sums = [];
|
||||
@@ -235,6 +259,7 @@ layout("/layouts/platform.html"){
|
||||
return sums;
|
||||
},
|
||||
doExportUserExcel() {
|
||||
if (!this.syncDateRange()) return
|
||||
const {
|
||||
searchKeyword,
|
||||
searchName,
|
||||
@@ -264,21 +289,24 @@ layout("/layouts/platform.html"){
|
||||
this.units = await getUnits(this.pageForm.unionId)
|
||||
this.doSearch()
|
||||
},
|
||||
pageData() {//加载分页数据
|
||||
pageData() {
|
||||
if (!this.syncDateRange()) return
|
||||
sublime.showLoadingbar();//显示loading
|
||||
this.tabLoading = true
|
||||
this.$set(this, "tableLoading", true)
|
||||
const pageForm = clone(this.pageForm)
|
||||
pageForm.reimbursementDate = JSON.stringify(pageForm.reimbursementDate)
|
||||
$.post(loc() + "/pageData", pageForm, (data) => {
|
||||
sublime.closeLoadingbar();//关闭loading
|
||||
this.tabLoading = false
|
||||
return $.post(loc() + "/pageData", pageForm).then((data) => {
|
||||
if (data.code == 0) {
|
||||
this.tableData = data.data.list;
|
||||
this.pageForm.totalCount = data.data.totalCount;
|
||||
this.$set(this, "tableData", data.data.list);
|
||||
this.$set(this.pageForm, "totalCount", data.data.totalCount);
|
||||
} else {
|
||||
this.$message.error(data.msg);
|
||||
}
|
||||
}, "json");
|
||||
}).always(() => {
|
||||
// 成功或失败均释放查询状态,避免日期筛选请求异常后界面一直等待。
|
||||
sublime.closeLoadingbar();
|
||||
this.$set(this, "tableLoading", false)
|
||||
});
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
|
||||
@@ -50,12 +50,18 @@ const COMMON_QUERY = {
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">变更日期</div>
|
||||
<div class="search-item-label">变更开始</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker :picker-options="pickerOptions" @change="changeDateRangeChange"
|
||||
align="right" end-placeholder="结束日期" format="yyyy-MM-dd"
|
||||
range-separator="-" start-placeholder="开始日期" style="width: 100%"
|
||||
type="datetimerange" v-model="pageForm.changeDateRange"
|
||||
<el-date-picker @change="doSearch" placeholder="请选择变更开始" format="yyyy-MM-dd"
|
||||
style="width: 100%" type="date" v-model="pageForm.changeDateBefore"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">变更结束</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker @change="doSearch" placeholder="请选择变更结束" format="yyyy-MM-dd"
|
||||
style="width: 100%" type="date" v-model="pageForm.changeDateEnd"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
@@ -68,37 +74,6 @@ const COMMON_QUERY = {
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return{
|
||||
pickerOptions: {
|
||||
shortcuts: [
|
||||
{
|
||||
text: "最近一周",
|
||||
onClick(picker) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
|
||||
picker.$emit("pick", [start, end])
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "最近一个月",
|
||||
onClick(picker) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
|
||||
picker.$emit("pick", [start, end])
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "最近三个月",
|
||||
onClick(picker) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
|
||||
picker.$emit("pick", [start, end])
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
unions: [],
|
||||
units: [],
|
||||
pageForm: {
|
||||
@@ -109,31 +84,29 @@ const COMMON_QUERY = {
|
||||
unitId: '',
|
||||
userState: '',
|
||||
personType: '',
|
||||
changeDateRange: []
|
||||
changeDateBefore: '',
|
||||
changeDateEnd: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setDefaultDateRange() {
|
||||
const end = new Date(); // 当前时间
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90); // 当前时间往前推90天
|
||||
this.$set(this.pageForm, "changeDateRange", [start, end])
|
||||
this.pageForm.changeDateBefore = start
|
||||
this.pageForm.changeDateEnd = end
|
||||
this.doSearch()
|
||||
},
|
||||
changeDateRangeChange(val){
|
||||
if (val && val.length > 0) {
|
||||
this.pageForm.changeDateBefore = val[0]
|
||||
this.pageForm.changeDateEnd = val[1]
|
||||
} else {
|
||||
this.pageForm.changeDateBefore = null
|
||||
this.pageForm.changeDateEnd = null
|
||||
}
|
||||
// 最近三个月沿用90天口径;日期字符串与后端按天筛选的参数格式保持一致。
|
||||
const end = moment()
|
||||
this.$set(this.pageForm, "changeDateBefore", end.clone().subtract(90, 'days').format('YYYY-MM-DD'))
|
||||
this.$set(this.pageForm, "changeDateEnd", end.format('YYYY-MM-DD'))
|
||||
this.doSearch()
|
||||
},
|
||||
doSearch(){
|
||||
// 后端需要完整的起止日期;缺失时会退回仅查询当天,因此不发送不完整或倒置的范围。
|
||||
if (!this.pageForm.changeDateBefore || !this.pageForm.changeDateEnd) {
|
||||
this.$message.warning('请选择变更开始和变更结束')
|
||||
return
|
||||
}
|
||||
if (this.pageForm.changeDateBefore > this.pageForm.changeDateEnd) {
|
||||
this.$message.warning('变更开始不能晚于变更结束')
|
||||
return
|
||||
}
|
||||
this.$emit('search', this.pageForm)
|
||||
},
|
||||
async initData(){
|
||||
|
||||
@@ -41,18 +41,19 @@ layout("/layouts/platform.html"){
|
||||
<el-link type="danger"
|
||||
v-if="changeTypeData.length && pageForm.changeTypes.length"
|
||||
:underline="false"
|
||||
@click="pageForm.changeTypes=[];doSearch()">清空
|
||||
@click="clearChangeTypes">清空
|
||||
</el-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool :app="this" label="变更记录(默认查询最近三个月,如需查询其他变更记录,请选择上方【变更日期】后进行搜索)">
|
||||
<table-tool :app="this" label="变更记录(默认查询最近三个月,如需查询其他变更记录,请选择上方【变更开始】【变更结束】后进行搜索)">
|
||||
<template #func>
|
||||
<el-button type="primary" icon="el-icon-download" size="small" @click="doExport">导出</el-button>
|
||||
<el-button type="primary" style="margin-right: 10px" size="small" @click="doBatchChange">批量确认</el-button>
|
||||
|
||||
<el-radio-group @change="search" class="mr5" size="small"
|
||||
<el-radio-group @change="doSearch" class="mr5" size="small"
|
||||
v-model="pageForm.isOperate">
|
||||
<el-radio-button label="true">已操作</el-radio-button>
|
||||
<el-radio-button label="false">未操作</el-radio-button>
|
||||
@@ -143,6 +144,12 @@ layout("/layouts/platform.html"){
|
||||
'user-change-info': USER_CHANGE_INFO
|
||||
},
|
||||
methods: {
|
||||
// 使用列表已应用的筛选条件导出全部匹配记录,类型编码按原接口格式传递。
|
||||
doExport() {
|
||||
const pageForm = clone(this.pageForm)
|
||||
pageForm.changeTypes = JSON.stringify(pageForm.changeTypes)
|
||||
this.$downLoad('/platform/sourcechange/manage/doExport', pageForm)
|
||||
},
|
||||
/**
|
||||
* 撤销
|
||||
*/
|
||||
@@ -254,11 +261,18 @@ layout("/layouts/platform.html"){
|
||||
} else {
|
||||
this.pageForm[key].push(val)
|
||||
}
|
||||
this.pageData()
|
||||
// 类型筛选变化后复用 mixin 的搜索入口,重置页码再查询。
|
||||
this.doSearch()
|
||||
},
|
||||
clearChangeTypes() {
|
||||
// 清空类型与点击类型标签保持相同的分页重置行为。
|
||||
this.$set(this.pageForm, 'changeTypes', [])
|
||||
this.doSearch()
|
||||
},
|
||||
search(pageForm){
|
||||
this.pageForm = { ...this.pageForm, ...pageForm }
|
||||
this.pageData()
|
||||
// 合并业务筛选后回到第一页,避免沿用旧页码导致新条件下出现空列表。
|
||||
this.$set(this, 'pageForm', { ...this.pageForm, ...pageForm })
|
||||
this.doSearch()
|
||||
},
|
||||
getChangeTypes(changeTypes){
|
||||
const changeTypesList = JSON.parse(changeTypes)
|
||||
@@ -286,7 +300,7 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
async created() {
|
||||
this.changeTypeData = await getEnumOptions("MemberChangeType")
|
||||
this.pageData()
|
||||
// 首次查询由筛选组件设置默认起止日期后触发,避免无日期请求覆盖默认范围的结果。
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -49,12 +49,18 @@ const COMMON_QUERY = {
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">生日日期</div>
|
||||
<div class="search-item-label">生日开始</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker :picker-options="pickerOptions" @change="changeDateRangeChange"
|
||||
align="right" end-placeholder="结束日期" format="yyyy-MM-dd"
|
||||
range-separator="-" start-placeholder="开始日期" style="width: 100%"
|
||||
type="datetimerange" v-model="pageForm.changeDateRange"
|
||||
<el-date-picker clearable type="date" @change="doSearch" style="width: 100%"
|
||||
placeholder="生日开始" v-model="pageForm.startDate"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">生日结束</div>
|
||||
<div class="search-item-option">
|
||||
<el-date-picker clearable type="date" @change="doSearch" style="width: 100%"
|
||||
placeholder="生日结束" v-model="pageForm.endDate"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
@@ -65,38 +71,6 @@ const COMMON_QUERY = {
|
||||
`,
|
||||
data() {
|
||||
return {
|
||||
pickerOptions: {
|
||||
shortcuts: [
|
||||
{
|
||||
text: "未来一周",
|
||||
onClick(picker) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
end.setTime(start.getTime() + 3600 * 1000 * 24 * 7)
|
||||
picker.$emit("pick", [start, end])
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "未来一个月",
|
||||
onClick(picker) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
end.setTime(start.getTime() + 3600 * 1000 * 24 * 30)
|
||||
picker.$emit("pick", [start, end])
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "未来三个月",
|
||||
onClick(picker) {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
end.setTime(start.getTime() + 3600 * 1000 * 24 * 90)
|
||||
picker.$emit("pick", [start, end])
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
unions: [],
|
||||
units: [],
|
||||
pageForm: {
|
||||
@@ -106,28 +80,20 @@ const COMMON_QUERY = {
|
||||
userStates: [],
|
||||
personTypes: [],
|
||||
preparedBys: [],
|
||||
changeDateRange: [],
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch(){
|
||||
// 生日接口按月日筛选,支持单端与跨年范围;两端为空时保留未来15天的默认查询。
|
||||
const pageForm = clone(this.pageForm)
|
||||
pageForm.userStates = JSON.stringify(this.pageForm.userStates)
|
||||
pageForm.personTypes = JSON.stringify(this.pageForm.personTypes)
|
||||
pageForm.preparedBys = JSON.stringify(this.pageForm.preparedBys)
|
||||
this.$emit('search', pageForm)
|
||||
},
|
||||
changeDateRangeChange(val){
|
||||
if (val && val.length > 0) {
|
||||
this.pageForm.startDate = val[0]
|
||||
this.pageForm.endDate = val[1]
|
||||
} else {
|
||||
this.pageForm.startDate = null
|
||||
this.pageForm.endDate = null
|
||||
}
|
||||
this.doSearch()
|
||||
},
|
||||
async initData(){
|
||||
if (this.$auth.hasRoleOr('sysadmin, SchoolUnionMemberAdmin, SchoolUnionAdmin')) {
|
||||
this.unions = await getUnions(this.pageForm.unionId)
|
||||
|
||||
@@ -39,15 +39,13 @@ layout("/layouts/platform.html"){
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-date-picker
|
||||
end-placeholder="购置日期"
|
||||
format="yyyy 年 MM 月 dd 日"
|
||||
range-separator="-"
|
||||
start-placeholder="购置日期"
|
||||
type="daterange"
|
||||
v-model="time"
|
||||
value-format="yyyy-MM-dd">
|
||||
</el-date-picker>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="购置开始" v-model="dateStart"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
<span class="mr5">至</span>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="购置结束" v-model="dateEnd"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
<div class="btn-group tool-button mt5">
|
||||
<el-select placeholder="请选择资产类型" v-model="pageForm.zcghlx">
|
||||
@@ -317,6 +315,8 @@ layout("/layouts/platform.html"){
|
||||
el: '#app',
|
||||
data: function () {
|
||||
return {
|
||||
dateStart: "",
|
||||
dateEnd: "",
|
||||
pageForm: {
|
||||
searchName: "",
|
||||
searchKeyword: "",
|
||||
@@ -345,7 +345,24 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 两个日期框合成为原接口的起止数组;两端清空表示不限定日期,单端或倒置时停止查询。
|
||||
syncDateRange() {
|
||||
const start = this.dateStart
|
||||
const end = this.dateEnd
|
||||
if ((!start && end) || (start && !end)) {
|
||||
this.$message.warning('请选择完整的购置开始和购置结束')
|
||||
return false
|
||||
}
|
||||
if (start && end && start > end) {
|
||||
this.$message.warning('购置开始不能晚于购置结束')
|
||||
return false
|
||||
}
|
||||
this.$set(this, 'time', start && end ? [start, end] : [])
|
||||
return true
|
||||
},
|
||||
|
||||
doAllExport() {
|
||||
if (!this.syncDateRange()) return
|
||||
const {searchKeyword, searchName, zczt, zcghlx, ghid} = this.pageForm
|
||||
let startTime = ''
|
||||
let endTime = ''
|
||||
@@ -365,16 +382,9 @@ layout("/layouts/platform.html"){
|
||||
doExport(id) {
|
||||
window.location.href = '/platform/zcgl/tzgl/downloadrzd?id=' + id
|
||||
},
|
||||
doSearch: function () {
|
||||
|
||||
if (this.time != "" && this.time != null) {
|
||||
this.pageForm.startTime = this.time[0];
|
||||
this.pageForm.endTime = this.time[1];
|
||||
} else {
|
||||
this.pageForm.startTime = null;
|
||||
this.pageForm.endTime = null;
|
||||
}
|
||||
this.pageForm.pageNumber = 1;
|
||||
doSearch() {
|
||||
if (!this.syncDateRange()) return
|
||||
this.$set(this.pageForm, 'pageNumber', 1)
|
||||
this.pageData();
|
||||
},
|
||||
pageOrder: function (column) {//按字段排序
|
||||
@@ -398,21 +408,27 @@ layout("/layouts/platform.html"){
|
||||
this.pageForm.pageSize = val;
|
||||
this.pageData();
|
||||
},
|
||||
pageData: function () {//加载分页数据
|
||||
var self = this;
|
||||
sublime.showLoadingbar();//显示loading
|
||||
$.post(base + "/platform/zcgl/zhcx/data", self.pageForm, function (data) {
|
||||
sublime.closeLoadingbar();//关闭loading
|
||||
pageData() {
|
||||
if (!this.syncDateRange()) return
|
||||
this.$set(this.pageForm, "startTime", this.dateStart || null)
|
||||
this.$set(this.pageForm, "endTime", this.dateEnd || null)
|
||||
sublime.showLoadingbar();
|
||||
this.$set(this, "tableLoading", true)
|
||||
return $.post(base + "/platform/zcgl/zhcx/data", this.pageForm).then((data) => {
|
||||
if (data.code == 0) {
|
||||
self.tableData = data.data.list;
|
||||
self.pageForm.totalCount = data.data.totalCount;
|
||||
this.$set(this, "tableData", data.data.list);
|
||||
this.$set(this.pageForm, "totalCount", data.data.totalCount);
|
||||
} else {
|
||||
self.$message({
|
||||
this.$message({
|
||||
message: data.msg,
|
||||
type: 'error'
|
||||
});
|
||||
}
|
||||
}, "json");
|
||||
}).always(() => {
|
||||
// 成功或失败均释放查询状态,避免日期筛选请求异常后界面一直等待。
|
||||
sublime.closeLoadingbar();
|
||||
this.$set(this, "tableLoading", false)
|
||||
});
|
||||
},
|
||||
viewInfo(scope) {
|
||||
this.viewData = JSON.parse(JSON.stringify(scope.row));
|
||||
|
||||
@@ -9,13 +9,13 @@ layout("/layouts/platform.html"){
|
||||
|
||||
<div class="btn-group tool-button">
|
||||
<div class="block">
|
||||
<el-date-picker clearable end-placeholder="结束日期"
|
||||
range-separator="-"
|
||||
start-placeholder="开始日期"
|
||||
type="daterange"
|
||||
v-model="pageForm._dateRange"
|
||||
value-format="yyyy-MM-dd">
|
||||
</el-date-picker>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="申请开始" v-model="dateStart"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
<span class="mr5">至</span>
|
||||
<el-date-picker clearable type="date" style="width: 180px"
|
||||
placeholder="申请结束" v-model="dateEnd"
|
||||
value-format="yyyy-MM-dd"></el-date-picker>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn-group tool-button">
|
||||
@@ -139,6 +139,8 @@ layout("/layouts/platform.html"){
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dateStart: "",
|
||||
dateEnd: "",
|
||||
unions: [],
|
||||
units: [],
|
||||
pageForm: {
|
||||
@@ -152,17 +154,27 @@ layout("/layouts/platform.html"){
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
this.tabKey = new Date().getTime()
|
||||
this.pageForm.pageNumber = 1
|
||||
|
||||
if (this.pageForm._dateRange && this.pageForm._dateRange.length) {
|
||||
this.pageForm.dateRange = JSON.stringify(this.pageForm._dateRange)
|
||||
} else {
|
||||
this.pageForm.dateRange = ""
|
||||
// 两个日期框合成为原接口的起止数组;两端清空表示不限定日期,单端或倒置时停止查询。
|
||||
syncDateRange() {
|
||||
const start = this.dateStart
|
||||
const end = this.dateEnd
|
||||
if ((!start && end) || (start && !end)) {
|
||||
this.$message.warning('请选择完整的申请开始和申请结束')
|
||||
return false
|
||||
}
|
||||
if (start && end && start > end) {
|
||||
this.$message.warning('申请开始不能晚于申请结束')
|
||||
return false
|
||||
}
|
||||
this.$set(this.pageForm, '_dateRange', start && end ? [start, end] : [])
|
||||
return true
|
||||
},
|
||||
|
||||
this.pageData()
|
||||
// 日期参数同步后复用全局列表请求,搜索和分页继续使用 mixin 的逻辑。
|
||||
pageData() {
|
||||
if (!this.syncDateRange()) return
|
||||
this.$set(this.pageForm, 'dateRange', JSON.stringify(this.pageForm._dateRange))
|
||||
return initTableMixins.methods.pageData.call(this)
|
||||
},
|
||||
dropdownCommand(command) {
|
||||
const {type, data} = command
|
||||
@@ -181,6 +193,7 @@ layout("/layouts/platform.html"){
|
||||
this.$refs.viewInfoRef.onOpen(row.id)
|
||||
},
|
||||
doExcel() {
|
||||
if (!this.syncDateRange()) return
|
||||
const {unionId, unitId, _dateRange} = this.pageForm
|
||||
window.open("/platform/difficulty/reading/doExcel?dateRange=" + JSON.stringify(_dateRange)
|
||||
+ "&unionId=" + unionId + "&unitId=" + unitId)
|
||||
|
||||
Reference in New Issue
Block a user