| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717 |
- <template>
- <xn-form-container
- :title="formData.id ? '编辑用户' : '增加用户'"
- :width="800"
- :visible="visible"
- :destroy-on-close="true"
- :body-style="{ 'padding-top': '0px' }"
- @close="onClose"
- >
- <a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
- <a-tabs v-model:activeKey="activeTabsKey">
- <a-tab-pane key="1" tab="基础信息" force-render>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="账号:" name="account">
- <a-input v-model:value="formData.account" placeholder="请输入账号" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="姓名:" name="name">
- <a-input v-model:value="formData.name" placeholder="请输入姓名" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="性别:" name="gender">
- <a-radio-group v-model:value="formData.gender" :options="genderOptions" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="昵称:" name="nickname">
- <a-input v-model:value="formData.nickname" placeholder="请输入昵称" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="手机号:" name="phone">
- <a-input v-model:value="formData.phone" placeholder="请输入手机" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="邮箱:" name="email">
- <a-input v-model:value="formData.email" placeholder="请输入邮箱" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="出生日期:" name="birthday">
- <a-date-picker v-model:value="formData.birthday" value-format="YYYY-MM-DD" style="width: 100%" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="学号:" name="studentNum">
- <a-input v-model:value="formData.studentNum" placeholder="请输入学号" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="所属院系:" name="collegeId">
- <a-select
- v-model:value="formData.collegeId"
- placeholder="请选择所属院系"
- :options="collegeList"
- :field-names="{ label: 'name', value: 'id' }"
- @change="handleCollegeChange"
- allow-clear
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="专业:" name="majorId">
- <a-select
- v-model:value="formData.majorId"
- placeholder="请选择专业"
- :options="majorList"
- :field-names="{ label: 'majorName', value: 'id' }"
- @change="handleMajorChange"
- allow-clear
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="班级:" name="gradesId">
- <a-select
- v-model:value="formData.gradesId"
- placeholder="请选择班级"
- :options="gradesList"
- :field-names="{ label: 'gradesName', value: 'gradesId' }"
- allow-clear
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="学届:" name="fallDue">
- <a-select
- v-model:value="formData.fallDue"
- placeholder="请选择学届"
- :options="fallDueOptions"
- allow-clear
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="选择组织:" name="orgId">
- <a-tree-select
- v-model:value="formData.orgId"
- style="width: 100%"
- :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
- placeholder="请选择组织"
- allow-clear
- tree-default-expand-all
- :tree-data="treeData"
- :tree-default-expanded-keys="treeDefaultExpandedKeys"
- :field-names="{
- children: 'children',
- label: 'name',
- value: 'id'
- }"
- @change="selePositionData(formData.orgId, 0)"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="选择职位:" name="positionId">
- <xn-page-select
- ref="xnPositionPageSelectRef"
- v-model:value="formData.positionId"
- placeholder="请选择职位"
- allow-clear
- :page-function="selectApiFunction.positionSelector"
- :echo-function="selectApiFunction.echoPosition"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="选择教育身份:" name="eduIdentity">
- <a-select
- v-model:value="formData.eduIdentity"
- placeholder="请选择选择项类型"
- :options="eduIdentityOptions"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="选择主管:" name="directorId">
- <xn-page-select
- ref="xnUserPageSelectRef"
- v-model:value="formData.directorId"
- placeholder="请选择主管"
- allow-clear
- :page-function="selectApiFunction.userSelector"
- :echo-function="selectApiFunction.echoUser"
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="员工编号:" name="empNo">
- <a-input v-model:value="formData.empNo" placeholder="请输入员工编号" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="职级:" name="positionLevel">
- <a-input v-model:value="formData.positionLevel" placeholder="请输入职级" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="入职日期:" name="entryDate">
- <a-date-picker v-model:value="formData.entryDate" value-format="YYYY-MM-DD" style="width: 100%" />
- </a-form-item>
- </a-col>
- </a-row>
- <a-form-item label="任职信息" name="positionJson">
- <a-button type="primary" class="childAddButton" @click="addDomains()">
- <PlusOutlined />
- 增加任职
- </a-button>
- <a-row :gutter="10" class="form-row">
- <a-col :span="7" class="form-row-con"> 机构 </a-col>
- <a-col :span="7" class="form-row-con"> 职位 </a-col>
- <a-col :span="7" class="form-row-con"> 主管 </a-col>
- <a-col :span="3" class="form-row-con"> 操作 </a-col>
- </a-row>
- <div v-for="(positionInfo, index) in formData.positionJson" :key="index" class="form-div">
- <a-row :gutter="10">
- <a-col :span="7">
- <a-form-item
- :name="['positionJson', index, 'orgId']"
- :rules="{ required: true, message: '请选择组织' }"
- >
- <a-tree-select
- v-model:value="positionInfo.orgId"
- style="width: 100%"
- :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
- placeholder="请选择组织"
- allow-clear
- tree-default-expand-all
- :tree-data="treeData"
- :tree-default-expanded-keys="treeDefaultExpandedKeys"
- :field-names="{ children: 'children', label: 'name', value: 'id' }"
- @select="childOrgSelect(positionInfo, 0, index)"
- />
- </a-form-item>
- </a-col>
- <a-col :span="7">
- <a-form-item
- :name="['positionJson', index, 'positionId']"
- :rules="{ required: true, message: '请选择职位' }"
- >
- <xn-page-select
- ref="xnChildPositionPageSelectRef"
- v-model:value="positionInfo.positionId"
- placeholder="请选择职位"
- allow-clear
- :page-function="selectApiFunction.childPositionSelector"
- :echo-function="selectApiFunction.echoPosition"
- />
- </a-form-item>
- </a-col>
- <a-col :span="7">
- <a-form-item :name="['positionJson', index, 'directorId']">
- <xn-page-select
- ref="xnChildUserPageSelectRef"
- v-model:value="positionInfo.directorId"
- placeholder="请选择主管"
- allow-clear
- :page-function="selectApiFunction.childUserSelector"
- :echo-function="selectApiFunction.echoUser"
- />
- </a-form-item>
- </a-col>
- <a-col :span="3" style="margin-top: 4px">
- <a-button size="small" type="primary" danger ghost @click="delDomains(index)">移除</a-button>
- </a-col>
- </a-row>
- </div>
- </a-form-item>
- </a-tab-pane>
- <a-tab-pane key="2" tab="更多信息" force-render>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="民族:" name="nation">
- <a-select v-model:value="formData.nation" placeholder="请选择民族" :options="nationOptions" />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="籍贯:" name="nativePlace">
- <a-input v-model:value="formData.nativePlace" placeholder="请输入籍贯" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="家庭住址:" name="homeAddress">
- <a-textarea
- v-model:value="formData.homeAddress"
- placeholder="请输入家庭住址"
- :auto-size="{ minRows: 2, maxRows: 5 }"
- allow-clear
- />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="通信地址:" name="mailingAddress">
- <a-textarea
- v-model:value="formData.mailingAddress"
- placeholder="请输入通信地址"
- :auto-size="{ minRows: 2, maxRows: 5 }"
- allow-clear
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="证件类型:" name="idCardType">
- <a-select
- v-model:value="formData.idCardType"
- placeholder="请选择证件类型"
- :options="idcardTypeOptions"
- />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="证件号码:" name="idCardNumber">
- <a-input v-model:value="formData.idCardNumber" placeholder="请输入证件号码" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="文化程度:" name="cultureLevel">
- <a-select
- v-model:value="formData.cultureLevel"
- placeholder="请选择文化程度"
- :options="cultureLevelOptions"
- />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="政治面貌:" name="politicalOutlook">
- <a-input v-model:value="formData.politicalOutlook" placeholder="请输入政治面貌" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="毕业学校:" name="college">
- <a-input v-model:value="formData.college" placeholder="请输入毕业学校" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="学历:" name="education">
- <a-input v-model:value="formData.education" placeholder="请输入学历" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="学制:" name="eduLength">
- <a-input v-model:value="formData.eduLength" placeholder="请输入学制" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="学位:" name="degree">
- <a-input v-model:value="formData.degree" placeholder="请输入学位" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="家庭电话:" name="homeTel">
- <a-input v-model:value="formData.homeTel" placeholder="请输入家庭电话" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="办公电话:" name="officeTel">
- <a-input v-model:value="formData.officeTel" placeholder="请输入办公电话" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="紧急联系人:" name="emergencyContact">
- <a-input v-model:value="formData.emergencyContact" placeholder="请输入紧急联系人" allow-clear />
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="紧急联系电话:" name="emergencyPhone">
- <a-input v-model:value="formData.emergencyPhone" placeholder="请输入紧急联系电话" allow-clear />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="紧急联系人地址:" name="emergencyAddress">
- <a-textarea
- v-model:value="formData.emergencyAddress"
- placeholder="请输入紧急联系人地址"
- :auto-size="{ minRows: 2, maxRows: 5 }"
- allow-clear
- />
- </a-form-item>
- </a-col>
- </a-row>
- </a-tab-pane>
- </a-tabs>
- </a-form>
- <template #footer>
- <a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
- <a-button type="primary" :loading="formLoading" @click="onSubmit">保存</a-button>
- </template>
- </xn-form-container>
- </template>
- <script setup>
- import userApi from '@/api/sys/userApi'
- import userCenterApi from '@/api/sys/userCenterApi'
- import resourceAuditApi from '@/api/resourceAudit'
- import { required } from '@/utils/formRules'
- import tool from '@/utils/tool'
- // 默认是关闭状态
- const visible = ref(false)
- const formRef = ref()
- const activeTabsKey = ref('1')
- const emit = defineEmits({ successful: null })
- const formLoading = ref(false)
- const treeData = ref([])
- const treeDefaultExpandedKeys = ref([])
- const eduIdentityOptions = tool.dictList('SYS_USER_EDU_IDENTITY')
- const collegeList = ref([])
- const majorList = ref([])
- const gradesList = ref([])
- console.log(eduIdentityOptions, 'eduIdentityOptions')
- // 分页select组件dom定义
- const xnPositionPageSelectRef = ref()
- const xnUserPageSelectRef = ref()
- const xnChildPositionPageSelectRef = ref()
- const xnChildUserPageSelectRef = ref()
- // 表单数据
- const formData = ref({})
- const fallDueOptions = tool.dictList('FALL_TYPE')
- // 加载院系列表
- const loadCollegeList = () => {
- resourceAuditApi.orgList().then((res) => {
- if (res) {
- collegeList.value = res.data
- }
- })
- }
- // 处理院系变化
- const handleCollegeChange = (value) => {
- formData.value.majorId = undefined
- formData.value.gradesId = undefined
- majorList.value = []
- gradesList.value = []
- if (value) {
- // 加载专业列表
- resourceAuditApi.zyselect({ collegeId: value }).then((res) => {
- if (res) {
- majorList.value = res.data
- }
- })
- }
- }
- // 处理专业变化
- const handleMajorChange = (value) => {
- formData.value.gradesId = undefined
- gradesList.value = []
- if (value && formData.value.collegeId) {
- // 加载班级列表
- resourceAuditApi
- .gradeByZyAndOrgId({
- collegeId: formData.value.collegeId,
- majorId: value
- })
- .then((res) => {
- if (res) {
- gradesList.value = res.data
- }
- })
- }
- }
- // 打开抽屉
- const onOpen = (record, orgId) => {
- visible.value = true
- formData.value = {
- gender: '男',
- positionJson: [],
- collegeId: undefined,
- majorId: undefined,
- gradesId: undefined,
- studentNum: '',
- fallDue: undefined
- }
- // 加载院系列表
- loadCollegeList()
- if (orgId) {
- formData.value.orgId = orgId
- // 通过机构再查询职位、主管
- nextTick(() => {
- selePositionData(orgId)
- })
- }
- if (record) {
- convertFormData(record)
- }
- nextTick(() => {
- // 机构选择器数据
- userApi.userOrgTreeSelector().then((res) => {
- if (res !== null) {
- treeData.value = res
- // 默认展开2级
- treeData.value.forEach((item) => {
- // 因为0的顶级
- if (item.parentId === '0') {
- treeDefaultExpandedKeys.value.push(item.id)
- // 取到下级ID
- if (item.children) {
- item.children.forEach((items) => {
- treeDefaultExpandedKeys.value.push(items.id)
- })
- }
- }
- })
- }
- })
- })
- }
- // 关闭抽屉
- const onClose = () => {
- treeData.value = []
- treeDefaultExpandedKeys.value = []
- visible.value = false
- }
- // 回显数据
- const convertFormData = (record) => {
- const param = {
- id: record.id
- }
- // 查询详情
- userApi.userDetail(param).then((data) => {
- if (data.positionJson) {
- // 替换表单中的格式与后端查到的
- data.positionJson = JSON.parse(data.positionJson)
- }
- formData.value = Object.assign(formData.value, data)
- // 这里再写一次是因为上面需要先加载增行,下面再进行循环赋值
- if (data.positionJson) {
- // 遍历进行补充
- data.positionJson.map((item, index) => {
- childOrgSelect(item, 1, index)
- return item
- })
- }
- selePositionData(formData.value.orgId)
- // 如果有院系ID,加载专业列表并回显
- if (formData.value.collegeId) {
- resourceAuditApi.zyselect({ collegeId: formData.value.collegeId }).then((res) => {
- if (res) {
- majorList.value = res.data
- // 如果有专业ID,加载班级列表并回显
- if (formData.value.majorId) {
- resourceAuditApi
- .gradeByZyAndOrgId({
- collegeId: formData.value.collegeId,
- majorId: formData.value.majorId
- })
- .then((gradeRes) => {
- if (gradeRes) {
- formData.value.gradesId = Number(formData.value.gradesId)
- gradesList.value = gradeRes.data
- }
- })
- }
- }
- })
- }
- })
- }
- // 默认要校验的
- const formRules = {
- account: [required('请输入账号')],
- name: [required('请输入姓名')],
- sex: [required('请选择性别')],
- orgId: [required('请选择组织')],
- positionId: [required('请选择职位')],
- eduIdentity: [required('请选择教育身份')],
- collegeId: [required('请选择所属院系')],
- majorId: [required('请选择专业')],
- gradesId: [required('请选择班级')],
- studentNum: [required('请输入学号')],
- fallDue: [required('请选择学届')]
- }
- // 机构选择后查询对应的职位
- const selePositionData = (orgId, type) => {
- if (orgId) {
- const xnPositionPageSelectParam = {
- orgId: orgId
- }
- xnPositionPageSelectRef.value.onPage(xnPositionPageSelectParam)
- xnUserPageSelectRef.value.onPage()
- // 此类型代表选择的时候重置后面的职位
- if (type === 0) {
- formData.value.positionId = undefined
- formData.value.directorId = undefined
- }
- } else {
- formData.value.positionId = undefined
- formData.value.directorId = undefined
- }
- }
- // 传递选择组件需要的API
- const selectApiFunction = {
- positionSelector: (param) => {
- return userApi.userPositionSelector(param).then((data) => {
- return Promise.resolve(data)
- })
- },
- userSelector: (param) => {
- return userApi.userSelector(param).then((data) => {
- return Promise.resolve(data)
- })
- },
- childPositionSelector: (param) => {
- return userApi.userPositionSelector(param).then((data) => {
- return Promise.resolve(data)
- })
- },
- childUserSelector: (param) => {
- return userApi.userSelector(param).then((data) => {
- return Promise.resolve(data)
- })
- },
- // 通过id回显数据接口
- echoPosition: (param) => {
- return userCenterApi.userCenterGetPositionListByIdList(param).then((data) => {
- return Promise.resolve(data)
- })
- },
- echoUser: (param) => {
- return userCenterApi.userCenterGetUserListByIdList(param).then((data) => {
- return Promise.resolve(data)
- })
- }
- }
- // 附属职位信息增行
- const addDomains = () => {
- if (formData.value.positionJson === null) {
- formData.value.positionJson = []
- }
- formData.value.positionJson.push({
- orgId: undefined,
- positionId: undefined,
- directorId: undefined
- })
- }
- // 删减行
- const delDomains = (index) => {
- formData.value.positionJson.splice(index, 1)
- }
- // 子表行内选择机构
- const childOrgSelect = (data, type, index) => {
- // 说明正在切换机构,我们就将他的后面的设置空
- if (type === 0) {
- formData.value.positionJson.filter((item, serial) => {
- if (item.orgId === data.orgId && serial === index) {
- item.positionId = undefined
- item.directorId = undefined
- }
- })
- }
- const param = {
- orgId: data.orgId
- }
- nextTick(() => {
- xnChildPositionPageSelectRef.value[index].onPage(param)
- xnChildUserPageSelectRef.value[index].onPage(param)
- })
- }
- // 验证并提交数据
- const onSubmit = () => {
- formRef.value.validate().then(() => {
- // 因为不切断,我下面转换数据格式,影响上面表单会报错
- let formDatas = JSON.parse(JSON.stringify(formData.value))
- if (formDatas.positionJson && formDatas.positionJson.length > 0) {
- formDatas.positionJson = JSON.stringify(formDatas.positionJson)
- } else {
- delete formDatas.positionJson
- }
- formLoading.value = true
- userApi
- .submitForm(formDatas, formDatas.id)
- .then(() => {
- onClose()
- emit('successful')
- })
- .finally(() => {
- formLoading.value = false
- })
- })
- }
- // 性别
- const genderOptions = tool.dictList('GENDER')
- // 民族
- const nationOptions = tool.dictList('NATION')
- // 身份证件
- const idcardTypeOptions = tool.dictList('IDCARD_TYPE')
- // 文化程度
- const cultureLevelOptions = tool.dictList('CULTURE_LEVEL')
- // 调用这个函数将子组件的一些数据和方法暴露出去
- defineExpose({
- onOpen
- })
- </script>
- <style scoped type="less">
- .childAddButton {
- margin-bottom: 10px;
- }
- .form-row {
- background-color: var(--item-hover-bg);
- margin-left: 0px !important;
- }
- .form-row-con {
- padding-bottom: 5px;
- padding-top: 5px;
- padding-left: 15px;
- }
- .form-div {
- padding-top: 10px;
- }
- </style>
|