first commit
This commit is contained in:
212
src/views/system/dept/detail.vue
Normal file
212
src/views/system/dept/detail.vue
Normal file
@@ -0,0 +1,212 @@
|
||||
<template>
|
||||
<el-form class="detail-form" ref="form" :model="model" label-width="auto" :rules="rules" label-suffix=":">
|
||||
<template v-for="(item, index) in items">
|
||||
<el-form-item v-if="!item.show || (item.show && item.show())" :key="index" :label="item.label" :prop="item.prop"
|
||||
:style="`grid-column-start: span ${item.width || '1'};`">
|
||||
<el-input v-if="item.type === 'input'" v-model="model[item.prop]" />
|
||||
<el-input v-if="item.type === 'password'" type="password" v-model="model[item.prop]" show-password />
|
||||
<el-input v-if="item.type === 'textarea'" autosize v-model="model[item.prop]" :rows="item.rows || 2" type="textarea" />
|
||||
<el-input-number v-if="item.type === 'number'" v-model="model[item.prop]" controls-position="right" :min="0"
|
||||
style="width: 100%;" />
|
||||
|
||||
<el-select v-if="item.type === 'select'" v-model="model[item.prop]" :clearable="item.clearable">
|
||||
<el-option v-for="(opt, index) in item.options" :key="index" :label="opt.label" :value="opt.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<el-tree-select v-if="item.type === 'treeselect'" v-model="model[item.prop]" :data="tree"
|
||||
:props="{ value: 'deptId', label: 'deptName', children: 'children' }" value-key="deptId" placeholder="选择上级部门"
|
||||
check-strictly :render-after-expand="false" />
|
||||
|
||||
<el-radio-group v-if="item.type === 'radiobutton'" v-model="model[item.prop]">
|
||||
<el-radio-button v-for="(opt, index) in item.options" :key="index" :label="opt.label" :value="opt.value" />
|
||||
</el-radio-group>
|
||||
|
||||
<el-radio-group v-if="item.type === 'radio'" v-model="model[item.prop]">
|
||||
<el-radio v-for="(opt, index) in item.options" :key="index" :label="opt.label" :value="opt.value" />
|
||||
</el-radio-group>
|
||||
|
||||
<el-tree v-if="item.type === 'tree'" class="tree-border" :data="areaOptions" show-checkbox ref="areaRef"
|
||||
node-key="areaCode" accordion empty-text="加载中,请稍候"
|
||||
:props="{ label: 'areaName', children: 'childArea' }"></el-tree>
|
||||
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
<div class="button-wrapper">
|
||||
<el-button type="primary" @click="validate">提交</el-button>
|
||||
<el-button @click="$emit('close')">取消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive, nextTick } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { addDept, updateDept, getAreaTree } from '@/api/system'
|
||||
|
||||
const emit = defineEmits([ 'close' ])
|
||||
const props = defineProps({
|
||||
data: {
|
||||
default() {
|
||||
return {}
|
||||
},
|
||||
required: false,
|
||||
type: Object
|
||||
},
|
||||
type: {
|
||||
default: '',
|
||||
required: false,
|
||||
type: String
|
||||
},
|
||||
tree: {
|
||||
default: () => [],
|
||||
required: false,
|
||||
type: Array
|
||||
}
|
||||
})
|
||||
|
||||
const form = ref(null)
|
||||
const areaRef = ref(null)
|
||||
const areaOptions = ref([])
|
||||
|
||||
const model = reactive({
|
||||
deptName: '',
|
||||
parentId: undefined,
|
||||
leader: '',
|
||||
phone: '',
|
||||
email: '',
|
||||
areaCodes: '',
|
||||
orderNum: ''
|
||||
})
|
||||
|
||||
const items = [
|
||||
{
|
||||
label: '部门名称',
|
||||
prop: 'deptName',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '上级部门',
|
||||
prop: 'parentId',
|
||||
type: 'treeselect',
|
||||
show: () => {
|
||||
return model.parentId !== 0
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '数据来源',
|
||||
prop: 'areaCodes',
|
||||
type: 'tree'
|
||||
},
|
||||
{
|
||||
label: '负责人',
|
||||
prop: 'leader',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '联系电话',
|
||||
prop: 'phone',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '邮箱',
|
||||
prop: 'email',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
prop: 'orderNum',
|
||||
type: 'number'
|
||||
}
|
||||
]
|
||||
|
||||
const rules = {
|
||||
deptName: [ { required: true, message: '部门名称 未填写', trigger: 'blur' } ],
|
||||
parentId: [ { required: true, message: '上级部门 未选择', trigger: 'change' } ]
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有选中节点数据
|
||||
* */
|
||||
const getAllCheckedKeys = () => {
|
||||
// 目前被选中的节点
|
||||
let checkedKeys = areaRef.value[0].getCheckedKeys()
|
||||
// 半选中的节点
|
||||
let halfCheckedKeys = areaRef.value[0].getHalfCheckedKeys()
|
||||
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
|
||||
return checkedKeys.join(',')
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化赋值
|
||||
*/
|
||||
const initData = () => {
|
||||
getAreaTree({ id: 331000 }).then(res => {
|
||||
areaOptions.value = res.data
|
||||
if (props.data.areaCodes && props.type !== 'add') {
|
||||
props.data.areaCodes.split(',').forEach(item => {
|
||||
nextTick(() => {
|
||||
areaRef.value[0].setChecked(item, true, false)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
if (props.type !== 'add') {
|
||||
Object.keys(model).forEach((key) => {
|
||||
model[key] = props.data[key]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单校验
|
||||
*/
|
||||
const validate = () => {
|
||||
model.areaCodes = getAllCheckedKeys()
|
||||
form.value.validate().then((valid) => {
|
||||
if (valid) {
|
||||
submit()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 表单校验
|
||||
*/
|
||||
const submit = () => {
|
||||
if (props.type === 'add') {
|
||||
addDept(model).then(() => {
|
||||
ElMessage.success('提交成功!')
|
||||
emit('close', true)
|
||||
})
|
||||
} else {
|
||||
updateDept({ ...model, deptId: props.data.deptId }).then(() => {
|
||||
ElMessage.success('提交成功!')
|
||||
emit('close', true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
initData()
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.detail-form {
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
|
||||
.tree-border {
|
||||
width: 100%;
|
||||
border: 1px solid #e5e6e7;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.button-wrapper {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 20px;
|
||||
}
|
||||
</style>
|
||||
192
src/views/system/dept/index.vue
Normal file
192
src/views/system/dept/index.vue
Normal file
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<FilterComponent :filter-items="items" :filter-model="model" theme="light" @handle="handle" />
|
||||
<TableComponent style="height: calc(100% - 60px);" v-loading="loading" :data="listData" :columns="columns" :config="config" :operate="operate" theme="light"
|
||||
size="large" @handle="handle" />
|
||||
<DialogComponent v-if="detail.visible" :title="detail.title[detail.type]" :modal="true" width="500"
|
||||
@close="closeDetail">
|
||||
<DetailComponent :data="detail.data" :type="detail.type" :tree="treeOptions" @close="closeDetail" />
|
||||
</DialogComponent>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ref, reactive } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getDept, delDept, listDeptExcludeChild } from '@/api/system'
|
||||
import { handleTree } from '@/utils/common'
|
||||
import FilterComponent from '@/components/Filter/index.vue'
|
||||
import TableComponent from '@/components/Table/index.vue'
|
||||
import DialogComponent from '@/components/Dialog/index.vue'
|
||||
import DetailComponent from './detail.vue'
|
||||
|
||||
const items = [
|
||||
{
|
||||
label: '部门名称',
|
||||
prop: 'deptName',
|
||||
type: 'input'
|
||||
},
|
||||
{
|
||||
name: '查询',
|
||||
prop: 'query',
|
||||
theme: 'primary',
|
||||
type: 'button',
|
||||
permission: [ 'system:dept:query' ]
|
||||
},
|
||||
{
|
||||
name: '新增',
|
||||
prop: 'add',
|
||||
theme: 'success',
|
||||
type: 'button',
|
||||
permission: [ 'system:dept:add' ]
|
||||
}
|
||||
]
|
||||
|
||||
let model = {
|
||||
deptName: ''
|
||||
}
|
||||
|
||||
const loading = ref(false)
|
||||
const listData = ref([])
|
||||
const treeOptions = ref([])
|
||||
|
||||
const columns = [
|
||||
{
|
||||
label: '部门名称',
|
||||
prop: 'deptName'
|
||||
},
|
||||
{
|
||||
label: '负责人',
|
||||
prop: 'leader'
|
||||
},
|
||||
{
|
||||
label: '联系电话',
|
||||
prop: 'phone'
|
||||
},
|
||||
{
|
||||
label: '邮箱',
|
||||
prop: 'email'
|
||||
},
|
||||
{
|
||||
label: '排序',
|
||||
prop: 'orderNum'
|
||||
}
|
||||
]
|
||||
|
||||
const config = {
|
||||
width: 120,
|
||||
rowKey: 'deptId'
|
||||
}
|
||||
|
||||
const operate = [
|
||||
{
|
||||
label: '编辑',
|
||||
prop: 'edit',
|
||||
theme: 'primary',
|
||||
permission: [ 'system:dept:edit' ]
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
prop: 'delete',
|
||||
theme: 'danger',
|
||||
permission: [ 'system:dept:remove' ]
|
||||
}
|
||||
]
|
||||
|
||||
const detail = reactive({
|
||||
visible: false,
|
||||
title: {
|
||||
add: '部门新增',
|
||||
check: '部门查看',
|
||||
edit: '部门编辑'
|
||||
},
|
||||
type: 'add',
|
||||
data: {}
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取数据
|
||||
*/
|
||||
const initData = () => {
|
||||
loading.value = true
|
||||
getDept(model).then(res => {
|
||||
if(res.code === 200) {
|
||||
listData.value = handleTree(res.data, 'deptId')
|
||||
}else{
|
||||
ElMessage.error(res.msg || '查询失败!')
|
||||
}
|
||||
}).finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除部门
|
||||
* @param id 部门ID
|
||||
*/
|
||||
const deleteData = (id) => {
|
||||
delDept(id).then(() => {
|
||||
ElMessage.success('删除成功!')
|
||||
initData()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 按钮操作
|
||||
* @param type 操作类型
|
||||
* @param data 数据
|
||||
*/
|
||||
const handle = (type, data) => {
|
||||
|
||||
switch (type) {
|
||||
case 'query':
|
||||
model = { ...data }
|
||||
initData()
|
||||
break
|
||||
case 'add':
|
||||
treeOptions.value = listData.value
|
||||
detail.visible = true
|
||||
detail.type = 'add'
|
||||
detail.data = {}
|
||||
break
|
||||
case 'check':
|
||||
case 'edit':
|
||||
listDeptExcludeChild(data.deptId).then(res => {
|
||||
treeOptions.value = handleTree(res.data, 'deptId')
|
||||
})
|
||||
detail.type = type
|
||||
detail.data = { ...data }
|
||||
detail.visible = true
|
||||
break
|
||||
case 'delete': {
|
||||
ElMessageBox.confirm(
|
||||
'是否删除该条数据?',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
deleteData(data.deptId)
|
||||
})
|
||||
break
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭详情弹窗
|
||||
* @param refresh 是否刷新数据
|
||||
*/
|
||||
const closeDetail = (refresh) => {
|
||||
detail.visible = false
|
||||
if (refresh) {
|
||||
initData()
|
||||
}
|
||||
}
|
||||
|
||||
initData()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
Reference in New Issue
Block a user