【招生用户端】 新增# 子账号管理:1、对接编辑、删除接口;2、组织状态设为停用时不可新增账号
parent
ebbe48d31c
commit
314c71a520
|
@ -16,3 +16,11 @@ export function subAccountList(params: Record<string, any>) {
|
||||||
export function subAccountNumber() {
|
export function subAccountNumber() {
|
||||||
return request.get({ url: '/user/validUserCount' })
|
return request.get({ url: '/user/validUserCount' })
|
||||||
}
|
}
|
||||||
|
// 子账号详情
|
||||||
|
export function subAccountDetail(params: Record<string, any>) {
|
||||||
|
return request.get({ url: '/user/detail', params })
|
||||||
|
}
|
||||||
|
// 删除子账号
|
||||||
|
export function subAccountDelete(params: Record<string, any>) {
|
||||||
|
return request.post({ url: '/user/sonDel', params })
|
||||||
|
}
|
||||||
|
|
|
@ -66,9 +66,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { organzationLists } from '@/api/account_center/organization'
|
import { organzationLists } from '@/api/account_center/organization'
|
||||||
import { postLists } from '@/api/account_center/postion'
|
import { postLists } from '@/api/account_center/postion'
|
||||||
import { subAccountAdd } from '@/api/account_center/sub_account'
|
import { subAccountAdd, subAccountDetail, subAccountEdit } from '@/api/account_center/sub_account'
|
||||||
import ProDialog, { type IParams } from '@/components/ProDialog/index.vue'
|
import ProDialog, { type IParams } from '@/components/ProDialog/index.vue'
|
||||||
import { DataFlowEnum } from '@/enums'
|
import { DataFlowEnum, StatusEnum } from '@/enums'
|
||||||
import { validateContact } from '@/utils/validate'
|
import { validateContact } from '@/utils/validate'
|
||||||
import type { FormInstance, FormRules } from 'element-plus'
|
import type { FormInstance, FormRules } from 'element-plus'
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ export interface IAccount {
|
||||||
}
|
}
|
||||||
const proDialogRef = ref<InstanceType<typeof ProDialog>>()
|
const proDialogRef = ref<InstanceType<typeof ProDialog>>()
|
||||||
|
|
||||||
const emit = defineEmits(['fetchTableList'])
|
const emit = defineEmits(['confirmAfter'])
|
||||||
const data = ref([])
|
const data = ref([])
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
label: 'name', // 显示字段
|
label: 'name', // 显示字段
|
||||||
|
@ -102,6 +102,7 @@ const accountStatusOptions = ref([
|
||||||
])
|
])
|
||||||
const channelTooltips = ['选择默认组织则数据流向到所属组织下的所有招生老师;', '选择组织指定则可选择将数据流向到所属组织下的指定招生老师;']
|
const channelTooltips = ['选择默认组织则数据流向到所属组织下的所有招生老师;', '选择组织指定则可选择将数据流向到所属组织下的指定招生老师;']
|
||||||
const form = ref({
|
const form = ref({
|
||||||
|
id: '',
|
||||||
organizationId: '',
|
organizationId: '',
|
||||||
username: '',
|
username: '',
|
||||||
mobile: '',
|
mobile: '',
|
||||||
|
@ -110,17 +111,23 @@ const form = ref({
|
||||||
status: 1,
|
status: 1,
|
||||||
teacher: ''
|
teacher: ''
|
||||||
})
|
})
|
||||||
const fetchPostionData = async () => {
|
const fetchPostionData = async (callback?: (params: []) => void) => {
|
||||||
try {
|
try {
|
||||||
const result = await postLists()
|
const result = await postLists()
|
||||||
positionOptions.value = result.lists
|
positionOptions.value = result.lists
|
||||||
|
callback && callback(result.lists)
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
const fetchOrganizationData = async () => {
|
const fetchOrganizationData = async (organizationId: number) => {
|
||||||
try {
|
try {
|
||||||
const result = await organzationLists()
|
const result = await organzationLists()
|
||||||
setDsiabled(result)
|
setDsiabled(result)
|
||||||
data.value = result
|
data.value = result
|
||||||
|
const targetNode = findNodeById(data.value, organizationId)
|
||||||
|
if (targetNode) {
|
||||||
|
const { id, disabled } = targetNode
|
||||||
|
form.value.organizationId = !disabled ? id : ''
|
||||||
|
}
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
// 三级节点可选中,其余禁止选中
|
// 三级节点可选中,其余禁止选中
|
||||||
|
@ -128,15 +135,48 @@ const setDsiabled = (nodes: any[]) => {
|
||||||
nodes.forEach(node => {
|
nodes.forEach(node => {
|
||||||
const ancestorArray = node.ancestors ? node.ancestors.split(',') : []
|
const ancestorArray = node.ancestors ? node.ancestors.split(',') : []
|
||||||
const level = ancestorArray.length - 1
|
const level = ancestorArray.length - 1
|
||||||
node.disabled = level < 2
|
node.disabled = level < 2 || node.status == StatusEnum.Stop
|
||||||
if (node.children && node.children.length > 0) {
|
if (node.children && node.children.length > 0) {
|
||||||
setDsiabled(node.children)
|
setDsiabled(node.children)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const openDialog = (params: IParams) => {
|
const fetchDetail = async (data: any) => {
|
||||||
|
const { id } = data
|
||||||
|
try {
|
||||||
|
const result = await subAccountDetail({ id })
|
||||||
|
setFormData(result)
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
const setFormData = result => {
|
||||||
|
for (const key in result) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(form.value, key)) {
|
||||||
|
form.value[key] = result[key]
|
||||||
|
}
|
||||||
|
if (key == 'postIds') {
|
||||||
|
form.value.postIds = result[key].split(',').map((item: string) => Number(item))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 根据组织id查找对应的节点
|
||||||
|
const findNodeById = (nodes: any[], id: number): any | undefined => {
|
||||||
|
for (const node of nodes) {
|
||||||
|
if (node.id === id) {
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
if (node.children && node.children.length > 0) {
|
||||||
|
const foundNode = findNodeById(node.children, id)
|
||||||
|
if (foundNode) {
|
||||||
|
return foundNode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
const openDialog = async (params: IParams) => {
|
||||||
fetchPostionData()
|
fetchPostionData()
|
||||||
fetchOrganizationData()
|
fetchOrganizationData(params.data.organizationId)
|
||||||
|
if (params.data.id) fetchDetail(params.data)
|
||||||
proDialogRef.value?.openDialog(params)
|
proDialogRef.value?.openDialog(params)
|
||||||
}
|
}
|
||||||
const handleCancel = (callback: () => void) => {
|
const handleCancel = (callback: () => void) => {
|
||||||
|
@ -161,9 +201,10 @@ const handleConfirm = (callback: () => void) => {
|
||||||
...form.value,
|
...form.value,
|
||||||
postIds: form.value.postIds.join(',')
|
postIds: form.value.postIds.join(',')
|
||||||
}
|
}
|
||||||
await subAccountAdd(data)
|
const api = form.value.id ? subAccountEdit : subAccountAdd
|
||||||
|
await api(data)
|
||||||
callback()
|
callback()
|
||||||
emit('fetchTableList')
|
emit('confirmAfter')
|
||||||
resetForm()
|
resetForm()
|
||||||
} catch (error) {}
|
} catch (error) {}
|
||||||
})
|
})
|
||||||
|
@ -172,7 +213,8 @@ const resetForm = () => {
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openDialog
|
openDialog,
|
||||||
|
fetchPostionData
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<account-number :accoutnInfo="accoutnInfo" />
|
<account-number :accoutnInfo="accoutnInfo" />
|
||||||
<div class="flex flex-1 bg-white overflow-x-auto">
|
<div class="flex flex-1 bg-white overflow-x-auto">
|
||||||
<organization @set-selected-node="setSelectedNode" :curSelectedNode="selectedNode" @fetch-table-list="fetchTableList" />
|
<organization @set-selected-node="setSelectedNode" :curSelectedNode="selectedNode" @fetch-table-list="fetchTableList" />
|
||||||
<account-list ref="accountListRef" :curOrganization="selectedNode" />
|
<account-list ref="accountListRef" :curOrganization="selectedNode" @refresh-sub-account-number="fetchSubAccountNumber" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -14,6 +14,8 @@ import organization from './modules/organization.vue'
|
||||||
import accountList from './modules/account-list.vue'
|
import accountList from './modules/account-list.vue'
|
||||||
import type { Tree } from './components/organization/organization-tree.vue'
|
import type { Tree } from './components/organization/organization-tree.vue'
|
||||||
import { subAccountNumber } from '@/api/account_center/sub_account'
|
import { subAccountNumber } from '@/api/account_center/sub_account'
|
||||||
|
import { StatusEnum } from '@/enums'
|
||||||
|
import feedback from '@/utils/feedback'
|
||||||
|
|
||||||
const selectedNode = ref()
|
const selectedNode = ref()
|
||||||
const setSelectedNode = (data: Tree) => {
|
const setSelectedNode = (data: Tree) => {
|
||||||
|
@ -23,6 +25,7 @@ watch(
|
||||||
() => selectedNode.value,
|
() => selectedNode.value,
|
||||||
val => {
|
val => {
|
||||||
if (val) {
|
if (val) {
|
||||||
|
if (val.status == StatusEnum.Stop) feedback.msgError('当前组织状态为停用,请先启用')
|
||||||
fetchTableList()
|
fetchTableList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="px-[20px] py-[16px] flex justify-between">
|
<div class="px-[20px] py-[16px] flex justify-between">
|
||||||
<el-space>
|
<el-space>
|
||||||
<el-button type="primary" :icon="Plus" @click="showAccountDialog">新建账号</el-button>
|
<el-button type="primary" :icon="Plus" :disabled="isDisabledAdd" @click="showAccountDialog">新建账号</el-button>
|
||||||
<el-button type="danger" plain :icon="Delete" :disabled="isDisabled" @click="handleBatchDelete">批量删除</el-button>
|
<el-button type="danger" plain :icon="Delete" :disabled="isDisabled" @click="handleBatchDelete">批量删除</el-button>
|
||||||
</el-space>
|
</el-space>
|
||||||
<el-space>
|
<el-space>
|
||||||
|
@ -16,7 +16,10 @@
|
||||||
</el-select>
|
</el-select>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
<el-select placeholder="请选择账号状态" v-model="searchForm.accountStatus" clearable @change="handleSelectChange">
|
<el-select placeholder="请选择岗位名称" v-model="searchForm.postId" clearable @change="handleSelectChange">
|
||||||
|
<el-option v-for="option in positionOptions" :key="option.id" :label="option.name" :value="option.id" />
|
||||||
|
</el-select>
|
||||||
|
<el-select placeholder="请选择账号状态" v-model="searchForm.status" clearable @change="handleSelectChange">
|
||||||
<el-option v-for="option in accountStatusOptions" :key="option.value" :label="option.label" :value="option.value" />
|
<el-option v-for="option in accountStatusOptions" :key="option.value" :label="option.label" :value="option.value" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-space>
|
</el-space>
|
||||||
|
@ -44,7 +47,7 @@
|
||||||
</template>
|
</template>
|
||||||
</ProTable>
|
</ProTable>
|
||||||
</div>
|
</div>
|
||||||
<account-dialog ref="accountDialogRef" @fetch-table-list="fetchTableList" />
|
<account-dialog ref="accountDialogRef" @confirm-after="confirmAfter" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -53,7 +56,8 @@ import feedback from '@/utils/feedback'
|
||||||
import { Plus, Delete } from '@element-plus/icons-vue'
|
import { Plus, Delete } from '@element-plus/icons-vue'
|
||||||
import accountDialog from '../components/account-list/account-dialog.vue'
|
import accountDialog from '../components/account-list/account-dialog.vue'
|
||||||
import { useDebounceFn } from '@vueuse/core'
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
import { subAccountList } from '@/api/account_center/sub_account'
|
import { subAccountDelete, subAccountList } from '@/api/account_center/sub_account'
|
||||||
|
import { StatusEnum } from '@/enums'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
curOrganization: {
|
curOrganization: {
|
||||||
|
@ -61,16 +65,17 @@ const props = defineProps({
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const selectKey = ref('accountName')
|
const emit = defineEmits(['refreshSubAccountNumber'])
|
||||||
|
|
||||||
|
const selectKey = ref('username')
|
||||||
const searchOptions = shallowRef([
|
const searchOptions = shallowRef([
|
||||||
{ field: 'accountName', label: '账号名称' },
|
{ field: 'username', label: '账号名称' },
|
||||||
{ field: 'mobile', label: '联系电话' },
|
{ field: 'mobile', label: '联系电话' }
|
||||||
{ field: 'positionName', label: '岗位名称' }
|
|
||||||
])
|
])
|
||||||
const placeholder = computed(() => searchOptions.value.find(item => item.field == selectKey.value)?.label)
|
const placeholder = computed(() => searchOptions.value.find(item => item.field == selectKey.value)?.label)
|
||||||
const accountStatusOptions = ref([
|
const accountStatusOptions = ref([
|
||||||
{ label: '启用', value: 1 },
|
{ label: '启用', value: StatusEnum.Normal },
|
||||||
{ label: '停用', value: 2 }
|
{ label: '停用', value: StatusEnum.Stop }
|
||||||
])
|
])
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const proTableRef = ref()
|
const proTableRef = ref()
|
||||||
|
@ -87,6 +92,7 @@ const columns = reactive([
|
||||||
|
|
||||||
const isGroupLeader = computed(() => (groupLeader: number) => groupLeader == 1)
|
const isGroupLeader = computed(() => (groupLeader: number) => groupLeader == 1)
|
||||||
const btnText = computed(() => (groupLeader: number) => isGroupLeader.value(groupLeader) ? '取消设为组长' : '设置组长')
|
const btnText = computed(() => (groupLeader: number) => isGroupLeader.value(groupLeader) ? '取消设为组长' : '设置组长')
|
||||||
|
const isDisabledAdd = computed(() => props.curOrganization.status == StatusEnum.Stop)
|
||||||
const fetchTableList = async (nodeId?: number) => {
|
const fetchTableList = async (nodeId?: number) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
try {
|
try {
|
||||||
|
@ -121,13 +127,22 @@ const handleDelete = async row => {
|
||||||
const deleteCommon = async (row?: any) => {
|
const deleteCommon = async (row?: any) => {
|
||||||
if (row) proTableRef.value.tableRef.toggleRowSelection(row, true)
|
if (row) proTableRef.value.tableRef.toggleRowSelection(row, true)
|
||||||
const ids = proTableRef.value.selectedListIds
|
const ids = proTableRef.value.selectedListIds
|
||||||
const message = '是否要删除选中的员工?'
|
const message = '是否要删除选中的账号?'
|
||||||
const flag = await useHandleData(message)
|
const flag = await useHandleData(message)
|
||||||
if (flag) {
|
if (flag) {
|
||||||
console.log(ids)
|
try {
|
||||||
|
await subAccountDelete({ ids })
|
||||||
|
feedback.msgSuccess('删除成功')
|
||||||
|
fetchTableList()
|
||||||
|
emit('refreshSubAccountNumber')
|
||||||
|
} catch (error) {}
|
||||||
}
|
}
|
||||||
proTableRef.value.tableRef.clearSelection()
|
proTableRef.value.tableRef.clearSelection()
|
||||||
}
|
}
|
||||||
|
const confirmAfter = () => {
|
||||||
|
fetchTableList()
|
||||||
|
emit('refreshSubAccountNumber')
|
||||||
|
}
|
||||||
const handleEdit = row => {
|
const handleEdit = row => {
|
||||||
showAccountDialog(row)
|
showAccountDialog(row)
|
||||||
}
|
}
|
||||||
|
@ -139,24 +154,34 @@ const showAccountDialog = (row?: any) => {
|
||||||
accountDialogRef.value?.openDialog({
|
accountDialogRef.value?.openDialog({
|
||||||
title: row?.id ? '编辑账号' : '新建账号',
|
title: row?.id ? '编辑账号' : '新建账号',
|
||||||
width: 400,
|
width: 400,
|
||||||
data: {}
|
data: {
|
||||||
|
id: row?.id ?? '',
|
||||||
|
organizationId: props.curOrganization.id
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const searchForm = ref({
|
const searchForm = ref({
|
||||||
keyword: '',
|
keyword: '',
|
||||||
accountStatus: ''
|
postId: '',
|
||||||
|
status: ''
|
||||||
})
|
})
|
||||||
const handleInputChange = useDebounceFn(() => {
|
const handleInputChange = useDebounceFn(() => {
|
||||||
const formMap: Record<string, string> = {
|
const formMap: Record<string, string> = {
|
||||||
accountName: '',
|
username: '',
|
||||||
mobile: '',
|
mobile: ''
|
||||||
position: ''
|
|
||||||
}
|
}
|
||||||
formMap[selectKey.value] = searchForm.value.keyword
|
formMap[selectKey.value] = searchForm.value.keyword
|
||||||
}, 500)
|
}, 500)
|
||||||
const handleSelectChange = () => {
|
const handleSelectChange = () => {
|
||||||
console.log('handleSelectChange')
|
console.log('handleSelectChange')
|
||||||
}
|
}
|
||||||
|
const positionOptions = ref<any[]>([])
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
accountDialogRef.value?.fetchPostionData(lists => {
|
||||||
|
positionOptions.value = lists ?? []
|
||||||
|
})
|
||||||
|
})
|
||||||
watch(
|
watch(
|
||||||
() => selectKey.value,
|
() => selectKey.value,
|
||||||
(newVal, oldVal) => {
|
(newVal, oldVal) => {
|
||||||
|
|
|
@ -23,6 +23,6 @@ const props = defineProps({
|
||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const parseUnuseNumber = computed(() => props.accoutnInfo.quota - props.accoutnInfo.quantity)
|
const parseUnuseNumber = computed(() => props.accoutnInfo?.quota - props.accoutnInfo?.quantity)
|
||||||
</script>
|
</script>
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|
Loading…
Reference in New Issue