Files
zhgh_zjvtit/target/classes/static/components/module/activity/UserScope.vue
T
2026-08-26 14:25:17 +08:00

852 lines
27 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="user-scope">
<template>
<el-card shadow="never">
<el-row class="query-row">
<el-col class="query-title">姓名/工号</el-col>
<el-col class="query-content">
<el-select
v-model="pageForm.userId"
clearable
collapse-tags
filterable
multiple
remote
placeholder="输入工号或者姓名查询"
:remote-method="queryUser"
@change="doSearch"
@clear="doSearch"
style="width: 100%"
>
<el-option
v-for="item in userList"
:key="item.id"
:label="item.username + '(' + item.loginname + ')'"
:value="item.id"
></el-option>
</el-select>
</el-col>
</el-row>
<el-row class="query-row" v-if="is_A06 || is_sysadmin || is_H02">
<el-col class="query-title">会员类型</el-col>
<el-col class="query-content">
<el-tag
v-for="item in memberTypeOptions"
:key="item.code"
:effect="pageForm.memberTypes.includes(item.name) ? 'dark' : 'plain'"
@click="tagClick('memberTypes', item.name)"
style="margin-right: 10px; cursor: pointer"
>
{{ item.name }}
</el-tag>
</el-col>
</el-row>
<el-row class="query-row">
<el-col class="query-title">性别</el-col>
<el-col class="query-content">
<el-tag
v-for="item in sexTypeOptions"
:key="item.code"
:effect="pageForm.sexTypes.includes(item.name) ? 'dark' : 'plain'"
@click="tagClick('sexTypes', item.name)"
style="margin-right: 10px; cursor: pointer"
>
{{ item.name }}
</el-tag>
</el-col>
</el-row>
<el-row class="query-row" v-if="is_A06 || is_sysadmin || is_H04">
<el-col class="query-title">年龄范围</el-col>
<el-col class="query-content">
<el-row type="flex" style="align-items: center">
<el-col :span="15">
<el-slider v-model="pageForm.age" range show-stops :max="100"></el-slider>
</el-col>
<el-col :span="9" class="pl20">当前范围{{ pageForm.age }}</el-col>
</el-row>
</el-col>
</el-row>
<el-row class="query-row" v-if="is_A06 || is_sysadmin || is_H04">
<el-col class="query-title">教职工类别</el-col>
<el-col class="query-content">
<el-tag
v-for="item in personTypeOptions"
:key="item.code"
:effect="pageForm.personTypes.includes(item.name) ? 'dark' : 'plain'"
@click="tagClick('personTypes', item.name)"
style="margin-right: 10px; cursor: pointer"
>
{{ item.name }}
</el-tag>
<el-link
v-if="personTypeOptions.length && pageForm.personTypes.length"
:underline="false"
type="danger"
@click="
pageForm.personTypes = []
doSearch()
"
>
清空
</el-link>
<el-link
:underline="false"
type="success"
@click="
pageForm.personTypes = personTypeOptions.map((item) => item.name)
doSearch()
"
>
全部
</el-link>
</el-col>
</el-row>
<el-row class="query-row" v-if="is_A06 || is_sysadmin || is_H04">
<el-col class="query-title">在职状态</el-col>
<el-col class="query-content">
<el-tag
v-for="item in userStateOptions"
:key="item.code"
:effect="pageForm.userStates.includes(item.name) ? 'dark' : 'plain'"
@click="tagClick('userStates', item.name)"
style="margin-right: 10px; cursor: pointer"
>
{{ item.name }}
</el-tag>
<el-link
v-if="userStateOptions.length && pageForm.userStates.length"
:underline="false"
type="danger"
@click="
pageForm.userStates = []
doSearch()
"
>
清空
</el-link>
<el-link
:underline="false"
type="success"
@click="
pageForm.userStates = userStateOptions.map((item) => item.name)
doSearch()
"
>
全部
</el-link>
</el-col>
</el-row>
<el-row class="query-row" v-if="is_A06 || is_sysadmin || is_H04">
<el-col class="query-title">工会查询</el-col>
<el-col class="query-content">
<el-select
v-model="pageForm.unionIds"
clearable
collapse-tags
filterable
multiple
placeholder="请选择分工会"
style="width: 100%"
@change="doSearch"
@clear="doSearch"
>
<el-option
v-for="item in unions"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-col>
</el-row>
<template v-if="is_A06 || is_sysadmin">
<el-row class="query-row">
<el-col class="query-title">系统角色</el-col>
<el-col class="query-content">
<el-row :gutter="20">
<el-col :span="12">
<el-select
v-model="pageForm.roleIds"
clearable
filterable
multiple
placeholder="请选择角色"
style="width: 100%"
@change="doSearch"
@clear="doSearch"
>
<el-option
v-for="item in roleList"
:key="item.id"
:label="item.name"
:value="item.id"
></el-option>
</el-select>
</el-col>
<el-col :span="12">
<el-select
v-model="pageForm.sessionId"
clearable
placeholder="请选择教代会"
style="width: 100%"
@change="doSearch"
@clear="doSearch"
>
<el-option
v-for="item in sessionOptions"
:key="item.id"
:label="item.fullName"
:value="item.id"
></el-option>
</el-select>
</el-col>
</el-row>
</el-col>
</el-row>
</template>
<el-row class="query-row" v-if="is_A06 || is_sysadmin || is_H02 || is_CLUB_PRESIDENT">
<el-col class="query-title">社团</el-col>
<el-col class="query-content">
<el-select
v-model="pageForm.clubId"
clearable
filterable
placeholder="请选择社团"
style="width: 100%"
@change="doSearch"
@clear="doSearch"
>
<el-option
v-for="item in clubOptions"
:key="item.id"
:label="item.clubName"
:value="item.id"
></el-option>
</el-select>
</el-col>
</el-row>
<el-row class="query-row">
<el-col class="query-title">活动组别</el-col>
<el-col class="query-content">
<el-select
v-model="pageForm.activityGroupId"
clearable
placeholder="请选择活动组别范围之外的人员"
style="width: 100%"
@change="handleActivityGroupChange"
@clear="handleActivityGroupChange('')"
>
<el-option
v-for="item in activityGroupList2"
:key="item.groupId"
:label="item.groupName"
:value="item.groupId"
></el-option>
</el-select>
</el-col>
</el-row>
<el-row class="query-row query-actions">
<el-checkbox
v-model="pageForm.reverseSelection"
border
class="reverseCheckBox"
label="是否反选"
@change="doSearch"
></el-checkbox>
<el-button type="danger" icon="el-icon-circle-close" @click="doReset">重置</el-button>
<el-button type="primary" icon="el-icon-search" :loading="tableLoading" @click="doSearch(true)">搜索</el-button>
</el-row>
</el-card>
<el-card class="mt10" shadow="never">
<table-tool label="筛选人员">
<el-button
v-if="is_sysadmin || is_A06"
type="primary"
size="medium"
icon="el-icon-printer"
@click="importDialogVisible = true"
>
导入XLSX设置分组
</el-button>
<el-button @click="doExportUser" size="medium" type="primary" icon="el-icon-download">
导出查询人员
</el-button>
<el-button @click="openSetDialog" size="medium" type="primary">
设置为活动人员
</el-button>
</table-tool>
<el-table
ref="userTable"
v-loading="tableLoading"
element-loading-text="正在查询请稍候..."
:data="tableData"
:size="tableSize"
@sort-change="pageOrder"
border
stripe
>
<el-table-column label="序号" type="index" width="80">
<template slot-scope="scope">
<span>{{ scope.$index + (pageForm.pageNumber - 1) * pageForm.pageSize + 1 }}</span>
</template>
</el-table-column>
<el-table-column
v-for="column in tableColumns"
:key="column.prop"
:label="column.label"
:prop="column.prop"
:sortable="column.sortable"
align="center"
header-align="center"
show-overflow-tooltip
></el-table-column>
</el-table>
<el-row class="el-pagination-container">
<el-pagination
@size-change="pageSizeChange"
@current-change="pageNumberChange"
:current-page="pageForm.pageNumber"
:page-size="pageForm.pageSize"
layout="total, prev, pager, next"
:total="pageForm.totalCount"
></el-pagination>
</el-row>
</el-card>
</template>
<el-dialog
:visible.sync="setDialogVisible"
title="设置活动人员"
width="45%"
:append-to-body="true"
:close-on-click-modal="false"
>
<el-form ref="setForm" :model="formData" :rules="rules" label-width="100px">
<el-form-item label="添加方式" prop="setGroupType">
<el-radio-group v-model="formData.setGroupType" size="small" @change="handleSetGroupModeChange">
<el-radio :label="1">添加至原有分组</el-radio>
<el-radio :label="2">添加到新分组</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="保存方式" prop="groupType">
<el-radio-group v-model="formData.groupType" size="small" @change="handleGroupTypeChange">
<el-radio :label="1">保存人员结果</el-radio>
<el-radio :label="2">保存SQL条件</el-radio>
</el-radio-group>
</el-form-item>
<el-row v-if="formData.setGroupType === 1">
<el-form-item label="原有分组" prop="setGroupId">
<el-radio-group v-model="formData.setGroupId" size="small" class="existing-group-radio-list">
<el-radio
v-for="item in sameTypeGroupList"
:key="item.groupId"
:label="item.groupId"
:disabled="!isSelectedActivityGroup(item)"
border
class="existing-group-radio"
>
{{ formatGroupDisplayName(item) }}
</el-radio>
</el-radio-group>
<div v-if="!selectedActivityGroup" class="form-tip">请先在筛选条件中选择活动组别</div>
<div v-else class="form-tip">仅允许添加至当前选择的活动组别{{ formatGroupDisplayName(selectedActivityGroup) }}</div>
</el-form-item>
</el-row>
<el-row v-if="formData.setGroupType === 2">
<el-form-item label="新分组" prop="setGroupName">
<el-input v-model="formData.setGroupName" placeholder="请输入新分组名称"></el-input>
</el-form-item>
</el-row>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="setDialogVisible = false">取消</el-button>
<el-button type="primary" @click="doSetActivityUser" v-loading="settingLoading">确定</el-button>
</span>
</el-dialog>
<el-dialog
:visible.sync="importDialogVisible"
title="设置活动人员"
width="45%"
:append-to-body="true"
:close-on-click-modal="false"
>
<activity-import-user
ref="importUserRef"
@clear_import_dialog="clearImportDialog"
@flush="flush"
do_import_url="/platform/activity/basic/scope/doImport"
:exists_login_name_redis_key="pageForm.existsLoginNameRedisKey"
></activity-import-user>
</el-dialog>
</div>
</template>
<script>
module.exports = {
props: {},
model: {},
mixins: [initTableMixins],
data() {
return {
userList: [],
clubOptions: [],
settingLoading: false,
setDialogVisible: false,
formData: {
setGroupType: 2,
setGroupId: null,
setGroupName: "",
groupType: 1
},
personTypeOptions: [],
userStateOptions: [],
activityGroupList: [],
activityGroupList2: [],
memberTypeOptions: [
{ code: "unionMember", name: "工会会员" },
{ code: "welfareMember", name: "福利会员" },
{ code: "sickFundMember", name: "基金会员" }
],
sexTypeOptions: [
{ code: "male", name: "男" },
{ code: "female", name: "女" }
],
pageForm: {
age: [0, 0],
unionIds: [],
clubId: "",
searchName: "u.username",
personTypes: [],
userStates: [],
memberStatus: [],
memberTypes: ["工会会员"],
sexTypes: [],
minAge: 0,
maxAge: 0,
year: moment().format("YYYY"),
module: "",
teacherMeetingId: "",
activityGroupId: "",
roleIds: [],
userId: [],
activityUserCnd: "",
reverseSelection: false
},
unions: [],
roleList: [],
tableHeight: "0px",
tableColumns: [
{ prop: "loginName", label: "工号" },
{ prop: "userName", label: "姓名" },
{ prop: "sex", label: "性别" },
{ prop: "birthday", label: "出生年月", sortable: true },
{ prop: "age", label: "年龄", sortable: true },
{ prop: "mobile", label: "联系电话" },
{ prop: "personType", label: "教职工类别", sortable: true },
{ prop: "userState", label: "在职状态", sortable: true },
{ prop: "unitName", label: "所属单位", sortable: true },
{ prop: "unionName", label: "所属工会", sortable: true }
],
rules: {
setGroupType: [{ required: true, message: "请选择添加方式", trigger: ["blur", "change"] }],
groupType: [{ required: true, message: "请选择保存方式", trigger: ["blur", "change"] }],
setGroupId: [{ required: true, message: "请选择分组", trigger: ["blur", "change"] }],
setGroupName: [{ required: true, message: "请输入分组名称", trigger: ["blur", "change"] }]
},
roleData: {},
importDialogVisible: false,
sessionOptions: []
}
},
computed: {
is_H10() {
return this.roleData.is_H10
},
is_A06() {
return this.roleData.is_A06
},
is_H04() {
return this.roleData.is_H04
},
is_H02() {
return this.roleData.is_H02
},
is_CLUB_PRESIDENT() {
return this.roleData.is_CLUB_PRESIDENT
},
is_sysadmin() {
return this.roleData.is_sysadmin
},
unionid() {
return this.roleData.unionid
},
selectedActivityGroup() {
return this.activityGroupList.find((item) => Number(item.groupId) === Number(this.pageForm.activityGroupId))
},
sameTypeGroupList() {
return this.activityGroupList.filter((item) => Number(item.groupType) === Number(this.formData.groupType))
}
},
components: {
"user-cnd": httpVueLoader("/components/plugins/UserCnd.vue"),
"activity-import-user": httpVueLoader("/components/module/activity/ActivityImportUser.vue?v=" + new Date().getTime())
},
methods: {
getDefaultFormData() {
return {
setGroupType: 2,
setGroupId: null,
setGroupName: "",
groupType: 1
}
},
getInitialUnionIds() {
// 分工会和社团双身份默认不带分工会筛选,保证初始列表走后端并集逻辑。
if ((this.is_sysadmin || this.is_A06 || this.is_H02 || this.is_CLUB_PRESIDENT) === false && this.is_H04 === true && this.unionid) {
return [this.unionid]
}
return []
},
normalizePageForm(pageForm) {
const form = clone(pageForm)
form.personTypes = JSON.stringify(form.personTypes)
form.userStates = JSON.stringify(form.userStates)
form.memberStatus = JSON.stringify(form.memberStatus)
form.memberTypes = JSON.stringify(form.memberTypes)
form.sexTypes = JSON.stringify(form.sexTypes)
form.roleIds = JSON.stringify(form.roleIds)
form.userId = JSON.stringify(form.userId)
form.age = JSON.stringify(form.age)
form.unionIds = JSON.stringify(form.unionIds)
form.activityUserCnd = form.activityUserCnd ? JSON.stringify(form.activityUserCnd) : form.activityUserCnd
return form
},
openSetDialog() {
this.formData = this.getDefaultFormData()
this.setDialogVisible = true
this.$nextTick(() => {
if (this.$refs.setForm) {
this.$refs.setForm.clearValidate()
}
})
},
handleSetGroupModeChange() {
if (this.formData.setGroupType === 1) {
this.formData.setGroupName = ""
if (this.selectedActivityGroup) {
// 原有分组只能使用当前筛选的活动组别,保存方式需与该分组类型一致。
this.formData.groupType = Number(this.selectedActivityGroup.groupType)
this.formData.setGroupId = this.selectedActivityGroup.groupId
} else {
this.formData.setGroupId = null
}
return
}
this.formData.setGroupId = null
},
handleGroupTypeChange() {
if (this.formData.setGroupType === 1 && this.selectedActivityGroup) {
this.formData.groupType = Number(this.selectedActivityGroup.groupType)
this.formData.setGroupId = this.selectedActivityGroup.groupId
return
}
if (!this.sameTypeGroupList.some((item) => item.groupId === this.formData.setGroupId)) {
this.formData.setGroupId = null
}
},
isSelectedActivityGroup(group) {
return this.selectedActivityGroup && Number(group.groupId) === Number(this.selectedActivityGroup.groupId)
},
handleActivityGroupChange(val) {
this.pageForm.memberTypes = val ? [] : ["工会会员"]
this.doSearch()
},
formatGroupDisplayName(group) {
if (Number(group.groupType) === 2) {
return group.groupName + "SQL条件)"
}
return group.groupName + "(人员结果)"
},
listSession() {
this.$axios.post("/platform/teacherCongress/common/listSession").then((res) => {
if (res.code === 0) {
this.sessionOptions = res.data
}
})
},
flush(existsLoginNameRedisKey) {
this.pageForm.existsLoginNameRedisKey = existsLoginNameRedisKey
this.doSearch()
},
clearImportDialog() {
this.importDialogVisible = false
},
doExportUser() {
const props = {}
this.tableColumns.forEach((item) => {
props[item.prop] = item.label
})
const pageForm = this.normalizePageForm(this.pageForm)
pageForm.props = JSON.stringify(props)
this.$downLoad("/platform/activity/basic/scope/doExportUser", {
data: JSON.stringify(pageForm)
})
},
doReset() {
this.pageForm.userId = []
this.pageForm.memberTypes = ["工会会员"]
this.pageForm.sexTypes = []
this.pageForm.personTypes = []
this.pageForm.userStates = []
this.pageForm.unionIds = this.getInitialUnionIds()
this.pageForm.module = ""
this.pageForm.teacherMeetingId = ""
this.pageForm.roleIds = []
this.pageForm.clubId = ""
this.pageForm.activityGroupId = ""
this.pageForm.activityUserCnd = ""
this.pageForm.age = [0, 0]
this.pageForm.reverseSelection = false
this.doSearch()
},
async queryUser(val) {
const resp = await $.get("/open/common/userOptions", { query: val })
this.userList = resp.data
},
tagClick(key, value) {
const index = this.pageForm[key].indexOf(value)
if (index !== -1) {
this.pageForm[key].splice(index, 1)
} else {
this.pageForm[key].push(value)
}
this.doSearch()
},
doSearch(showFullLoading = false) {
this.tableKey = new Date().getTime()
this.pageForm.pageNumber = 1
this.pageData(showFullLoading === true)
},
async pageData(showFullLoading = false) {
this.tableLoading = true
const loading = showFullLoading && this.pageForm.activityGroupId
? this.$loading({
lock: true,
text: "正在查询,请稍候...",
spinner: "el-icon-loading",
background: "rgba(255, 255, 255, 0.65)"
})
: null
try {
const resp = await $.post("/platform/activity/basic/scope/pageData", {
data: JSON.stringify(this.normalizePageForm(this.pageForm))
})
if (resp.code === 0) {
this.tableData = (resp.data.list || []).map((item) => ({
...item,
birthday: item.birthday ? moment(item.birthday).format("YYYY-MM-DD") : item.birthday
}))
this.pageForm.totalCount = resp.data.totalCount
} else {
this.notifyWarning(resp.msg)
}
} finally {
this.tableLoading = false
if (loading) {
loading.close()
}
}
},
async doSetActivityUser() {
const valid = await this.$refs.setForm.validate()
if (!valid) {
return
}
if (this.formData.groupType !== 2 && this.tableData.length === 0) {
this.$message.warning("请先指定筛选条件!")
return
}
const confirm = await this.$confirm("是否将符合搜索条件的用户设为活动人员?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
if (confirm === "confirm") {
this.settingLoading = true
const pageForm = this.normalizePageForm(this.pageForm)
Object.assign(pageForm, this.formData)
const resp = await $.post("/platform/activity/basic/scope/doSetActivityUser", {
data: JSON.stringify(pageForm)
})
if (resp.code === 0) {
this.setDialogVisible = false
await this.getActivityGroup()
this.doSearch()
this.$message.success(resp.msg)
this.formData = this.getDefaultFormData()
} else {
this.$message.error(resp.msg)
}
this.settingLoading = false
this.$emit("update:group_id", resp.data)
this.$emit("group_change")
}
},
async getActivityGroup() {
const resp = await $.get("/platform/activity/basic/scope/getActivityUserScopeGroup")
this.activityGroupList = resp.data || []
this.activityGroupList2 = this.activityGroupList.map((item) => ({
groupId: item.groupId,
groupName: this.formatGroupDisplayName(item) + "范围之外人员"
}))
},
async getRoleListByMenuId() {
const { data } = await $.post("/platform/activity/basic/scope/getRoleListByMenuId")
this.roleList = data
},
async getRolesAndUnion() {
const { data } = await $.post("/platform/activity/basic/scope/getRolesAndUnion")
this.roleData = data
}
},
async created() {
this.listSession()
await this.getRolesAndUnion()
this.clubOptions = (this.is_sysadmin || this.is_A06)
? await this.$businessTool.listClubByRole()
: this.is_CLUB_PRESIDENT
? await this.$businessTool.listManageClubByRole()
: await this.$businessTool.listClubByRole()
this.unions = (this.is_sysadmin || this.is_A06 || this.is_H02)
? await this.$businessTool.listUnion()
: this.$businessTool.listUnion(this.unionid)
this.pageForm.unionIds = this.getInitialUnionIds()
await this.getActivityGroup()
this.personTypeOptions = await this.$businessTool.getDictOptions("USER_PERSON_TYPE")
this.userStateOptions = await this.$businessTool.getDictOptions("USER_STATE")
await this.getRoleListByMenuId()
await this.pageData()
}
}
</script>
<style scoped>
.query-row {
display: flex;
align-items: center;
padding: 6px 0;
}
.query-row:not(:last-child) {
border-bottom: 1px dashed rgb(230, 230, 230);
}
.query-row > .query-title {
width: 100px;
max-width: 100px;
min-width: 100px;
overflow: hidden;
}
.query-row > .query-content {
min-width: 200px;
overflow: hidden;
flex: 1;
}
.query-row > .query-content > .el-tag {
margin-bottom: 5px;
margin-top: 5px;
}
.query-actions {
justify-content: end;
}
@media screen and (max-width: 992px) {
.query-title {
display: none;
}
}
.header_card .el-card__body {
padding: 2px 20px;
}
.user_card .el-card__body {
padding: 2px 20px;
}
.user_card {
border: none !important;
}
.user_table {
max-height: 260px;
}
.user_table .el-table__cell {
padding: 0;
}
.el-pagination {
height: 40px;
}
.reverseCheckBox {
margin: 0 10px 0 0 !important;
}
.form-tip {
color: #909399;
font-size: 12px;
line-height: 20px;
margin-top: 8px;
}
.existing-group-radio-list {
display: grid;
grid-template-columns: repeat(auto-fill, 190px);
column-gap: 24px;
row-gap: 5px;
align-items: start;
}
.existing-group-radio-list /deep/ .existing-group-radio,
.existing-group-radio-list /deep/ .el-radio.is-bordered,
.existing-group-radio-list /deep/ .el-radio.is-bordered + .el-radio.is-bordered {
margin: 0 !important;
width: 190px;
}
.existing-group-radio-list /deep/ .el-radio.is-bordered {
display: flex;
align-items: center;
}
</style>