diff --git a/src/main/java/io/v/nutz/proposal/constants/ProposalAuditEnum.java b/src/main/java/io/v/nutz/proposal/constants/ProposalAuditEnum.java index b7d9e18..8d1141f 100644 --- a/src/main/java/io/v/nutz/proposal/constants/ProposalAuditEnum.java +++ b/src/main/java/io/v/nutz/proposal/constants/ProposalAuditEnum.java @@ -86,7 +86,7 @@ public enum ProposalAuditEnum { String subTitle = createUser.getUsername() + "邀请您提案查阅"; // 参与审核人员 - /*Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" + + Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" + " where sur.roleId in (@roleId)"); userSql.params().set("roleId", Arrays.asList(Roles.WYH_ZR, Roles.tmanage)); userSql.setCallback(Sqls.callback.maps()); @@ -102,16 +102,9 @@ public enum ProposalAuditEnum { subTitle, createUser.getId(), userIds, - Globals.AppDomain + "/platform/proposal/transact/case/case?proposalId=" + info.getId(), - Globals.AppDomain + "/platform/proposal/transact/case/case");*/ - auditInstanceService.createTask(OaBusinessTypeEnum.COMMITTEE_READ, - info.getId(), - title, - subTitle, - createUser.getId(), - List.of("20010021"), - Globals.AppDomain + "/platform/proposal/transact/caseRead?proposalId=" + info.getId(), - Globals.AppDomain + "/platform/proposal/transact/caseRead"); + Globals.AppDomain + "/platform/proposal/transact/preAudit?proposalId=" + info.getId(), + Globals.AppDomain + "/platform/proposal/transact/preAudit"); + } }catch (Exception e) { e.printStackTrace(); diff --git a/src/main/java/io/v/nutz/proposal/controller/transact/CaseReadController.java b/src/main/java/io/v/nutz/proposal/controller/transact/CaseReadController.java index d629da9..2448329 100644 --- a/src/main/java/io/v/nutz/proposal/controller/transact/CaseReadController.java +++ b/src/main/java/io/v/nutz/proposal/controller/transact/CaseReadController.java @@ -206,7 +206,7 @@ public class CaseReadController { Sql userSql = Sqls.create("select su.* from sys_user su left join sys_user_role sur on su.id = sur.userid" + " where sur.roleId in (@roleId)"); - userSql.params().set("roleId", Arrays.asList(Roles.tmanage)); + userSql.params().set("roleId", Arrays.asList(Roles.WYH_ZR,Roles.tmanage)); userSql.setCallback(Sqls.callback.maps()); dao.execute(userSql); List sysUsers = userSql.getList(NutMap.class); diff --git a/src/main/java/io/v/nutz/proposal/services/impl/ProposalProposalPreAuditServiceImpl.java b/src/main/java/io/v/nutz/proposal/services/impl/ProposalProposalPreAuditServiceImpl.java index af49cb5..576f9bb 100644 --- a/src/main/java/io/v/nutz/proposal/services/impl/ProposalProposalPreAuditServiceImpl.java +++ b/src/main/java/io/v/nutz/proposal/services/impl/ProposalProposalPreAuditServiceImpl.java @@ -3,6 +3,8 @@ package io.v.nutz.proposal.services.impl; import cn.hutool.core.util.StrUtil; import cn.wizzer.framework.page.Pagination; import io.v.nutz.modules.models.PageForm; +import io.v.nutz.oa.enums.OaBusinessTypeEnum; +import io.v.nutz.oa.service.IOaAuditInstanceService; import io.v.nutz.proposal.constants.ProposalState; import io.v.nutz.proposal.constants.ProposalStateDirectionEnum; import io.v.nutz.proposal.models.ProposalAudit; @@ -13,6 +15,8 @@ import io.v.nutz.proposal.services.ProposalInfoService; import io.v.nutz.proposal.services.ProposalPreAuditService; import io.v.nutz.proposal.services.ProposalProcessService; import io.v.nutz.service.impl.ViServiceImpl; +import io.v.nutz.sys.models.Sys_user; +import io.v.nutz.web.commons.base.Globals; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; @@ -26,6 +30,7 @@ import org.nutz.lang.Lang; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @IocBean(args = {"refer:dao"}) public class ProposalProposalPreAuditServiceImpl extends ViServiceImpl implements ProposalPreAuditService { @@ -40,6 +45,9 @@ public class ProposalProposalPreAuditServiceImpl extends ViServiceImpl implement @Inject private ProposalProcessService proposalProcessService; + @Inject + private IOaAuditInstanceService auditInstanceService; + @Override public Pagination pageData(PageForm page, ProposalSearch search) { Sql sql = Sqls.create(""" @@ -109,5 +117,19 @@ public class ProposalProposalPreAuditServiceImpl extends ViServiceImpl implement Chain chain = Chain.make("preAuditId", preAuditId); chain.add("stateCode", newStateCode); dao().update(ProposalInfo.class, chain, Cnd.where("id", "=", proposalId)); + + Sys_user createUser = dao().fetch(Sys_user.class, proposalInfo.getCreateUser()); + String title = "提案委成员审核-" + proposalInfo.getProposalName() + "(" + proposalInfo.getProposalCode() + "[" + createUser.getUsername() + "]" + ")"; + String subTitle = createUser.getUsername() + "邀请您提案审核"; + List userList = dao().query(Sys_user.class, Cnd.where("loginname", "=", "20010021")); + List userIds = userList.stream().map(Sys_user::getId).collect(Collectors.toList()); + auditInstanceService.createTask(OaBusinessTypeEnum.COMMITTEE_READ, + proposalInfo.getId(), + title, + subTitle, + createUser.getId(), + userIds, + Globals.AppDomain + "/platform/proposal/transact/caseRead?proposalId=" + proposalInfo.getId(), + Globals.AppDomain + "/platform/proposal/transact/caseRead"); } } diff --git a/src/main/resources/static/components/plugins/ELTabPlus.vue b/src/main/resources/static/components/plugins/ELTabPlus.vue index 23e4d1f..ec85a6f 100644 --- a/src/main/resources/static/components/plugins/ELTabPlus.vue +++ b/src/main/resources/static/components/plugins/ELTabPlus.vue @@ -42,70 +42,70 @@ module.exports = { }, methods: { jump(tab, event) { - let target = document.querySelector('.scroll-content') - let scrollItems = document.querySelectorAll('.scroll-item') - // 判断滚动条是否滚动到底部 - if (target.scrollHeight <= target.scrollTop + target.clientHeight) { - this.tabIndex = tab.index.toString() - } - let totalY = scrollItems[tab.index].offsetTop - scrollItems[0].offsetTop // 锚点元素距离其offsetParent(这里是body)顶部的距离(待滚动的距离) - let distance = document.querySelector('.scroll-content').scrollTop // 滚动条距离滚动区域顶部的距离 - // let distance = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset // 滚动条距离滚动区域顶部的距离(滚动区域为窗口) - // 滚动动画实现, 使用setTimeout的递归实现平滑滚动,将距离细分为50小段,10ms滚动一次 - // 计算每一小段的距离 - let step = totalY / 50 - if (totalY > distance) { - smoothDown(document.querySelector('.scroll-content')) - } else { - let newTotal = distance - totalY - step = newTotal / 50 - smoothUp(document.querySelector('.scroll-content')) - } + const container = this.$el.querySelector('.scroll-content') + const scrollItems = this.$el.querySelectorAll('.scroll-item') - // 参数element为滚动区域 - function smoothDown(element) { - if (distance < totalY) { - distance += step - element.scrollTop = distance - setTimeout(smoothDown.bind(this, element), 10) - } else { - element.scrollTop = totalY - } - } + if (!container || !scrollItems.length) return - // 参数element为滚动区域 - function smoothUp(element) { - if (distance > totalY) { - distance -= step - element.scrollTop = distance - setTimeout(smoothUp.bind(this, element), 10) - } else { - element.scrollTop = totalY - } - } + const targetIndex = Number(tab.index) + const targetTop = scrollItems[targetIndex].offsetTop - scrollItems[0].offsetTop - console.log(this.tabName) + // ✅ 设置标志位,锁定 tab 不被 onScroll 覆盖 + this.isJumping = true + this.tabName = this.tabs[targetIndex]?.refName + container.scrollTo({ + top: targetTop, + behavior: 'smooth' + }) + + // ✅ 滚动动画结束后解锁(smooth 滚动大约 300~500ms) + clearTimeout(this._jumpTimer) + this._jumpTimer = setTimeout(() => { + this.isJumping = false + }, 500) }, + onScroll(e) { - if (e.target.scrollTop === 0) { - this.tabName = this.tabs[0].refName + // ✅ jump 期间不处理滚动联动 + if (this.isJumping) return + + const container = e.target + const { scrollTop, scrollHeight, clientHeight } = container + + // 1. 滚动到底部 + if (scrollTop + clientHeight >= scrollHeight - 1) { + const lastIndex = this.tabs.length - 1 + if (this.tabIndex !== lastIndex) { + this.tabIndex = lastIndex + this.tabName = this.tabs[lastIndex]?.refName + } return } - $('#app > div.guava-main-content > span > div.el-card').each((idx, item) => { - if ($(item).is(':visible')) { - const scrollItems = $(item).find('.scroll-item') - for (let i = scrollItems.length - 1; i >= 0; i--) { - let judge = e.target.scrollTop >= scrollItems[i].offsetTop - scrollItems[0].offsetTop - 300 - if (judge) { - this.tabIndex = i.toString() - this.tabName = this.tabs[this.tabIndex].refName - break - } - } + // 2. 顶部 + if (scrollTop === 0) { + if (this.tabIndex !== 0) { + this.tabIndex = 0 + this.tabName = this.tabs[0]?.refName } - }) + return + } + + // 3. 中间区域 + const scrollItems = this.$el.querySelectorAll('.scroll-item') + const threshold = 100 + + for (let i = scrollItems.length - 1; i >= 0; i--) { + const itemTop = scrollItems[i].offsetTop - scrollItems[0].offsetTop + if (scrollTop + threshold >= itemTop) { + if (this.tabIndex !== i) { + this.tabIndex = i + this.tabName = this.tabs[i]?.refName + } + break + } + } }, scrollEnd() { @@ -121,7 +121,29 @@ module.exports = { this.tabName = 'audit' }, 250) }) - } + }, + scrollToTop() { + const tryScroll = () => { + const scrollEl = this.$el.querySelector('.scroll-content') + if (!scrollEl) return + + // 检查内容是否已渲染(scrollHeight > clientHeight 说明有滚动空间) + if (scrollEl.scrollHeight <= scrollEl.clientHeight) { + // 内容还没加载完,100ms 后重试 + setTimeout(tryScroll, 100) + return + } + + // ✅ 内容就绪,执行滚动 + scrollEl.scrollTo({top: 0, behavior: 'auto'}) + this.tabIndex = 0 + this.tabName = this.tabs[0]?.refName + } + + this.$nextTick(() => { + setTimeout(tryScroll, 200) + }) + }, }, created() { @@ -206,4 +228,4 @@ module.exports = { color: #fff; } - \ No newline at end of file + diff --git a/src/main/resources/static/components/proposal/ProposalInfo.vue b/src/main/resources/static/components/proposal/ProposalInfo.vue index 2062e23..20182c4 100644 --- a/src/main/resources/static/components/proposal/ProposalInfo.vue +++ b/src/main/resources/static/components/proposal/ProposalInfo.vue @@ -1058,14 +1058,14 @@ module.exports = { if (this.viewData.delegationAudit && this.viewData.delegationAudit.length > 0) { tabs.push({name: '团长审核', refName: 'delegation-audit-info'}) } - if (proposal.enableState.some(v => v.stateCode === proposal.PREAUDIT)) { - tabs.push({name: '预审核', refName: 'pre-audit-info'}) + if (this.viewData.preAudit && this.viewData.preAudit.length > 0) { + tabs.push({name: '提案委秘书、主任审核', refName: 'pre-audit-info'}) } if (this.viewData.membersOpinions && this.viewData.membersOpinions.length > 0) { tabs.push({name: '委员会成员意见', refName: 'members-audit-info'}) } if (this.viewData.caseAuditId && this.viewData.caseAudit) { - tabs.push({name: '提案委员会立案', refName: 'case-audit-info'}) + tabs.push({name: '提案委主任、秘书提交上会讨论结果', refName: 'case-audit-info'}) } if (this.viewData.underTakeFirstOpinion && this.viewData.underTakeFirstOpinion.length > 0) { tabs.push({name: '承办单位初步意见', refName: 'undertake-first-audit-info'}) @@ -1107,7 +1107,9 @@ module.exports = { this.$refs.etp.scrollEnd() } } else { - this.$refs.etp.tabName = tabs[0].refName + if (this.$refs.etp) { + this.$refs.etp.scrollToTop() + } } this.tabs = tabs @@ -1228,4 +1230,8 @@ module.exports = { height: 15px; } - \ No newline at end of file +.custom-desc .el-descriptions-item__label { + width: 15% !important; + +} + diff --git a/src/main/resources/static/components/proposal/ProposalSearch.vue b/src/main/resources/static/components/proposal/ProposalSearch.vue index f63355c..38264e3 100644 --- a/src/main/resources/static/components/proposal/ProposalSearch.vue +++ b/src/main/resources/static/components/proposal/ProposalSearch.vue @@ -1,5 +1,6 @@