diff --git a/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java b/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java index 2693259..4d031c9 100644 --- a/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java +++ b/src/main/java/com/budwk/app/sys/services/impl/SysUserServiceImpl.java @@ -381,9 +381,9 @@ public class SysUserServiceImpl extends BaseServiceImpl implements Sys String decodePwd = Base64Decoder.decodeStr(passowrd); String hashedPassword = PwdUtil.getPassword(decodePwd, user.getSalt()); if (!Strings.sNull(hashedPassword).equalsIgnoreCase(user.getPassword())) { - if (Globals.sso) { - throw new BaseException("用户名或者密码不正确"); - } + // if (Globals.sso) { + throw new BaseException("用户名或者密码不正确"); + // } } user = this.fetchLinks(user, "unit"); if (Lang.isNotEmpty(user.getUnit()) && StrUtil.isNotBlank(user.getUnit().getUnionId())) { diff --git a/src/main/java/com/budwk/app/zhgh/activity/basic/controller/ActivityBasicUnitController.java b/src/main/java/com/budwk/app/zhgh/activity/basic/controller/ActivityBasicUnitController.java index 4b2fb48..86fab55 100644 --- a/src/main/java/com/budwk/app/zhgh/activity/basic/controller/ActivityBasicUnitController.java +++ b/src/main/java/com/budwk/app/zhgh/activity/basic/controller/ActivityBasicUnitController.java @@ -1,35 +1,24 @@ package com.budwk.app.zhgh.activity.basic.controller; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.lang.tree.Tree; -import cn.hutool.core.lang.tree.TreeNode; -import cn.hutool.core.lang.tree.TreeUtil; -import cn.hutool.core.util.StrUtil; -import com.budwk.app.base.page.Pagination; import com.budwk.app.base.param.PageForm; import com.budwk.app.base.result.Result; -import com.budwk.app.base.service.BaseService; -import com.budwk.app.sys.models.Sys_unit; -import com.budwk.app.sys.services.SysUnitService; -import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnion; import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; -import org.nutz.dao.Sqls; -import org.nutz.dao.sql.Sql; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; +import com.budwk.app.zhgh.activity.basic.service.ActivityBasicUnitService; +import org.nutz.log.Log; +import org.nutz.log.Logs; import org.nutz.mvc.annotation.At; import org.nutz.mvc.annotation.Ok; import org.nutz.mvc.annotation.Param; -import java.util.ArrayList; import java.util.List; -import java.util.Map; /** * @ClassName ActivityBasicUnitController @@ -42,8 +31,10 @@ import java.util.Map; @Ok("json:full") public class ActivityBasicUnitController { + private static final Log log = Logs.get(); + @Inject - private BaseService baseService; + private ActivityBasicUnitService activityBasicUnitService; @Inject private Dao dao; @@ -54,47 +45,29 @@ public class ActivityBasicUnitController { public void index() { } + /** + * @param parentId 树中选中的活动单位 ID,为空时返回空列表。 + * @param pageForm 分页参数和名称/编码筛选条件。 + * @return Result.data 为直属下级分页,包含 list、totalCount 等分页字段。 + */ @At @SaCheckPermission("activity.basic.unit") - public Result pageData(@Param(value = "parentId") String parentId, PageForm pageForm) { - Cnd cnd = Cnd.NEW(); - if (StrUtil.isBlank(parentId)) { - cnd.and("parentId", "=", "1"); - } else { - cnd.and("parentId", "=", parentId); - } - if (StrUtil.isNotBlank(pageForm.getSearchName()) && StrUtil.isNotBlank(pageForm.getSearchKeyword())) { - cnd.and(Cnd.likeEX(pageForm.getSearchName(), pageForm.getSearchKeyword())); - } - Sql sql = Sqls.create("select id,parentId,name,unitcode,unitLevel,unionId from activity_basic_unit $condition"); - cnd.asc("unitcode"); - sql.setCondition(cnd); - Pagination pagination = baseService.listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); - return Result.success(pagination); + public Result pageData(@Param("parentId") String parentId, PageForm pageForm) { + return Result.success(activityBasicUnitService.getUnitPage(parentId, pageForm)); } + /** + * @param pid 可选的活动单位 ID;不传时获取完整组织树。 + * @return Result.data 为节点数组,子节点统一放在 children 中。 + */ @At @SaCheckPermission("activity.basic.unit") public Result tree(@Param("pid") String pid) { try { - Cnd cnd = Cnd.NEW(); - cnd.andEX("id", "=", pid); - cnd.asc("unitcode"); - List list = baseService.dao().query(ActivityBasicUnit.class, cnd); - - List> nodeList = CollUtil.newArrayList(); - for (int i = 0; i < list.size(); i++) { - nodeList.add(new TreeNode<>(list.get(i).getId(), list.get(i).getParentId(), list.get(i).getName(), i) - .setExtra( - Map.of( - "unitTypeCode", list.get(i).getUnitTypeCode() - ) - )); - } - List> treeList = TreeUtil.build(nodeList, StrUtil.blankToDefault(pid, "0")); - return Result.success(treeList); + return Result.success(activityBasicUnitService.getUnitTree(pid)); } catch (Exception e) { - return Result.error(); + log.error("加载活动单位树失败,pid=" + pid, e); + return Result.error("加载活动单位树失败,请稍后重试"); } } diff --git a/src/main/java/com/budwk/app/zhgh/activity/basic/service/ActivityBasicUnitService.java b/src/main/java/com/budwk/app/zhgh/activity/basic/service/ActivityBasicUnitService.java new file mode 100644 index 0000000..498f8e5 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/basic/service/ActivityBasicUnitService.java @@ -0,0 +1,26 @@ +package com.budwk.app.zhgh.activity.basic.service; + +import cn.hutool.core.lang.tree.Tree; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.BaseService; +import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit; +import org.nutz.lang.util.NutMap; + +import java.util.List; + +/** 活动单位的组织树及直属下级查询,数据来源为 activity_basic_unit。 */ +public interface ActivityBasicUnitService extends BaseService { + /** + * @param pid 可选的活动单位 ID;为空返回全部根节点,否则返回该单位及其后代。 + * @return 树节点列表,包含 id、parentId、name、unitTypeCode 和 children;不存在的 ID 返回空列表。 + */ + List> getUnitTree(String pid); + + /** + * @param parentId 当前选中的活动单位 ID;为空返回空分页,避免查询到其他单位。 + * @param pageForm 页码、每页条数及查询条件;searchName 仅支持 name、unitcode。 + * @return 直属下级分页,list 包含 id、parentId、name、unitcode、unitLevel、unionId。 + */ + Pagination getUnitPage(String parentId, PageForm pageForm); +} diff --git a/src/main/java/com/budwk/app/zhgh/activity/basic/service/impl/ActivityBasicUnitServiceImpl.java b/src/main/java/com/budwk/app/zhgh/activity/basic/service/impl/ActivityBasicUnitServiceImpl.java new file mode 100644 index 0000000..b40d8c1 --- /dev/null +++ b/src/main/java/com/budwk/app/zhgh/activity/basic/service/impl/ActivityBasicUnitServiceImpl.java @@ -0,0 +1,90 @@ +package com.budwk.app.zhgh.activity.basic.service.impl; + +import cn.hutool.core.lang.tree.Tree; +import cn.hutool.core.lang.tree.TreeNode; +import cn.hutool.core.lang.tree.TreeUtil; +import cn.hutool.core.util.StrUtil; +import com.budwk.app.base.page.Pagination; +import com.budwk.app.base.param.PageForm; +import com.budwk.app.base.service.impl.BaseServiceImpl; +import com.budwk.app.zhgh.activity.basic.models.ActivityBasicUnit; +import com.budwk.app.zhgh.activity.basic.service.ActivityBasicUnitService; +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.util.NutMap; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** 按系统单位页的虚拟根规则组织活动单位,不修改数据库中的父级及工会归属。 */ +@IocBean(args = {"refer:dao"}) +public class ActivityBasicUnitServiceImpl extends BaseServiceImpl implements ActivityBasicUnitService { + public ActivityBasicUnitServiceImpl(Dao dao) { + super(dao); + } + + @Override + public List> getUnitTree(String pid) { + List units = query(Cnd.NEW().asc("unitcode")); + Set ids = units.stream().map(ActivityBasicUnit::getId).collect(Collectors.toSet()); + // 虚拟根只用于树构建;避开真实单位 ID,兼容空父级、孤立节点和自引用根节点。 + String rootId = "root"; + while (ids.contains(rootId)) { + rootId = "_" + rootId; + } + List> nodes = new ArrayList<>(); + for (int i = 0; i < units.size(); i++) { + ActivityBasicUnit unit = units.get(i); + String parentId = unit.getParentId(); + if (StrUtil.isBlank(parentId) || !ids.contains(parentId) || unit.getId().equals(parentId)) { + parentId = rootId; + } + // 旧活动单位类型可为空,展示时按“其他”处理,不回写数据,也不再触发 Map.of 的空值异常。 + nodes.add(new TreeNode<>(unit.getId(), parentId, unit.getName(), i) + .setExtra(NutMap.NEW().setv("unitTypeCode", unit.getUnitTypeCode() == null ? 0 : unit.getUnitTypeCode()))); + } + List> tree = TreeUtil.build(nodes, rootId); + if (tree == null) { + return Collections.emptyList(); + } + if (StrUtil.isBlank(pid)) { + return tree; + } + // 先构建完整树再截取指定节点,避免只查询节点自身而丢失其后代。 + ArrayDeque> pending = new ArrayDeque<>(tree); + while (!pending.isEmpty()) { + Tree node = pending.removeFirst(); + if (pid.equals(node.getId())) { + return Collections.singletonList(node); + } + if (node.getChildren() != null) { + pending.addAll(node.getChildren()); + } + } + return Collections.emptyList(); + } + + @Override + public Pagination getUnitPage(String parentId, PageForm pageForm) { + if (StrUtil.isBlank(parentId)) { + return new Pagination<>(pageForm.getPageNumber(), pageForm.getPageSize(), 0, Collections.emptyList()); + } + Cnd cnd = Cnd.where("parentId", "=", parentId).and("id", "!=", parentId); + cnd.asc("unitcode"); + // 查询字段限于页面提供的单位名称、编码;自引用根节点不应出现在自身的下级列表中。 + if (StrUtil.isNotBlank(pageForm.getSearchKeyword()) + && ("name".equals(pageForm.getSearchName()) || "unitcode".equals(pageForm.getSearchName()))) { + cnd.and(Cnd.likeEX(pageForm.getSearchName(), pageForm.getSearchKeyword())); + } + Sql sql = Sqls.create("select id,parentId,name,unitcode,unitLevel,unionId from activity_basic_unit $condition"); + sql.setCondition(cnd); + return listPageMap(pageForm.getPageNumber(), pageForm.getPageSize(), sql); + } +} diff --git a/src/main/resources/static/components/module/member/MemberCnd.vue b/src/main/resources/static/components/module/member/MemberCnd.vue index a60f02a..7be7139 100644 --- a/src/main/resources/static/components/module/member/MemberCnd.vue +++ b/src/main/resources/static/components/module/member/MemberCnd.vue @@ -4,7 +4,7 @@ column.COLUMN_NAME !== 'userAttribute' && column.COLUMN_COMMENT !== '人员属性') + } + }, watch: { cnd: { handler(val) { diff --git a/src/main/resources/views/platform/zhgh/activity/basic/unit/index.html b/src/main/resources/views/platform/zhgh/activity/basic/unit/index.html index 40ea9a9..3dac08e 100644 --- a/src/main/resources/views/platform/zhgh/activity/basic/unit/index.html +++ b/src/main/resources/views/platform/zhgh/activity/basic/unit/index.html @@ -2,29 +2,43 @@ layout("/layouts/platform.html"){ #--> +
- + -
+ +
@@ -77,7 +91,7 @@ layout("/layouts/platform.html"){ @@ -95,50 +109,99 @@ layout("/layouts/platform.html"){ data() { return { pageForm: { - searchName: "name" + searchName: "name", + parentId: "" }, treeData: [], + filterText: "", + defaultExpandedKeys: [], + treeLoading: false, + deleteLoading: false, currentTreeNode: null, currentTreeData: null } }, - components: {}, + watch: { + filterText(value) { + this.$refs.treeRef.filter(value) + } + }, methods: { - async doDelete(id) { - const confirm = await this.$confirm("确定要删除该单位吗?", "提示", { + doDelete(id) { + this.$confirm("确定要删除该单位吗?", "提示", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning" - }) - if (confirm === "confirm") { - const resp = await this.$axios.post(loc() + "/doDelete", { id }) - if (resp.code === 0) { - this.getTreeData() - this.doSearch() - this.$message.success(resp.msg) - } else { - this.notifyWarning(resp.msg) + }).then(() => { + this.deleteLoading = true + // 删除后统一刷新树,由树恢复选中节点并刷新直属下级,避免重复查询或保留已删除节点。 + return this.$axios.post(loc() + "/doDelete", { id }) + .then((res) => { + if (res.code === 0) { + this.$message.success(res.msg) + return this.getTreeData() + } + this.notifyWarning(res.msg) + }) + .finally(() => { + this.deleteLoading = false + }) + }).catch((error) => { + if (error !== "cancel" && error !== "close") { + this.notifyWarning("删除活动单位失败,请稍后重试") } - } + }) }, treeNodeClick(data, node) { this.currentTreeData = data this.currentTreeNode = node - this.pageForm.parentId = data.id + this.$set(this.pageForm, "parentId", data.id) + // 复用公共查询方法重置页码,列表始终对应当前选中单位的直属下级。 this.doSearch() }, - getTreeData() { - this.$axios.post(loc() + "/tree").then((res) => { - this.treeData = res.data - if (this.treeData) { - this.currentTreeData = this.treeData[0] - } - }) + filterNode(value, data) { + return !value || (data.name || "").indexOf(value) !== -1 }, - openUnit() {} + getTreeData() { + this.treeLoading = true + return this.$axios.post(loc() + "/tree") + .then((res) => { + if (res.code !== 0) { + this.notifyWarning(res.msg || "加载活动单位树失败") + return + } + this.treeData = res.data || [] + this.defaultExpandedKeys = this.treeData.length ? [this.treeData[0].id] : [] + return this.$nextTick(() => { + // 首次选中实际根节点;刷新时保留有效选中项,不再假定根单位 ID 为 1。 + const tree = this.$refs.treeRef + const selectedId = this.currentTreeData ? this.currentTreeData.id : null + const selectedNode = selectedId ? tree.getNode(selectedId) : null + const data = selectedNode ? selectedNode.data : this.treeData[0] + tree.filter(this.filterText) + tree.setCurrentKey(data ? data.id : null) + if (data) { + this.treeNodeClick(data, tree.getNode(data.id)) + } else { + // 空树直接清空旧列表,避免显示刷新前的单位数据。 + this.currentTreeData = null + this.currentTreeNode = null + this.$set(this.pageForm, "parentId", "") + this.$set(this.pageForm, "pageNumber", 1) + this.$set(this.pageForm, "totalCount", 0) + this.tableData = [] + } + }) + }) + .catch(() => { + this.notifyWarning("加载活动单位树失败,请稍后重试") + }) + .finally(() => { + this.treeLoading = false + }) + } }, created() { - this.pageData() this.getTreeData() } }) diff --git a/src/main/resources/views/platform/zhgh/staffbenefit/blessing/blessingUser.html b/src/main/resources/views/platform/zhgh/staffbenefit/blessing/blessingUser.html index fa9051f..22dbfcb 100644 --- a/src/main/resources/views/platform/zhgh/staffbenefit/blessing/blessingUser.html +++ b/src/main/resources/views/platform/zhgh/staffbenefit/blessing/blessingUser.html @@ -51,9 +51,9 @@ layout("/layouts/platform.html"){
- +
@@ -64,7 +64,7 @@ layout("/layouts/platform.html"){ - +
@@ -144,6 +144,7 @@ layout("/layouts/platform.html"){