人员数据治理模块迁移1.0

This commit is contained in:
2026-10-12 15:31:53 +08:00
parent 8fd7eeac11
commit e539f6af36
9 changed files with 128 additions and 39 deletions
@@ -2,31 +2,23 @@
.person-governance-page-transition {
visibility: hidden;
opacity: 0;
transform: translateY(6px);
transition:
opacity 220ms ease,
transform 220ms ease,
visibility 0s linear 220ms;
}
.person-governance-page-transition.is-ready {
visibility: visible;
opacity: 1;
transform: translateY(0);
transition-delay: 0s;
}
.person-governance-page-transition.is-leaving {
pointer-events: none;
opacity: 0;
transform: translateY(3px);
}
.person-governance-list-page {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: calc(100vh - 50px);
height: 100%;
min-height: 0;
overflow: hidden;
padding: 10px;
@@ -58,6 +50,7 @@
.person-governance-table-wrap {
flex: 1;
min-height: 0;
overflow: hidden;
}
.person-governance-table-wrap > .el-table {
@@ -69,12 +62,52 @@
flex: none;
}
/* 人员变更列表位于 Guava 默认插槽内,列表视图仍按查询区、表格区、分页区分配固定高度。 */
.person-governance-change-page > .guava-main-content,
.person-governance-change-page > .guava-main-content > .transition-item {
height: 100%;
min-height: 0;
overflow: hidden;
}
.person-governance-change-page > .guava-main-content > .transition-item {
display: flex;
flex-direction: column;
}
.person-governance-change-list-card {
flex: 1;
min-height: 0;
}
.person-governance-change-list-card > .el-card__body {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
}
.person-governance-change-table-wrap {
flex: 1;
min-height: 0;
overflow: hidden;
}
.person-governance-change-table-wrap > .el-table {
height: 100%;
}
.person-governance-change-list-card .el-pagination-container {
flex: none;
}
/* 配置页顶部字段根据内容区宽度自动分列,空间不足时自然换行。 */
.person-governance-form-page {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: calc(100vh - 50px);
height: 100%;
max-width: 100%;
min-height: 0;
overflow-x: hidden;
@@ -291,6 +324,9 @@
}
.person-governance-form-footer {
display: flex;
align-items: center;
justify-content: flex-end;
flex: none;
margin-top: 10px;
}
@@ -70,7 +70,8 @@ const initTableMixins = {
pageData(data = null) {
const address = this.pageDataUrl ? this.pageDataUrl : loc() + "/pageData"
this.tableLoading = true
this.$axios.post(address, data ? data : this.pageForm).then((res) => {
// 返回请求 Promise,供页面在列表数据加载结束后再显示主体内容。
return this.$axios.post(address, data ? data : this.pageForm).then((res) => {
if (res.code === 0) {
this.tableData = res.data.list
this.pageForm.totalCount = res.data.totalCount
@@ -399,6 +399,14 @@ layout("/layouts/v4/baseLayout.html"){
// 默认选中
getMenuOwnerPath() {
const pathname = window.location.pathname
// API配置表单不是独立菜单,直接刷新表单地址时仍归属API配置菜单。
if (pathname === "/platform/personGovernance/apiConfig/form") {
return "/platform/personGovernance/apiConfig"
}
// 会员匹配表单不是独立菜单,直接刷新表单地址时仍归属会员匹配菜单。
if (pathname === "/platform/personGovernance/memberMatch/form") {
return "/platform/personGovernance/memberMatch"
}
if (pathname === "/platform/qsv/survey/reportPage") {
return "/platform/qsv/survey"
}
@@ -409,6 +417,12 @@ layout("/layouts/v4/baseLayout.html"){
},
getMenuOwnerFullPath() {
if (window.location.pathname === "/platform/personGovernance/apiConfig/form") {
return "/platform/personGovernance/apiConfig"
}
if (window.location.pathname === "/platform/personGovernance/memberMatch/form") {
return "/platform/personGovernance/memberMatch"
}
if (window.location.pathname === "/platform/qsv/survey/reportPage") {
return "/platform/qsv/survey"
}
@@ -1,5 +1,5 @@
<!--# layout("/layouts/platform.html"){ #-->
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.20" />
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.24" />
<div
id="app"
v-cloak
@@ -439,8 +439,10 @@
</el-dialog>
</div>
<script>
// 使用独立作用域承载页面常量和实例,支持表单页通过 PJAX 多次进入而不发生重复声明。
;(() => {
const apiBase = '/platform/personGovernance/apiConfig'
const vue = new Vue({
new Vue({
el: '#app',
mixins: [initTableMixins],
// platform布局已加载本地vCrontab资源,页面仅注册组件,不重复引入脚本。
@@ -1060,10 +1062,11 @@
leavePage(url) {
this.$set(this, 'pageLeaving', true)
window.setTimeout(() => {
window.location.href = url
// 仅替换右侧内容区域,返回列表时不销毁或重新请求左侧菜单。
commonUtil.pjaxPush(url)
}, 180)
},
// 使用完整页面返回,避免 PJAX 重复加载后台公共脚本;跳转前先柔和淡出当前页面。
// 使用 PJAX 返回列表,并保留跳转前的页面淡出效果。
back() {
this.leavePage(apiBase)
},
@@ -1086,6 +1089,7 @@
})
},
})
})()
</script>
<!--# } #-->
@@ -1,5 +1,5 @@
<!--# layout("/layouts/platform.html"){ #-->
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.6" />
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.22" />
<div
id="app"
v-cloak
@@ -91,7 +91,9 @@
</el-dialog>
</div>
<script>
const vue = new Vue({
// 使用独立作用域承载页面实例,避免列表页与表单页通过 PJAX 反复切换时重复声明顶层变量。
;(() => {
new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
@@ -157,10 +159,11 @@
leavePage(url) {
this.$set(this, 'pageLeaving', true)
window.setTimeout(() => {
window.location.href = url
// 仅替换右侧内容区域,保留左侧导航实例及已经加载的菜单数据。
commonUtil.pjaxPush(url)
}, 180)
},
// 表单页使用完整页面跳转,避免 PJAX 重复执行公共脚本中的顶层常量声明。
// 弹窗关闭后通过 PJAX 打开表单页,避免整个后台布局重新加载。
create(type) {
// 关闭期间忽略重复选择;仅记录目标类型,由closed事件统一触发跳转。
if (!this.typeVisible || this.pendingCreateType || this.pageLeaving) {
@@ -193,6 +196,7 @@
})
},
})
})()
</script>
<!--# } #-->
@@ -1,5 +1,5 @@
<!--# layout("/layouts/platform.html"){ #-->
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.21" />
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.24" />
<div
id="app"
v-cloak
@@ -253,6 +253,8 @@
</div>
</script>
<script>
// 使用独立作用域承载页面常量、组件和实例,避免 PJAX 多次进入时重复声明。
;(() => {
const apiBase = '/platform/personGovernance/apiConfig'
const memberBase = '/platform/personGovernance/memberMatch'
Vue.component('member-condition-group', {
@@ -310,7 +312,7 @@
},
},
})
const vue = new Vue({
new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
@@ -613,10 +615,11 @@
leavePage(url) {
this.$set(this, 'pageLeaving', true)
window.setTimeout(() => {
window.location.href = url
// 仅替换右侧内容区域,返回列表时不销毁或重新请求左侧菜单。
commonUtil.pjaxPush(url)
}, 180)
},
// 使用完整页面返回,避免 PJAX 重复加载后台公共脚本;跳转前先柔和淡出当前页面。
// 使用 PJAX 返回列表,并保留跳转前的页面淡出效果。
back() {
this.leavePage(memberBase)
},
@@ -634,6 +637,7 @@
})
},
})
})()
</script>
<!--# } #-->
@@ -1,5 +1,5 @@
<!--# layout("/layouts/platform.html"){ #-->
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.17" />
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.23" />
<div
id="app"
v-cloak
@@ -76,7 +76,9 @@
</el-drawer>
</div>
<script>
const vue = new Vue({
// 使用独立作用域承载页面实例,支持列表与表单通过 PJAX 反复切换。
;(() => {
new Vue({
el: '#app',
mixins: [initTableMixins],
data() {
@@ -133,10 +135,11 @@
leavePage(url) {
this.$set(this, 'pageLeaving', true)
window.setTimeout(() => {
window.location.href = url
// 仅替换右侧内容区域,避免重新初始化平台布局和左侧菜单。
commonUtil.pjaxPush(url)
}, 180)
},
// 表单页使用完整页面跳转,避免 PJAX 重复执行公共脚本中的顶层常量声明。
// 进入新增或编辑页时保留人员数据治理模块的左侧菜单。
create() {
this.leavePage('/platform/personGovernance/memberMatch/form')
},
@@ -188,6 +191,7 @@
})
},
})
})()
</script>
<!--# } #-->
@@ -1,9 +1,15 @@
<!--#
layout("/layouts/platform.html"){
#-->
<div id="app" v-cloak>
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.22" />
<div
id="app"
v-cloak
class="person-governance-list-page person-governance-change-page person-governance-page-transition"
:class="{'is-ready':pageReady}"
>
<guava ref="guava">
<el-card shadow="never">
<el-card shadow="never" class="person-governance-search-card">
<search @search="doSearch">
<search-item label="姓名/工号">
<el-input placeholder="请输入姓名或工号" clearable v-model="pageForm.searchKeyword"></el-input>
@@ -64,7 +70,7 @@ layout("/layouts/platform.html"){
</search>
</el-card>
<el-card shadow="never" class="mt10">
<el-card shadow="never" class="mt10 person-governance-change-list-card">
<table-tool label="人员列表(工会小组或分工会提交的变更还需校工会审核)">
<el-button :disabled="!checkUsers.length" @click="openBatchEditMember" class="ml5" icon="el-icon-edit"
size="small" type="primary">
@@ -148,8 +154,9 @@ layout("/layouts/platform.html"){
</table-tool>
<div class="person-governance-change-table-wrap">
<el-table :data="tableData" :size="tableSize" @selection-change="tableHandleSelectionChange" @sort-change="pageOrder"
class="vi-table" ref="table" row-key="id" style="width: 100%">
class="vi-table" ref="table" row-key="id" style="width: 100%" height="100%">
<el-table-column :reserve-selection="true" type="selection"></el-table-column>
<el-table-column :index="indexMethod" align="center" header-align="center"
label="序号" type="index" width="80px" fixed="left"></el-table-column>
@@ -227,6 +234,7 @@ layout("/layouts/platform.html"){
</template>
</el-table-column>
</el-table>
</div>
<!--#include("/layouts/pagination.html"){}#-->
</el-card>
@@ -490,6 +498,7 @@ layout("/layouts/platform.html"){
store,
mixins: [initTableMixins],
data: {
pageReady: false,
pickerOptions: {
shortcuts: [{
text: '最近一周',
@@ -611,6 +620,16 @@ layout("/layouts/platform.html"){
pageData(data = null) {
return initTableMixins.methods.pageData.call(this, this.buildQueryPageForm(data || this.pageForm))
},
showPage() {
this.$nextTick(() => {
if (this.$refs.table && this.$refs.table.doLayout) {
this.$refs.table.doLayout()
}
window.requestAnimationFrame(() => {
this.$set(this, "pageReady", true)
})
})
},
dropdownCommand(command) {
const {type, data} = command
if (type === 'view') {
@@ -685,7 +704,7 @@ layout("/layouts/platform.html"){
initData() {
const isAdmin = this.$auth.hasRoleOr(["SYSADMIN", "SCHOOL_UNION_ADMIN"])
const unionId = isAdmin ? this.pageForm.unionId : this.$store.state.user.union.id
Promise.all([
return Promise.all([
this.$businessTool.listUnion(unionId),
this.$businessTool.getEnumOptions("MemberChangeType"),
this.$businessTool.getDictOptions("ALLOW_CHANGE_FIELDS")
@@ -913,8 +932,10 @@ layout("/layouts/platform.html"){
this.$set(this, "checkedFields", this.tableColumns.filter(c => c.checked !== 0).map(c => c.prop));
},
created() {
this.initData()
this.pageData()
// 单位、字典和列表请求全部结束后再显示页面,避免初始化过程中的布局跳动。
$.when(this.initData(), this.pageData()).always(() => {
this.showPage()
})
}
})
</script>
@@ -1,5 +1,5 @@
<!--# layout("/layouts/platform.html"){ #-->
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.6" />
<link rel="stylesheet" href="${base!}/assets/platform/css/personGovernance.css?v=1.0.22" />
<div
id="app"
v-cloak
@@ -18,7 +18,7 @@
:closable="false"
></el-alert>
<el-form class="mt20" :inline="true" :model="pageForm">
<el-form-item label="职工信息">
<el-form-item>
<el-input
v-model="pageForm.searchKeyword"
clearable
@@ -394,13 +394,14 @@
},
},
created() {
const unitRequest = getUnits().then((rows) => {
// 当前项目通过 businessTool 获取单位和人员字典,避免依赖原项目 v.js 中不存在的全局方法。
const unitRequest = this.$businessTool.listUnit().then((rows) => {
this.$set(this, 'units', rows)
})
const personTypeRequest = getDictOptions('UserType').then((rows) => {
const personTypeRequest = this.$businessTool.getDictOptions('USER_PERSON_TYPE').then((rows) => {
this.$set(this, 'personTypeOptions', rows)
})
const userStateRequest = getDictOptions('UserState').then((rows) => {
const userStateRequest = this.$businessTool.getDictOptions('USER_STATE').then((rows) => {
this.$set(this, 'userStateOptions', rows)
})
$.when(this.pageData(), unitRequest, personTypeRequest, userStateRequest).always(() => {