完成前端部署内容
This commit is contained in:
@@ -221,11 +221,13 @@ import {
|
||||
import type { ApprovalTemplate, ApprovalScenario, ApprovalNode } from '@/types'
|
||||
import { ApprovalScenarioMap } from '@/types'
|
||||
import {
|
||||
mockGetApprovalStats,
|
||||
mockGetApprovalTemplateList,
|
||||
mockToggleApprovalTemplate,
|
||||
mockDeleteApprovalTemplate
|
||||
} from '@/mock'
|
||||
getApprovalStats,
|
||||
getApprovalTemplateList,
|
||||
toggleApprovalTemplate,
|
||||
deleteApprovalTemplate,
|
||||
createApprovalTemplate,
|
||||
updateApprovalTemplate
|
||||
} from '@/api/system/approval'
|
||||
import { formatDateTime } from '@/utils/common'
|
||||
import FlowEditor from '@/components/FlowEditor/index.vue'
|
||||
|
||||
@@ -290,7 +292,7 @@ function getScenarioColor(scenario: ApprovalScenario): string {
|
||||
|
||||
async function loadStats() {
|
||||
try {
|
||||
const data = await mockGetApprovalStats()
|
||||
const data = await getApprovalStats()
|
||||
Object.assign(stats, data)
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
@@ -300,10 +302,8 @@ async function loadStats() {
|
||||
async function loadTemplates() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await mockGetApprovalTemplateList({
|
||||
scenario: filterScenario.value
|
||||
})
|
||||
templateList.value = res.list
|
||||
const list = await getApprovalTemplateList(filterScenario.value)
|
||||
templateList.value = list
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
message.error('加载数据失败')
|
||||
@@ -346,12 +346,27 @@ async function handleSubmit() {
|
||||
formData.nodes = flowEditorRef.value.toApprovalNodes()
|
||||
}
|
||||
|
||||
// 这里应该调用创建/更新API
|
||||
const requestData = {
|
||||
name: formData.name,
|
||||
description: formData.description,
|
||||
scenario: formData.scenario!,
|
||||
enabled: formData.enabled,
|
||||
nodes: formData.nodes
|
||||
}
|
||||
|
||||
if (editingTemplate.value) {
|
||||
await updateApprovalTemplate(editingTemplate.value.id, requestData)
|
||||
} else {
|
||||
await createApprovalTemplate(requestData)
|
||||
}
|
||||
|
||||
message.success(editingTemplate.value ? '更新成功' : '创建成功')
|
||||
drawerVisible.value = false
|
||||
loadTemplates()
|
||||
} catch {
|
||||
// 验证失败
|
||||
loadStats()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
message.error('保存失败')
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
@@ -359,7 +374,7 @@ async function handleSubmit() {
|
||||
|
||||
async function handleToggle(id: number) {
|
||||
try {
|
||||
await mockToggleApprovalTemplate(id)
|
||||
await toggleApprovalTemplate(id)
|
||||
message.success('状态已更新')
|
||||
loadTemplates()
|
||||
loadStats()
|
||||
@@ -371,7 +386,7 @@ async function handleToggle(id: number) {
|
||||
|
||||
async function handleDelete(id: number) {
|
||||
try {
|
||||
await mockDeleteApprovalTemplate(id)
|
||||
await deleteApprovalTemplate(id)
|
||||
message.success('删除成功')
|
||||
loadTemplates()
|
||||
loadStats()
|
||||
|
||||
@@ -203,7 +203,7 @@ import {
|
||||
} from '@ant-design/icons-vue'
|
||||
import type { ApprovalInstance, ApprovalScenario, ApprovalInstanceStatus } from '@/types'
|
||||
import { ApprovalScenarioMap, ApprovalInstanceStatusMap, ApprovalInstanceStatusBadgeMap } from '@/types'
|
||||
import { mockGetApprovalInstanceList } from '@/mock'
|
||||
import { getApprovalInstancePage } from '@/api/system/approval'
|
||||
import { formatDateTime } from '@/utils/common'
|
||||
|
||||
const loading = ref(false)
|
||||
@@ -274,16 +274,14 @@ function getActionText(action: string): string {
|
||||
async function loadData() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await mockGetApprovalInstanceList({
|
||||
const res = await getApprovalInstancePage({
|
||||
page: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
keyword: searchKeyword.value || undefined,
|
||||
scenario: filterScenario.value,
|
||||
status: filterStatus.value,
|
||||
startDate: dateRange.value?.[0]?.format('YYYY-MM-DD'),
|
||||
endDate: dateRange.value?.[1]?.format('YYYY-MM-DD')
|
||||
status: filterStatus.value
|
||||
})
|
||||
instanceList.value = res.list
|
||||
instanceList.value = res.records
|
||||
pagination.total = res.total
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
|
||||
290
src/views/system/dept/index.vue
Normal file
290
src/views/system/dept/index.vue
Normal file
@@ -0,0 +1,290 @@
|
||||
<template>
|
||||
<div class="dept-page">
|
||||
<a-page-header title="部门管理" sub-title="管理组织架构和部门信息">
|
||||
<template #extra>
|
||||
<a-button type="primary" @click="showCreateModal()">
|
||||
<PlusOutlined /> 新增部门
|
||||
</a-button>
|
||||
</template>
|
||||
</a-page-header>
|
||||
|
||||
<a-card class="main-card" :loading="loading">
|
||||
<a-table
|
||||
:columns="columns"
|
||||
:data-source="deptTree"
|
||||
:pagination="false"
|
||||
row-key="id"
|
||||
:default-expand-all-rows="true"
|
||||
:indent-size="24"
|
||||
>
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.key === 'name'">
|
||||
<div class="dept-name">
|
||||
<ApartmentOutlined class="dept-icon" />
|
||||
<span>{{ record.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.key === 'leader'">
|
||||
<span v-if="record.leaderName">{{ record.leaderName }}</span>
|
||||
<span v-else class="empty-text">-</span>
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.key === 'status'">
|
||||
<a-tag :color="record.status === 1 ? 'green' : 'red'">
|
||||
{{ record.status === 1 ? '正常' : '停用' }}
|
||||
</a-tag>
|
||||
</template>
|
||||
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" size="small" @click="showCreateModal(record.id)">
|
||||
<PlusOutlined /> 新增子部门
|
||||
</a-button>
|
||||
<a-button type="link" size="small" @click="showEditModal(record as DeptRecord)">
|
||||
<EditOutlined /> 编辑
|
||||
</a-button>
|
||||
<a-popconfirm
|
||||
title="确定删除此部门?"
|
||||
@confirm="handleDelete(record.id)"
|
||||
>
|
||||
<a-button type="link" size="small" danger>
|
||||
<DeleteOutlined /> 删除
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</a-space>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<a-modal
|
||||
v-model:open="modalVisible"
|
||||
:title="editingDept ? '编辑部门' : '新增部门'"
|
||||
:confirm-loading="submitting"
|
||||
@ok="handleSubmit"
|
||||
@cancel="modalVisible = false"
|
||||
>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
:label-col="{ span: 5 }"
|
||||
:wrapper-col="{ span: 18 }"
|
||||
>
|
||||
<a-form-item label="上级部门" name="parentId">
|
||||
<a-tree-select
|
||||
v-model:value="formData.parentId"
|
||||
:tree-data="parentTreeData"
|
||||
placeholder="请选择上级部门"
|
||||
tree-default-expand-all
|
||||
:field-names="{ children: 'children', label: 'name', value: 'id' }"
|
||||
allow-clear
|
||||
/>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="部门名称" name="name" :rules="[{ required: true, message: '请输入部门名称' }]">
|
||||
<a-input v-model:value="formData.name" placeholder="请输入部门名称" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="部门编码" name="code">
|
||||
<a-input v-model:value="formData.code" placeholder="请输入部门编码" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="负责人" name="leaderName">
|
||||
<a-input v-model:value="formData.leaderName" placeholder="请输入负责人姓名" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="联系电话" name="phone">
|
||||
<a-input v-model:value="formData.phone" placeholder="请输入联系电话" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="邮箱" name="email">
|
||||
<a-input v-model:value="formData.email" placeholder="请输入邮箱" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="显示排序" name="sort">
|
||||
<a-input-number v-model:value="formData.sort" :min="0" style="width: 100%" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="状态" name="status">
|
||||
<a-radio-group v-model:value="formData.status">
|
||||
<a-radio :value="1">正常</a-radio>
|
||||
<a-radio :value="0">停用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="备注" name="remark">
|
||||
<a-textarea v-model:value="formData.remark" :rows="3" placeholder="请输入备注" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import type { FormInstance } from 'ant-design-vue'
|
||||
import {
|
||||
PlusOutlined,
|
||||
EditOutlined,
|
||||
DeleteOutlined,
|
||||
ApartmentOutlined
|
||||
} from '@ant-design/icons-vue'
|
||||
import { getDeptTree, createDept, updateDept, deleteDept, type DeptRecord, type DeptFormData } from '@/api/system/dept'
|
||||
|
||||
const loading = ref(false)
|
||||
const submitting = ref(false)
|
||||
const deptTree = ref<DeptRecord[]>([])
|
||||
const modalVisible = ref(false)
|
||||
const editingDept = ref<DeptRecord | null>(null)
|
||||
const formRef = ref<FormInstance>()
|
||||
|
||||
const formData = reactive<DeptFormData>({
|
||||
parentId: 0,
|
||||
name: '',
|
||||
code: '',
|
||||
leaderName: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
sort: 0,
|
||||
status: 1,
|
||||
remark: ''
|
||||
})
|
||||
|
||||
const columns = [
|
||||
{ title: '部门名称', key: 'name', width: 280 },
|
||||
{ title: '部门编码', dataIndex: 'code', width: 120 },
|
||||
{ title: '负责人', key: 'leader', width: 100 },
|
||||
{ title: '联系电话', dataIndex: 'phone', width: 120 },
|
||||
{ title: '状态', key: 'status', width: 80 },
|
||||
{ title: '排序', dataIndex: 'sort', width: 80 },
|
||||
{ title: '操作', key: 'action', width: 240 }
|
||||
]
|
||||
|
||||
// 构建上级部门下拉数据(添加顶级选项)
|
||||
const parentTreeData = computed(() => {
|
||||
return [
|
||||
{ id: 0, name: '无(顶级部门)', children: deptTree.value }
|
||||
]
|
||||
})
|
||||
|
||||
async function loadData() {
|
||||
loading.value = true
|
||||
try {
|
||||
deptTree.value = await getDeptTree()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
message.error('加载数据失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function resetForm() {
|
||||
Object.assign(formData, {
|
||||
parentId: 0,
|
||||
name: '',
|
||||
code: '',
|
||||
leaderName: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
sort: 0,
|
||||
status: 1,
|
||||
remark: ''
|
||||
})
|
||||
}
|
||||
|
||||
function showCreateModal(parentId?: number) {
|
||||
editingDept.value = null
|
||||
resetForm()
|
||||
if (parentId) {
|
||||
formData.parentId = parentId
|
||||
}
|
||||
modalVisible.value = true
|
||||
}
|
||||
|
||||
function showEditModal(dept: DeptRecord) {
|
||||
editingDept.value = dept
|
||||
Object.assign(formData, {
|
||||
parentId: dept.parentId,
|
||||
name: dept.name,
|
||||
code: dept.code || '',
|
||||
leaderName: dept.leaderName || '',
|
||||
phone: dept.phone || '',
|
||||
email: dept.email || '',
|
||||
sort: dept.sort,
|
||||
status: dept.status,
|
||||
remark: dept.remark || ''
|
||||
})
|
||||
modalVisible.value = true
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await formRef.value?.validate()
|
||||
submitting.value = true
|
||||
|
||||
if (editingDept.value) {
|
||||
await updateDept(editingDept.value.id, formData)
|
||||
message.success('更新成功')
|
||||
} else {
|
||||
await createDept(formData)
|
||||
message.success('创建成功')
|
||||
}
|
||||
|
||||
modalVisible.value = false
|
||||
loadData()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDelete(id: number) {
|
||||
try {
|
||||
await deleteDept(id)
|
||||
message.success('删除成功')
|
||||
loadData()
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
message.error('删除失败')
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.dept-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.main-card {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.dept-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.dept-icon {
|
||||
color: #1890ff;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
color: #bfbfbf;
|
||||
}
|
||||
</style>
|
||||
@@ -49,8 +49,8 @@
|
||||
</template>
|
||||
<template v-if="column.dataIndex === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
|
||||
<a-button type="link" size="small" @click="handleViewItems(record)">字典项</a-button>
|
||||
<a-button type="link" size="small" @click="handleEdit(record as DictRecord)">编辑</a-button>
|
||||
<a-button type="link" size="small" @click="handleViewItems(record as DictRecord)">字典项</a-button>
|
||||
<a-popconfirm
|
||||
title="确定删除此字典吗?"
|
||||
@confirm="handleDelete(record.id)"
|
||||
@@ -84,6 +84,7 @@ import { message } from 'ant-design-vue'
|
||||
import { PlusOutlined, SearchOutlined, ReloadOutlined } from '@ant-design/icons-vue'
|
||||
import DictFormModal from '@/components/system/dict/DictFormModal.vue'
|
||||
import DictItemDrawer from '@/components/system/dict/DictItemDrawer.vue'
|
||||
import { getDictPage, deleteDict } from '@/api/system/dict'
|
||||
|
||||
// 类型定义
|
||||
interface DictRecord {
|
||||
@@ -119,7 +120,7 @@ const columns = [
|
||||
{ title: '备注', dataIndex: 'remark', ellipsis: true },
|
||||
{ title: '状态', dataIndex: 'status', width: 80 },
|
||||
{ title: '创建时间', dataIndex: 'createdAt', width: 170 },
|
||||
{ title: '操作', dataIndex: 'action', width: 160, fixed: 'right' }
|
||||
{ title: '操作', dataIndex: 'action', width: 160, fixed: 'right' as const }
|
||||
]
|
||||
|
||||
// 字典弹窗
|
||||
@@ -134,18 +135,17 @@ const currentDict = ref<DictRecord | null>(null)
|
||||
async function loadData() {
|
||||
loading.value = true
|
||||
try {
|
||||
// TODO: 接入真实API
|
||||
// const res = await getDictList({ ...searchForm, page: pagination.current, pageSize: pagination.pageSize })
|
||||
// tableData.value = res.data.data.records
|
||||
// pagination.total = res.data.data.total
|
||||
|
||||
// 模拟数据
|
||||
tableData.value = [
|
||||
{ id: 1, name: '性别', code: 'gender', remark: '用户性别', status: 1, createdAt: '2026-01-08 10:00:00' },
|
||||
{ id: 2, name: '状态', code: 'status', remark: '通用状态', status: 1, createdAt: '2026-01-08 10:00:00' },
|
||||
{ id: 3, name: '审批状态', code: 'approval_status', remark: '审批流程状态', status: 1, createdAt: '2026-01-08 10:00:00' }
|
||||
]
|
||||
pagination.total = 3
|
||||
const res = await getDictPage({
|
||||
page: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
name: searchForm.name || undefined,
|
||||
code: searchForm.code || undefined
|
||||
})
|
||||
tableData.value = res.data.data.records || []
|
||||
pagination.total = res.data.data.total || 0
|
||||
} catch (error) {
|
||||
console.error('加载字典数据失败:', error)
|
||||
tableData.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
@@ -184,10 +184,15 @@ function handleViewItems(record: DictRecord) {
|
||||
}
|
||||
|
||||
async function handleDelete(id: number) {
|
||||
// TODO: 接入真实API
|
||||
// await deleteDict(id)
|
||||
message.success('删除成功')
|
||||
loadData()
|
||||
try {
|
||||
await deleteDict(id)
|
||||
message.success('删除成功')
|
||||
loadData()
|
||||
} catch (error: any) {
|
||||
if (error?.response?.data?.message) {
|
||||
message.error(error.response.data.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -119,7 +119,7 @@ async function loadData() {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getRolePage({ pageSize: 100 })
|
||||
tableData.value = res.data.data.records || []
|
||||
tableData.value = res.records || []
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error)
|
||||
} finally {
|
||||
@@ -161,7 +161,7 @@ async function handleAssignMenus(record: RoleRecord) {
|
||||
|
||||
// 加载角色已有的菜单
|
||||
const roleMenuRes = await getRoleMenuIds(record.id)
|
||||
checkedMenuIds.value = roleMenuRes.data.data || []
|
||||
checkedMenuIds.value = roleMenuRes || []
|
||||
} catch (error) {
|
||||
console.error('加载数据失败:', error)
|
||||
} finally {
|
||||
|
||||
@@ -6,6 +6,17 @@
|
||||
<a-form-item label="关键词">
|
||||
<a-input v-model:value="searchForm.keyword" placeholder="用户名/昵称/手机号" allow-clear style="width: 200px" />
|
||||
</a-form-item>
|
||||
<a-form-item label="部门">
|
||||
<a-tree-select
|
||||
v-model:value="searchForm.deptId"
|
||||
:tree-data="deptTreeData"
|
||||
placeholder="请选择部门"
|
||||
tree-default-expand-all
|
||||
:field-names="{ children: 'children', label: 'name', value: 'id' }"
|
||||
allow-clear
|
||||
style="width: 180px"
|
||||
/>
|
||||
</a-form-item>
|
||||
<a-form-item label="角色">
|
||||
<a-select v-model:value="searchForm.role" placeholder="请选择角色" allow-clear style="width: 150px">
|
||||
<a-select-option v-for="role in roleOptions" :key="role.code" :value="role.code">
|
||||
@@ -68,8 +79,8 @@
|
||||
</template>
|
||||
<template v-else-if="column.key === 'action'">
|
||||
<a-space>
|
||||
<a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
|
||||
<a-button type="link" size="small" @click="handleResetPassword(record)">重置密码</a-button>
|
||||
<a-button type="link" size="small" @click="handleEdit(record as UserRecord)">编辑</a-button>
|
||||
<a-button type="link" size="small" @click="handleResetPassword(record as UserRecord)">重置密码</a-button>
|
||||
<a-popconfirm title="确定删除该用户吗?" @confirm="handleDelete(record.id)">
|
||||
<a-button type="link" size="small" danger>删除</a-button>
|
||||
</a-popconfirm>
|
||||
@@ -106,6 +117,7 @@ import {
|
||||
|
||||
import { getUserList, deleteUser, updateUserStatus } from '@/api/system/user'
|
||||
import { getRoleList } from '@/api/system/role'
|
||||
import { getDeptTree, type DeptRecord } from '@/api/system/dept'
|
||||
import type { UserRecord, UserFormData } from '@/types/system/user'
|
||||
import type { RoleRecord } from '@/types/system/role'
|
||||
|
||||
@@ -116,10 +128,12 @@ import ResetPasswordModal from '@/components/system/user/ResetPasswordModal.vue'
|
||||
const loading = ref(false)
|
||||
const tableData = ref<UserRecord[]>([])
|
||||
const roleOptions = ref<{ code: string; name: string }[]>([]) // Role List for display/select
|
||||
const deptTreeData = ref<DeptRecord[]>([])
|
||||
|
||||
// 搜索表单
|
||||
const searchForm = reactive({
|
||||
keyword: '',
|
||||
deptId: undefined as number | undefined,
|
||||
role: undefined as string | undefined,
|
||||
status: undefined as number | undefined
|
||||
})
|
||||
@@ -139,11 +153,11 @@ const columns = [
|
||||
{ title: '用户名', dataIndex: 'username', key: 'username' },
|
||||
{ title: '昵称', dataIndex: 'nickname', key: 'nickname' },
|
||||
{ title: '手机号', dataIndex: 'phone', key: 'phone' },
|
||||
{ title: '邮箱', dataIndex: 'email', key: 'email' },
|
||||
{ title: '部门', dataIndex: 'deptName', key: 'deptName', width: 120 },
|
||||
{ title: '角色', dataIndex: 'role', key: 'role', width: 120 },
|
||||
{ title: '状态', dataIndex: 'status', key: 'status', width: 100 },
|
||||
{ title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', width: 180 },
|
||||
{ title: '操作', key: 'action', width: 200, fixed: 'right' }
|
||||
{ title: '操作', key: 'action', width: 200, fixed: 'right' as const }
|
||||
]
|
||||
|
||||
// Modal State
|
||||
@@ -190,16 +204,22 @@ async function loadData() {
|
||||
// 加载角色列表
|
||||
async function loadRoles() {
|
||||
try {
|
||||
// 这里如果后端没有 list-all,我们可以用 list 且不传参(默认第一页),或者传大 pageSize
|
||||
// 假设后端支持 list 并返回 records
|
||||
const res = await getRoleList()
|
||||
// Mapping RoleRecord to Option { code, name }
|
||||
roleOptions.value = (res.data.data || []).map((r: RoleRecord) => ({ code: r.code, name: r.name }))
|
||||
const roles = await getRoleList()
|
||||
roleOptions.value = (roles || []).map((r: any) => ({ code: r.code, name: r.name }))
|
||||
} catch (error) {
|
||||
console.error('加载角色列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载部门树
|
||||
async function loadDeptTree() {
|
||||
try {
|
||||
deptTreeData.value = await getDeptTree()
|
||||
} catch (error) {
|
||||
console.error('加载部门列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
function handleSearch() {
|
||||
pagination.current = 1
|
||||
loadData()
|
||||
@@ -207,6 +227,7 @@ function handleSearch() {
|
||||
|
||||
function handleReset() {
|
||||
searchForm.keyword = ''
|
||||
searchForm.deptId = undefined
|
||||
searchForm.role = undefined
|
||||
searchForm.status = undefined
|
||||
handleSearch()
|
||||
@@ -258,6 +279,7 @@ function handleResetPassword(record: UserRecord) {
|
||||
|
||||
onMounted(() => {
|
||||
loadRoles()
|
||||
loadDeptTree()
|
||||
loadData()
|
||||
})
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user