This commit is contained in:
2026-03-12 15:05:24 +08:00
parent 58c24fc7d0
commit 9ce85395fd
9 changed files with 127 additions and 82 deletions
@@ -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();
@@ -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<NutMap> sysUsers = userSql.getList(NutMap.class);
@@ -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<Sys_user> userList = dao().query(Sys_user.class, Cnd.where("loginname", "=", "20010021"));
List<String> 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");
}
}
@@ -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;
}
</style>
</style>
@@ -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;
}
</style>
.custom-desc .el-descriptions-item__label {
width: 15% !important;
}
</style>
@@ -1,5 +1,6 @@
<template>
<el-card shadow="never" style="position:relative;">
<div class="d-search-item btn-group tool-button">
<el-input placeholder="请输入内容" clearable v-model="page.searchKeyword"
@keyup.enter.native="$emit('doSearch')">
@@ -65,6 +66,7 @@
<div class="btn-group tool-button" style="margin-left: 10px">
<el-button type="primary" icon="el-icon-search" @click="$emit('search')"></el-button>
</div>
</div>
@@ -110,7 +112,7 @@ module.exports = {
default: true
},
audit: {
type: String,
type: Boolean,
default: true
},
title: {
@@ -181,4 +183,4 @@ module.exports = {
top: 0;
right: 10px;
}
</style>
</style>
@@ -39,7 +39,7 @@ layout("/layouts/platform.html"){
<proposal-search :page="pageForm" @search="doSearch"></proposal-search>
<el-card shadow="never" class="mt20">
<table-tool label="提案委员会立案审核" :app="this">
<table-tool label="提案委主任、秘书提交上会讨论结果" :app="this">
<template #func>
<el-button @click="mergeAudit"
:disabled="multipleSelection && multipleSelection.length >=2 ? false : true"
@@ -133,7 +133,7 @@ layout("/layouts/platform.html"){
</template>
<template #edit>
<proposal-info ref="audit" label="提案委员会立案审核" handle>
<proposal-info ref="audit" label="提案委主任、秘书提交上会讨论结果" handle>
<template #handle>
<el-form :model="formData" ref="auditForm" :rules="formRules" label-width="120px">
<!-- <vi-title title="审核信息"></vi-title>-->
@@ -808,4 +808,4 @@ layout("/layouts/platform.html"){
<!--#
}
#-->
#-->
@@ -310,4 +310,4 @@ layout("/layouts/platform.html"){
<!--#
}
#-->
#-->
@@ -9,7 +9,7 @@ layout("/layouts/platform.html"){
<proposal-search :page="pageForm" @search="doSearch"></proposal-search>
<el-card shadow="never" class="mt20">
<table-tool label="预审核" :app="this">
<table-tool label="提案委秘书、主任审核" :app="this">
<template #func>
<!--# if(@shiro.hasRole('jdhdbt01')){ #-->
<!-- <el-button v-if="!pageForm.isAudit" type="primary" size="small"-->
@@ -62,7 +62,7 @@ layout("/layouts/platform.html"){
</template>
<template #edit>
<proposal-info ref="audit" label="预审核" handle>
<proposal-info ref="audit" label="提案委秘书、主任审核" handle>
<template #handle>
<el-form :model="formData" ref="auditForm" :rules="formRules" label-width="120px">
<vi-title title="审核信息"></vi-title>
@@ -238,4 +238,4 @@ layout("/layouts/platform.html"){
<!--#
}
#-->
#-->