1
This commit is contained in:
+43
-4
@@ -9,6 +9,7 @@ import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.annotation.SLog;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.model.ExcelImportRes;
|
||||
import com.budwk.app.base.page.Pagination;
|
||||
import com.budwk.app.base.param.PageForm;
|
||||
@@ -17,6 +18,8 @@ import com.budwk.app.base.utils.CommonDownloadUtil;
|
||||
import com.budwk.app.flow.enums.ProcessInstanceStateEnum;
|
||||
import com.budwk.app.sys.models.Sys_union;
|
||||
import com.budwk.app.sys.views.View_user;
|
||||
import com.budwk.app.web.commons.auth.utils.AuthUtil;
|
||||
import com.budwk.app.web.commons.auth.utils.SecurityUtil;
|
||||
import com.budwk.app.zhgh.dayofficework.tour.mode.TourLedgerImportExcelMode;
|
||||
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedger;
|
||||
import com.budwk.app.zhgh.dayofficework.tour.models.TourLedgerDirectRelative;
|
||||
@@ -196,6 +199,9 @@ public class TourLedgerController {
|
||||
if (ledger == null) {
|
||||
return Result.error("台账记录不存在");
|
||||
}
|
||||
if (!canAccessLedgerUnion(ledger.getUnionId())) {
|
||||
return Result.error("无权查看该台账记录");
|
||||
}
|
||||
ledger.setLineName(getCurrentLineName(ledger));
|
||||
Cnd familyCnd = Cnd.NEW();
|
||||
familyCnd.and(TourLedgerFamily::getLedgerId, "=", id);
|
||||
@@ -225,6 +231,9 @@ public class TourLedgerController {
|
||||
if (ledger == null) {
|
||||
return Result.error("台账记录不存在");
|
||||
}
|
||||
if (!canAccessLedgerUnion(ledger.getUnionId())) {
|
||||
return Result.error("无权删除该台账记录");
|
||||
}
|
||||
tourLedgerFamilyService.clear(Cnd.where(TourLedgerFamily::getLedgerId, "=", id));
|
||||
tourLedgerService.delete(id);
|
||||
return Result.success();
|
||||
@@ -239,7 +248,9 @@ public class TourLedgerController {
|
||||
if (idList.isEmpty()) {
|
||||
return Result.error("请选择要设置的参加人员");
|
||||
}
|
||||
tourLedgerService.dao().update(TourLedger.class, Chain.make("joined", true), Cnd.where("id", "in", idList));
|
||||
Cnd cnd = Cnd.where("id", "in", idList);
|
||||
cnd.andEX("unionId", "=", resolveLedgerUnionId(null));
|
||||
tourLedgerService.dao().update(TourLedger.class, Chain.make("joined", true), cnd);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@@ -811,6 +822,9 @@ public class TourLedgerController {
|
||||
@SaCheckPermission("tour.ledger")
|
||||
public Result unionOptions() {
|
||||
Cnd cnd = Cnd.NEW();
|
||||
if (isBranchUnionChairmanScope()) {
|
||||
cnd.and("id", "=", SecurityUtil.getUnionId());
|
||||
}
|
||||
cnd.asc("unionCode");
|
||||
cnd.asc("name");
|
||||
return Result.success(tourLedgerService.dao().query(Sys_union.class, cnd));
|
||||
@@ -825,7 +839,7 @@ public class TourLedgerController {
|
||||
cnd.andEX("t.`year`", "<=", endYear == null ? LocalDate.now().getYear() : endYear);
|
||||
cnd.and("t.lineName", "IS NOT", null);
|
||||
cnd.and("t.lineName", "<>", "");
|
||||
cnd.andEX("t.unionId", "=", unionId);
|
||||
cnd.andEX("t.unionId", "=", resolveLedgerUnionId(unionId));
|
||||
cnd.andEX("t.lineType", "=", lineType);
|
||||
appendTravelPeriodFilter(cnd, travelPeriod);
|
||||
appendKeywordFilter(cnd, keyword);
|
||||
@@ -864,7 +878,7 @@ public class TourLedgerController {
|
||||
cnd.and("m.travelStartTime", "<>", "");
|
||||
cnd.and("m.travelEndTime", "IS NOT", null);
|
||||
cnd.and("m.travelEndTime", "<>", "");
|
||||
cnd.andEX("t.unionId", "=", unionId);
|
||||
cnd.andEX("t.unionId", "=", resolveLedgerUnionId(unionId));
|
||||
cnd.andEX("t.lineType", "=", lineType);
|
||||
appendLineFilter(cnd, lineId);
|
||||
appendKeywordFilter(cnd, keyword);
|
||||
@@ -892,7 +906,7 @@ public class TourLedgerController {
|
||||
cnd.and("t.delFlag", "=", false);
|
||||
cnd.andEX("t.`year`", ">=", startYear);
|
||||
cnd.andEX("t.`year`", "<=", endYear == null ? LocalDate.now().getYear() : endYear);
|
||||
cnd.andEX("t.unionId", "=", unionId);
|
||||
cnd.andEX("t.unionId", "=", resolveLedgerUnionId(unionId));
|
||||
cnd.andEX("t.lineType", "=", lineType);
|
||||
appendLineFilter(cnd, lineId);
|
||||
appendTravelPeriodFilter(cnd, travelPeriod);
|
||||
@@ -902,6 +916,31 @@ public class TourLedgerController {
|
||||
return cnd;
|
||||
}
|
||||
|
||||
private boolean hasSchoolLedgerScope() {
|
||||
return AuthUtil.hasRoleOr(RoleConstant.SYSADMIN.name(), RoleConstant.SCHOOL_UNION_ADMIN.name());
|
||||
}
|
||||
|
||||
private boolean isBranchUnionChairmanScope() {
|
||||
return !hasSchoolLedgerScope() && AuthUtil.hasRole(RoleConstant.BRANCH_UNION_CHAIRMAN.name());
|
||||
}
|
||||
|
||||
private String resolveLedgerUnionId(String unionId) {
|
||||
// 分工会主席只能查询当前登录人所在分工会;校工会管理员保留页面传入条件,支持查全部。
|
||||
if (isBranchUnionChairmanScope()) {
|
||||
String currentUnionId = SecurityUtil.getUnionId();
|
||||
return StrUtil.isBlank(currentUnionId) ? "__NO_UNION__" : currentUnionId;
|
||||
}
|
||||
return unionId;
|
||||
}
|
||||
|
||||
private boolean canAccessLedgerUnion(String unionId) {
|
||||
if (!isBranchUnionChairmanScope()) {
|
||||
return true;
|
||||
}
|
||||
String currentUnionId = SecurityUtil.getUnionId();
|
||||
return StrUtil.isNotBlank(currentUnionId) && StrUtil.equals(currentUnionId, unionId);
|
||||
}
|
||||
|
||||
private void appendApprovedWorkflowFilter(Cnd cnd) {
|
||||
SqlExpressionGroup group = new SqlExpressionGroup();
|
||||
group.or("ins.id", "IS", null);
|
||||
|
||||
+1
-4
@@ -49,7 +49,6 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -110,9 +109,7 @@ public class RecuperationLineController {
|
||||
@ApiOperation("获取编号")
|
||||
@SaCheckPermission("recuperation.line")
|
||||
public Result getNo() {
|
||||
Object serialNumber = dao.func2(RecuperationLine.class, "max", "serialNumber");
|
||||
serialNumber = Objects.requireNonNullElse(serialNumber, 0);
|
||||
return Result.success(Integer.parseInt(serialNumber.toString()) + 1);
|
||||
return Result.success(lineService.generateNextSerialNumber());
|
||||
}
|
||||
|
||||
@At
|
||||
|
||||
+7
@@ -39,6 +39,13 @@ public interface RecuperationLineService extends BaseService<RecuperationLine> {
|
||||
*/
|
||||
void editLine(RecuperationLine line);
|
||||
|
||||
/**
|
||||
* 生成新增线路默认编码,按现有纯数字线路编码最大值自增。
|
||||
*
|
||||
* @return 新线路默认编码
|
||||
*/
|
||||
String generateNextSerialNumber();
|
||||
|
||||
/**
|
||||
* 开启或关闭线路
|
||||
*
|
||||
|
||||
+14
@@ -81,6 +81,20 @@ public class RecuperationLineServiceImpl extends BaseServiceImpl<RecuperationLin
|
||||
deleteLineInfoCache(line.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateNextSerialNumber() {
|
||||
Sql sql = Sqls.fetchInt("""
|
||||
SELECT
|
||||
IFNULL(MAX(CAST(serialNumber AS UNSIGNED)), 0) + 1
|
||||
FROM
|
||||
recuperation_line
|
||||
WHERE
|
||||
serialNumber REGEXP '^[0-9]+$'
|
||||
""");
|
||||
dao().execute(sql);
|
||||
return String.valueOf(sql.getInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openClosedLine(String lineId) {
|
||||
update(Chain.makeSpecial("isDisabled", "isDisabled ^ 1"), Cnd.where("id", "=", lineId));
|
||||
|
||||
+4
-1
@@ -633,9 +633,12 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 分配路线选项展示线路管理中的线路类型,便于同名线路按类型区分。
|
||||
matterOptionLabel(item) {
|
||||
const lineName = item.lineName || ""
|
||||
return lineName || item.matterName || ""
|
||||
const lineType = item.lineType || ""
|
||||
const label = lineName || item.matterName || ""
|
||||
return label && lineType ? label + "(" + lineType + ")" : label
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -33,7 +33,7 @@ layout("/layouts/platform.html"){
|
||||
@keyup.enter.native="doSearch">
|
||||
</el-input>
|
||||
</search-item>
|
||||
<search-item label="所属工会">
|
||||
<search-item label="所属工会" v-if="canSelectUnion()">
|
||||
<el-select v-model="pageForm.unionId" clearable filterable placeholder="请选择所属工会" style="width: 100%">
|
||||
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
@@ -367,6 +367,7 @@ layout("/layouts/platform.html"){
|
||||
showImportDialog: false,
|
||||
multipleSelection: [],
|
||||
filterOptionsTimer: null,
|
||||
currentUnionId: "",
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
@@ -398,6 +399,17 @@ layout("/layouts/platform.html"){
|
||||
handleSelectionChange(val) {
|
||||
this.multipleSelection = val || []
|
||||
},
|
||||
canSelectUnion() {
|
||||
return this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])
|
||||
},
|
||||
isBranchUnionChairmanOnly() {
|
||||
return !this.canSelectUnion() && this.$auth.hasRole("BRANCH_UNION_CHAIRMAN")
|
||||
},
|
||||
applyUnionScope() {
|
||||
if (this.isBranchUnionChairmanOnly() && this.currentUnionId) {
|
||||
this.pageForm.unionId = this.currentUnionId
|
||||
}
|
||||
},
|
||||
clearTableSelection() {
|
||||
this.multipleSelection = []
|
||||
if (this.$refs.tableRef) {
|
||||
@@ -501,7 +513,7 @@ layout("/layouts/platform.html"){
|
||||
this.pageForm.startYear = moment().format("YYYY")
|
||||
this.pageForm.endYear = moment().format("YYYY")
|
||||
this.pageForm.keyword = ""
|
||||
this.pageForm.unionId = ""
|
||||
this.pageForm.unionId = this.isBranchUnionChairmanOnly() ? this.currentUnionId : ""
|
||||
this.pageForm.lineId = ""
|
||||
this.pageForm.travelPeriod = ""
|
||||
this.pageForm.lineType = ""
|
||||
@@ -556,6 +568,10 @@ layout("/layouts/platform.html"){
|
||||
this.$axios.post(loc() + "/unionOptions").then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.unionOptions = res.data || []
|
||||
if (this.isBranchUnionChairmanOnly()) {
|
||||
this.currentUnionId = this.unionOptions.length ? this.unionOptions[0].id : ""
|
||||
this.applyUnionScope()
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -611,6 +627,7 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
},
|
||||
doSearch() {
|
||||
this.applyUnionScope()
|
||||
this.tableKey = new Date().getTime()
|
||||
this.pageForm.pageNumber = 1
|
||||
this.clearTableSelection()
|
||||
|
||||
+4
-1
@@ -686,9 +686,12 @@ layout("/layouts/platform.html"){
|
||||
})
|
||||
}).catch(() => {})
|
||||
},
|
||||
// 分配线路选项展示线路管理中的线路类型,便于同名线路按类型区分。
|
||||
matterOptionLabel(item) {
|
||||
const lineName = item.lineName || ""
|
||||
return lineName || item.matterName || ""
|
||||
const lineType = item.lineType || ""
|
||||
const label = lineName || item.matterName || ""
|
||||
return label && lineType ? label + "(" + lineType + ")" : label
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -29,8 +29,8 @@ const basicForm = {
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :md="12" :sm="24" :xs="24">
|
||||
<el-form-item label="排序号" prop="serialNumber">
|
||||
<el-input maxlength="50" v-model="formData.serialNumber" placeholder="请输入排序号"></el-input>
|
||||
<el-form-item label="线路编码" prop="serialNumber">
|
||||
<el-input maxlength="50" v-model="formData.serialNumber" placeholder="请输入线路编码"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@@ -240,7 +240,7 @@ const basicForm = {
|
||||
isDisabled: true
|
||||
},
|
||||
formRules: {
|
||||
serialNumber: [{required: true, message: '请输入排序号', trigger: ['change', 'blur']}],
|
||||
serialNumber: [{required: true, message: '请输入线路编码', trigger: ['change', 'blur']}],
|
||||
lineName: [{required: true, message: '请输入线路名称', trigger: ['change', 'blur']}],
|
||||
travelAgencyId: [{required: true, message: '请选择旅行社', trigger: ['change', 'blur']}],
|
||||
regionalNature: [{required: true, message: '请选择区域性质', trigger: ['change', 'blur']}],
|
||||
@@ -297,6 +297,9 @@ const basicForm = {
|
||||
this.formData = {...data}
|
||||
})
|
||||
} else {
|
||||
this.formData = {
|
||||
isDisabled: true
|
||||
}
|
||||
await this.getNumber()
|
||||
const createMode = await this.getCreateMode()
|
||||
this.$set(this.formData, 'createMode', createMode)
|
||||
@@ -333,8 +336,15 @@ const basicForm = {
|
||||
return resp.data
|
||||
},
|
||||
async getNumber() {
|
||||
const resp = await this.$axios.post(loc() + '/getNo')
|
||||
this.$set(this.formData, 'serialNumber', resp.data)
|
||||
return this.$axios.post(loc() + '/getNo').then((resp) => {
|
||||
if (resp.code === 0) {
|
||||
this.$set(this.formData, 'serialNumber', resp.data)
|
||||
} else {
|
||||
this.$message.warning(resp.msg || '线路编码生成失败')
|
||||
}
|
||||
}).catch(() => {
|
||||
this.$message.warning('线路编码生成失败')
|
||||
})
|
||||
},
|
||||
},
|
||||
async created() {
|
||||
|
||||
@@ -1,21 +1,39 @@
|
||||
package com.budwk.app;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelImportUtil;
|
||||
import cn.afterturn.easypoi.excel.annotation.Excel;
|
||||
import cn.afterturn.easypoi.excel.entity.ImportParams;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.budwk.app.base.constant.RoleConstant;
|
||||
import com.budwk.app.base.sms.SmsService;
|
||||
import com.budwk.app.flow.constant.FlowConst;
|
||||
import com.budwk.app.flow.engine.FlowEngine;
|
||||
import com.budwk.app.flow.engine.model.*;
|
||||
import com.budwk.app.flow.entity.ProcessTask;
|
||||
import com.budwk.app.flow.enums.ProcessSubmitTypeEnum;
|
||||
import com.budwk.app.sys.models.Sys_role;
|
||||
import com.budwk.app.sys.models.Sys_user;
|
||||
import com.budwk.app.sys.models.Sys_user_role;
|
||||
import com.budwk.app.sys.services.SysRoleService;
|
||||
import lombok.Data;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.nutz.aop.interceptor.ioc.TransAop;
|
||||
import org.nutz.boot.test.junit4.NbJUnit4Runner;
|
||||
import org.nutz.dao.Chain;
|
||||
import org.nutz.dao.Cnd;
|
||||
import org.nutz.dao.Dao;
|
||||
import org.nutz.ioc.aop.Aop;
|
||||
import org.nutz.ioc.loader.annotation.Inject;
|
||||
import org.nutz.ioc.loader.annotation.IocBean;
|
||||
import org.nutz.lang.Lang;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@IocBean
|
||||
@RunWith(NbJUnit4Runner.class)
|
||||
@@ -23,6 +41,12 @@ public class FlowTest {
|
||||
|
||||
@Inject
|
||||
private FlowEngine flowEngine;
|
||||
@Inject
|
||||
private Dao dao;
|
||||
@Inject
|
||||
private SmsService smsService;
|
||||
@Inject
|
||||
private SysRoleService sysRoleService;
|
||||
|
||||
@Test
|
||||
@Aop(TransAop.READ_COMMITTED)
|
||||
@@ -91,4 +115,98 @@ public class FlowTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void importZJIPCMemberRoster() {
|
||||
File dir = new File("C:\\Users\\mayn\\Desktop\\客户\\浙江工业职业学院\\基础数据\\浙江工业职业技术学院最新会员名册");
|
||||
File[] files = dir.listFiles((file, name) -> name.endsWith(".xls") || name.endsWith(".xlsx"));
|
||||
if (files == null || files.length == 0) {
|
||||
System.out.println("未找到会员名单 Excel 文件");
|
||||
return;
|
||||
}
|
||||
Arrays.sort(files, Comparator.comparing(File::getName));
|
||||
|
||||
ImportParams importParams = new ImportParams();
|
||||
importParams.setTitleRows(1);
|
||||
importParams.setHeadRows(1);
|
||||
|
||||
List<MemberRosterImportTemp> importList = new ArrayList<>();
|
||||
for (File file : files) {
|
||||
List<MemberRosterImportTemp> rows = ExcelImportUtil.importExcel(file, MemberRosterImportTemp.class, importParams);
|
||||
importList.addAll(rows.stream()
|
||||
.filter(row -> StrUtil.isNotBlank(row.getLoginName()))
|
||||
.toList());
|
||||
}
|
||||
List<String> loginNames = importList.stream()
|
||||
.map(MemberRosterImportTemp::getLoginName)
|
||||
.map(String::trim)
|
||||
.distinct()
|
||||
.toList();
|
||||
if (Lang.isEmpty(loginNames)) {
|
||||
System.out.println("Excel 中未读取到有效教工号");
|
||||
return;
|
||||
}
|
||||
|
||||
Sys_role memberRole = sysRoleService.getByCode(RoleConstant.MEMBER);
|
||||
if (memberRole == null) {
|
||||
System.out.println("会员角色不存在");
|
||||
return;
|
||||
}
|
||||
|
||||
List<Sys_user> users = dao.query(Sys_user.class, Cnd.where(Sys_user::getLoginname, "in", loginNames));
|
||||
Map<String, Sys_user> userMap = users.stream().collect(Collectors.toMap(Sys_user::getLoginname, Function.identity(), (a, b) -> a));
|
||||
List<String> missingLoginNames = loginNames.stream()
|
||||
.filter(loginName -> !userMap.containsKey(loginName))
|
||||
.toList();
|
||||
if (Lang.isNotEmpty(missingLoginNames)) {
|
||||
System.out.println("系统中未匹配到的教工号:" + missingLoginNames);
|
||||
}
|
||||
|
||||
List<String> userIds = users.stream().map(Sys_user::getId).distinct().toList();
|
||||
if (Lang.isEmpty(userIds)) {
|
||||
System.out.println("没有可导入为会员的用户");
|
||||
return;
|
||||
}
|
||||
|
||||
// 模仿 /platform/member/info/batchMake/batchMake:设置会员状态和入会时间。
|
||||
dao.update(Sys_user.class, Chain.make("member", true)
|
||||
.add("memberTime", DateUtil.now()),
|
||||
Cnd.where(Sys_user::getId, "in", userIds));
|
||||
|
||||
List<Sys_user_role> existingRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "in", userIds)
|
||||
.and(Sys_user_role::getRoleId, "=", memberRole.getId()));
|
||||
Set<String> hasRoleUserIds = existingRoles.stream().map(Sys_user_role::getUserId).collect(Collectors.toSet());
|
||||
List<Sys_user_role> roleList = userIds.stream()
|
||||
.filter(userId -> !hasRoleUserIds.contains(userId))
|
||||
.map(userId -> {
|
||||
Sys_user_role userRole = new Sys_user_role();
|
||||
userRole.setUserId(userId);
|
||||
userRole.setRoleId(memberRole.getId());
|
||||
return userRole;
|
||||
})
|
||||
.toList();
|
||||
if (Lang.isNotEmpty(roleList)) {
|
||||
dao.insert(roleList);
|
||||
}
|
||||
|
||||
System.out.println("Excel 读取人数:" + importList.size());
|
||||
System.out.println("有效教工号数:" + loginNames.size());
|
||||
System.out.println("匹配并设置会员人数:" + userIds.size());
|
||||
System.out.println("新增会员角色人数:" + roleList.size());
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class MemberRosterImportTemp {
|
||||
@Excel(name = "姓名")
|
||||
private String userName;
|
||||
|
||||
@Excel(name = "部门")
|
||||
private String unitName;
|
||||
|
||||
@Excel(name = "教工号")
|
||||
private String loginName;
|
||||
|
||||
@Excel(name = "联系电话")
|
||||
private String mobile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user