449 lines
12 KiB
Vue
449 lines
12 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<!-- 搜索区域 -->
|
||
<div class="search-container">
|
||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||
<el-form-item prop="person" label="报销人">
|
||
<el-input
|
||
v-model="queryParams.person"
|
||
placeholder="请输入报销人"
|
||
clearable
|
||
@keyup.enter="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="创建时间" prop="times">
|
||
<el-date-picker
|
||
v-model="queryParams.times"
|
||
type="daterange"
|
||
value-format="YYYY-MM-DD"
|
||
placeholder="请选择创建时间"
|
||
range-separator="至"
|
||
start-placeholder="开始时间"
|
||
end-placeholder="结束时间"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item class="search-buttons">
|
||
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="refresh" @click="handleResetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<el-card shadow="hover" class="data-table">
|
||
<div class="data-table__toolbar">
|
||
<div class="data-table__toolbar--actions">
|
||
<el-button type="success" icon="plus" @click="handleOpenDialog()">新增</el-button>
|
||
</div>
|
||
</div>
|
||
<el-table
|
||
ref="dataTableRef"
|
||
v-loading="loading"
|
||
:data="roleList"
|
||
highlight-current-row
|
||
border
|
||
class="data-table__content"
|
||
@selection-change="handleSelectionChange"
|
||
>
|
||
<el-table-column type="selection" width="55" align="center" />
|
||
<el-table-column label="报销人" prop="person" />
|
||
<el-table-column label="报销金额" prop="amount" />
|
||
<el-table-column label="费用说明" prop="FeeDescription" />
|
||
<el-table-column label="状态" prop="state" />
|
||
<el-table-column label="时间" prop="times" />
|
||
<el-table-column fixed="right" label="操作" width="220">
|
||
<template #default="scope">
|
||
<el-button
|
||
type="primary"
|
||
size="small"
|
||
link
|
||
icon="edit"
|
||
@click="handleOpenDialog(scope.row)"
|
||
>
|
||
编辑
|
||
</el-button>
|
||
<el-button
|
||
type="danger"
|
||
size="small"
|
||
link
|
||
icon="delete"
|
||
@click="onUserDeleteDepartment(scope.row.id)"
|
||
>
|
||
删除
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-if="total > 0"
|
||
v-model:total="total"
|
||
v-model:page="queryParams.pageNum"
|
||
v-model:limit="queryParams.pageSize"
|
||
@pagination="fetchData"
|
||
/>
|
||
</el-card>
|
||
|
||
<!-- 角色表单弹窗 -->
|
||
<el-dialog
|
||
v-model="dialog.visible"
|
||
:title="dialog.title"
|
||
width="500px"
|
||
@close="handleCloseDialog"
|
||
>
|
||
<el-form ref="roleFormRef" :model="formData" :rules="rules" label-width="auto">
|
||
<el-form-item label="报销人" prop="person">
|
||
<el-input v-model="formData.person" placeholder="请输入报销人" />
|
||
</el-form-item>
|
||
<el-form-item label="报销时间" prop="times">
|
||
<el-date-picker
|
||
v-model="formData.times"
|
||
type="date"
|
||
value-format="YYYY-MM-DD"
|
||
placeholder="请选择报销时间"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="报销理由" prop="reason">
|
||
<el-input v-model="formData.reason" placeholder="请输入报销理由" />
|
||
</el-form-item>
|
||
<el-form-item label="报销金额" prop="amount">
|
||
<el-input v-model="formData.amount" placeholder="请输入报销金额" />
|
||
</el-form-item>
|
||
<el-form-item label="费用说明" prop="FeeDescription">
|
||
<el-input v-model="formData.FeeDescription" placeholder="请输入费用说明" />
|
||
</el-form-item>
|
||
<el-form-item v-if="!formData?.id" label="代办审核人" prop="personincharge">
|
||
<el-select v-model="formData.personincharge" placeholder="请选择代办审核人">
|
||
<el-option
|
||
v-for="item in personinchargeList"
|
||
:key="item.id"
|
||
:label="item.username"
|
||
:value="item.username"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||
<el-button @click="handleCloseDialog">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<!-- 分配权限弹窗 -->
|
||
<el-drawer
|
||
v-model="assignPermDialogVisible"
|
||
:title="'【' + checkedRole.name + '】权限分配'"
|
||
:size="drawerSize"
|
||
>
|
||
<div class="flex-x-between">
|
||
<el-input v-model="permKeywords" clearable class="w-[150px]" placeholder="菜单权限名称">
|
||
<template #prefix>
|
||
<Search />
|
||
</template>
|
||
</el-input>
|
||
|
||
<div class="flex-center ml-5">
|
||
<el-button type="primary" size="small" plain @click="togglePermTree">
|
||
<template #icon>
|
||
<Switch />
|
||
</template>
|
||
{{ isExpanded ? '收缩' : '展开' }}
|
||
</el-button>
|
||
<el-checkbox
|
||
v-model="parentChildLinked"
|
||
class="ml-5"
|
||
@change="handleparentChildLinkedChange"
|
||
>
|
||
父子联动
|
||
</el-checkbox>
|
||
|
||
<el-tooltip placement="bottom">
|
||
<template #content>
|
||
如果只需勾选菜单权限,不需要勾选子菜单或者按钮权限,请关闭父子联动
|
||
</template>
|
||
<el-icon class="ml-1 color-[--el-color-primary] inline-block cursor-pointer">
|
||
<QuestionFilled />
|
||
</el-icon>
|
||
</el-tooltip>
|
||
</div>
|
||
</div>
|
||
|
||
<el-tree
|
||
ref="permTreeRef"
|
||
node-key="value"
|
||
show-checkbox
|
||
:data="menuPermOptions"
|
||
:filter-node-method="handlePermFilter"
|
||
:default-expand-all="true"
|
||
:check-strictly="!parentChildLinked"
|
||
class="mt-5"
|
||
>
|
||
<template #default="{ data }">
|
||
{{ data.label }}
|
||
</template>
|
||
</el-tree>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button type="primary" @click="handleAssignPermSubmit">确 定</el-button>
|
||
<el-button @click="assignPermDialogVisible = false">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-drawer>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { useAppStore } from '@/store/modules/app-store'
|
||
import { DeviceEnum } from '@/enums/settings/device-enum'
|
||
|
||
import RoleAPI, { RolePageVO } from '@/api/system/role-api'
|
||
import {
|
||
FinanceDeleteReimbursement,
|
||
FinanceEditReimbursement,
|
||
FinanceReidetail,
|
||
FinanceReimbursement
|
||
} from '@/api/calibration/reimbursement'
|
||
import { UserPersonneldisplay } from '@/api/calibration/personnelManagement'
|
||
import { deepCloneByJSON } from '@/utils/auxiliaryFunction'
|
||
|
||
defineOptions({
|
||
name: 'Role',
|
||
inheritAttrs: false
|
||
})
|
||
|
||
const appStore = useAppStore()
|
||
|
||
const queryFormRef = ref()
|
||
const roleFormRef = ref()
|
||
const permTreeRef = ref()
|
||
|
||
const loading = ref(false)
|
||
const ids = ref<number[]>([])
|
||
const total = ref(0)
|
||
const personinchargeList = ref<any[]>([])
|
||
|
||
const queryParams = reactive<any>({
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
times: [],
|
||
person: ''
|
||
})
|
||
|
||
// 角色表格数据
|
||
const roleList = ref<RolePageVO[]>()
|
||
// 菜单权限下拉
|
||
const menuPermOptions = ref<OptionType[]>([])
|
||
|
||
// 弹窗
|
||
const dialog = reactive({
|
||
title: '',
|
||
visible: false
|
||
})
|
||
|
||
const drawerSize = computed(() => (appStore.device === DeviceEnum.DESKTOP ? '600px' : '90%'))
|
||
|
||
// 角色表单
|
||
const formData = reactive<any>({
|
||
id: '',
|
||
person: '',
|
||
times: '',
|
||
reason: '',
|
||
amount: '',
|
||
FeeDescription: '',
|
||
personincharge: ''
|
||
})
|
||
|
||
const rules = reactive({
|
||
person: [{ required: true, message: '请输入报销人', trigger: 'blur' }],
|
||
times: [{ required: true, message: '请输入报销时间', trigger: 'blur' }],
|
||
reason: [{ required: true, message: '请输入报销理由', trigger: 'blur' }],
|
||
amount: [{ required: true, message: '请输入报销金额', trigger: 'blur' }],
|
||
FeeDescription: [{ required: true, message: '请输入费用说明', trigger: 'blur' }],
|
||
personincharge: [{ required: true, message: '请选择费用说明', trigger: 'blur' }]
|
||
})
|
||
|
||
// 选中的角色
|
||
interface CheckedRole {
|
||
id?: string
|
||
name?: string
|
||
}
|
||
const checkedRole = ref<CheckedRole>({})
|
||
const assignPermDialogVisible = ref(false)
|
||
|
||
const permKeywords = ref('')
|
||
const isExpanded = ref(true)
|
||
|
||
const parentChildLinked = ref(true)
|
||
|
||
// 获取数据
|
||
function fetchData() {
|
||
loading.value = true
|
||
FinanceReidetail(queryParams)
|
||
.then((res: any) => {
|
||
roleList.value = res.data
|
||
total.value = res.total
|
||
})
|
||
.finally(() => {
|
||
loading.value = false
|
||
})
|
||
}
|
||
|
||
// 查询(重置页码后获取数据)
|
||
function handleQuery() {
|
||
queryParams.pageNum = 1
|
||
fetchData()
|
||
}
|
||
|
||
// 重置查询
|
||
function handleResetQuery() {
|
||
if (queryFormRef.value) queryFormRef.value.resetFields()
|
||
queryParams.pageNum = 1
|
||
fetchData()
|
||
}
|
||
|
||
// 行复选框选中
|
||
function handleSelectionChange(selection: any) {
|
||
ids.value = selection.map((item: any) => item.id)
|
||
}
|
||
|
||
// 打开角色弹窗
|
||
function handleOpenDialog(data: any = null) {
|
||
dialog.visible = true
|
||
if (data) {
|
||
dialog.title = '修改报销申请'
|
||
if (data && Object.keys(data).length > 0) {
|
||
const data1 = deepCloneByJSON(data)
|
||
|
||
Object.assign(formData, data1)
|
||
}
|
||
} else {
|
||
dialog.title = '新增报销申请'
|
||
}
|
||
}
|
||
|
||
// 提交角色表单
|
||
function handleSubmit() {
|
||
roleFormRef.value.validate((valid: any) => {
|
||
if (valid) {
|
||
loading.value = true
|
||
const roleId = formData.id
|
||
if (roleId) {
|
||
FinanceEditReimbursement(formData)
|
||
.then(() => {
|
||
ElMessage.success('修改成功')
|
||
handleCloseDialog()
|
||
handleResetQuery()
|
||
})
|
||
.finally(() => (loading.value = false))
|
||
} else {
|
||
FinanceReimbursement(formData)
|
||
.then(() => {
|
||
ElMessage.success('新增成功')
|
||
handleCloseDialog()
|
||
handleResetQuery()
|
||
})
|
||
.finally(() => (loading.value = false))
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 关闭弹窗
|
||
function handleCloseDialog() {
|
||
dialog.visible = false
|
||
|
||
roleFormRef.value.resetFields()
|
||
roleFormRef.value.clearValidate()
|
||
|
||
formData.id = undefined
|
||
formData.sort = 1
|
||
formData.status = 1
|
||
}
|
||
|
||
const onUserDeleteDepartment = (id: string) => {
|
||
ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(
|
||
() => {
|
||
loading.value = true
|
||
FinanceDeleteReimbursement(id)
|
||
.then(() => {
|
||
ElMessage.success('删除成功')
|
||
handleResetQuery()
|
||
})
|
||
.finally(() => (loading.value = false))
|
||
},
|
||
() => {
|
||
ElMessage.info('已取消删除')
|
||
}
|
||
)
|
||
}
|
||
|
||
// 分配菜单权限提交
|
||
function handleAssignPermSubmit() {
|
||
const roleId = checkedRole.value.id
|
||
if (roleId) {
|
||
const checkedMenuIds: number[] = permTreeRef
|
||
.value!.getCheckedNodes(false, true)
|
||
.map((node: any) => node.value)
|
||
|
||
loading.value = true
|
||
RoleAPI.updateRoleMenus(roleId, checkedMenuIds)
|
||
.then(() => {
|
||
ElMessage.success('分配权限成功')
|
||
assignPermDialogVisible.value = false
|
||
handleResetQuery()
|
||
})
|
||
.finally(() => {
|
||
loading.value = false
|
||
})
|
||
}
|
||
}
|
||
|
||
// 展开/收缩 菜单权限树
|
||
function togglePermTree() {
|
||
isExpanded.value = !isExpanded.value
|
||
if (permTreeRef.value) {
|
||
Object.values(permTreeRef.value.store.nodesMap).forEach((node: any) => {
|
||
if (isExpanded.value) {
|
||
node.expand()
|
||
} else {
|
||
node.collapse()
|
||
}
|
||
})
|
||
}
|
||
}
|
||
const DepartmentList = () => {
|
||
UserPersonneldisplay().then((res: any) => {
|
||
personinchargeList.value = res.data
|
||
})
|
||
}
|
||
// 权限筛选
|
||
watch(permKeywords, (val) => {
|
||
permTreeRef.value!.filter(val)
|
||
})
|
||
|
||
function handlePermFilter(
|
||
value: string,
|
||
data: {
|
||
[key: string]: any
|
||
}
|
||
) {
|
||
if (!value) return true
|
||
return data.label.includes(value)
|
||
}
|
||
|
||
// 父子菜单节点是否联动
|
||
function handleparentChildLinkedChange(val: any) {
|
||
parentChildLinked.value = val
|
||
}
|
||
|
||
onMounted(() => {
|
||
handleQuery()
|
||
DepartmentList()
|
||
})
|
||
</script>
|