Compare commits

..

No commits in common. 'ca5c23059baf41c90a3449b28a40c85ae2551aa1' and '9502fa189079236e430e99b57bbb6f0725085865' have entirely different histories.

@ -1,11 +1,9 @@
<template> <template>
<!-- 对话框组件 -->
<el-dialog <el-dialog
v-model="visible" v-model="visible"
:title="!dataForm.areaId ? '新增' : '修改'" :title="!dataForm.areaId ? '新增' : '修改'"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<!-- 表单组件 -->
<el-form <el-form
ref="dataFormRef" ref="dataFormRef"
:model="dataForm" :model="dataForm"
@ -13,7 +11,6 @@
label-width="100px" label-width="100px"
@keyup.enter="onSubmit()" @keyup.enter="onSubmit()"
> >
<!-- 地区名称输入项 -->
<el-form-item <el-form-item
label="地区名称" label="地区名称"
prop="areaName" prop="areaName"
@ -25,7 +22,6 @@
show-word-limit show-word-limit
/> />
</el-form-item> </el-form-item>
<!-- 上级地区选择项 -->
<el-form-item <el-form-item
label="上级地区" label="上级地区"
prop="parentId" prop="parentId"
@ -41,7 +37,6 @@
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 对话框底部操作按钮 -->
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button <el-button
@ -64,12 +59,7 @@
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { treeDataTranslate } from '@/utils' import { treeDataTranslate } from '@/utils'
import { Debounce } from '@/utils/debounce' import { Debounce } from '@/utils/debounce'
import { ref, reactive, nextTick, defineEmits, defineExpose } from 'vue'
//
const emit = defineEmits(['refreshDataList']) const emit = defineEmits(['refreshDataList'])
//
const dataRule = reactive({ const dataRule = reactive({
areaName: [ areaName: [
{ required: true, message: '区域名称不能为空', trigger: 'blur' }, { required: true, message: '区域名称不能为空', trigger: 'blur' },
@ -77,7 +67,6 @@ const dataRule = reactive({
] ]
}) })
//
const visible = ref(false) const visible = ref(false)
const areaList = ref([]) const areaList = ref([])
const dataForm = ref({ const dataForm = ref({
@ -92,76 +81,61 @@ const categoryTreeProps = reactive({
checkStrictly: true checkStrictly: true
}) })
const selectedOptions = ref([]) const selectedOptions = ref([])
//
const dataFormRef = ref(null) const dataFormRef = ref(null)
// areaId
const init = (areaId) => { const init = (areaId) => {
dataForm.value.areaId = areaId || 0 // ID dataForm.value.areaId = areaId || 0
visible.value = true // visible.value = true
selectedOptions.value = [] // selectedOptions.value = []
// 使nextTickDOM
nextTick(() => { nextTick(() => {
dataFormRef.value?.resetFields() // dataFormRef.value?.resetFields()
if (dataForm.value.areaId) { if (dataForm.value.areaId) {
// areaId
http({ http({
url: http.adornUrl('/admin/area/info/' + dataForm.value.areaId), url: http.adornUrl('/admin/area/info/' + dataForm.value.areaId),
method: 'get', method: 'get',
params: http.adornParams() params: http.adornParams()
}).then(({ data }) => { })
dataForm.value = data // .then(({ data }) => {
selectedOptions.value = dataForm.value.parentId // dataForm.value = data
// categoryTreePropsreactive selectedOptions.value = dataForm.value.parentId
categoryTreeProps.areaId = dataForm.value.areaId categoryTreeProps.areaId = dataForm.value.areaId
categoryTreeProps.areaName = dataForm.value.areaName categoryTreeProps.areaName = dataForm.value.areaName
}) })
} }
//
http({ http({
url: http.adornUrl('/admin/area/list'), url: http.adornUrl('/admin/area/list'),
method: 'get', method: 'get',
params: http.adornParams() params: http.adornParams()
}).then(({ data }) => { })
.then(({ data }) => {
areaList.value = treeDataTranslate(data, 'areaId', 'parentId') areaList.value = treeDataTranslate(data, 'areaId', 'parentId')
}) })
}) })
} }
// init
defineExpose({ init }) defineExpose({ init })
//
const page = { const page = {
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 20 // pageSize: 20 //
} }
/** /**
* 表单提交 * 表单提交
*/ */
const onSubmit = Debounce(() => { const onSubmit = Debounce(() => {
//
dataFormRef.value?.validate((valid) => { dataFormRef.value?.validate((valid) => {
if (valid) { if (valid) {
// HTTP
http({ http({
url: http.adornUrl('/admin/area'), url: http.adornUrl('/admin/area'),
method: dataForm.value.areaId ? 'put' : 'post', // method: dataForm.value.areaId ? 'put' : 'post',
data: http.adornData(dataForm.value) data: http.adornData(dataForm.value)
}).then(() => { }).then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
visible.value = false // visible.value = false
emit('refreshDataList', page) // emit('refreshDataList', page)
} }
}) })
}) })
@ -169,9 +143,8 @@ const onSubmit = Debounce(() => {
}) })
}) })
//
const handleChange = (val) => { const handleChange = (val) => {
// parentIdID
dataForm.value.parentId = val[val.length - 1] dataForm.value.parentId = val[val.length - 1]
} }
</script> </script>

@ -1,13 +1,10 @@
<template> <template>
<!-- 地区管理模块 -->
<div class="mod-sys-area"> <div class="mod-sys-area">
<!-- 地区名称输入框用于过滤树状结构中的节点 -->
<el-input <el-input
v-model="areaName" v-model="areaName"
class="area-search-input" class="area-search-input"
placeholder="地区关键词" placeholder="地区关键词"
/> />
<!-- 新增按钮点击时触发新增或更新操作 -->
<el-button <el-button
type="primary" type="primary"
class="area-add-btn" class="area-add-btn"
@ -16,7 +13,6 @@
新增 新增
</el-button> </el-button>
<!-- 树形控件展示地区层级结构 -->
<el-tree <el-tree
ref="tree2Ref" ref="tree2Ref"
:data="areaTreeData" :data="areaTreeData"
@ -25,11 +21,9 @@
:props="props" :props="props"
:expand-on-click-node="false" :expand-on-click-node="false"
> >
<!-- 自定义节点内容模板 -->
<template #default="{ node, data }"> <template #default="{ node, data }">
<span class="addr-name">{{ node.label }}</span> <!-- 显示地区名称 --> <span class="addr-name">{{ node.label }}</span>
<span> <span>
<!-- 修改按钮点击时触发修改操作 -->
<el-button <el-button
type="text" type="text"
icon="el-icon-edit" icon="el-icon-edit"
@ -37,7 +31,6 @@
> >
修改 修改
</el-button> </el-button>
<!-- 删除按钮点击时触发删除操作 -->
<el-button <el-button
type="text" type="text"
icon="el-icon-delete" icon="el-icon-delete"
@ -49,7 +42,6 @@
</template> </template>
</el-tree> </el-tree>
<!-- 添加或更新对话框组件 -->
<add-or-update <add-or-update
v-if="addOrUpdateVisible" v-if="addOrUpdateVisible"
ref="addOrUpdateRef" ref="addOrUpdateRef"
@ -61,44 +53,34 @@
<script setup> <script setup>
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import AddOrUpdate from './add-or-update.vue' // import AddOrUpdate from './add-or-update.vue'
import { treeDataTranslate } from '@/utils' // import { treeDataTranslate } from '@/utils'
import { ref, watch, onMounted, reactive, nextTick } from 'vue'
//
const areaName = ref('') const areaName = ref('')
//
const props = { const props = {
id: 'areaId', id: 'areaId',
label: 'areaName', label: 'areaName',
children: 'children' children: 'children'
} }
// const tree2Ref = ref(null)
watch( watch(
() => areaName.value, () => areaName,
(val) => { (val) => {
tree2Ref.value?.filter(val) tree2Ref.value?.filter(val)
} }
) )
//
onMounted(() => { onMounted(() => {
getDataList(page) getDataList(page)
}) })
//
const page = reactive({ const page = reactive({
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 10 // pageSize: 10 //
}) })
//
const areaTreeData = ref(null) const areaTreeData = ref(null)
//
const getDataList = (pageParam, params) => { const getDataList = (pageParam, params) => {
http({ http({
url: http.adornUrl('/admin/area/list'), url: http.adornUrl('/admin/area/list'),
@ -108,46 +90,38 @@ const getDataList = (pageParam, params) => {
size: pageParam == null ? page.pageSize : pageParam.pageSize size: pageParam == null ? page.pageSize : pageParam.pageSize
}, params)) }, params))
}).then(({ data }) => { }).then(({ data }) => {
// areaTreeData
areaTreeData.value = treeDataTranslate(data, 'areaId', 'parentId') areaTreeData.value = treeDataTranslate(data, 'areaId', 'parentId')
}) })
} }
//
const addOrUpdateRef = ref(null) const addOrUpdateRef = ref(null)
//
const addOrUpdateVisible = ref(false) const addOrUpdateVisible = ref(false)
/** /**
* 触发新增或更新操作 * 新增 / 修改
* @param id 可选参数若提供则表示更新指定ID的地区信息 * @param id
*/ */
const onAddOrUpdate = (id) => { const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true addOrUpdateVisible.value = true
nextTick(() => { nextTick(() => {
addOrUpdateRef.value?.init(id) // addOrUpdateRef.value?.init(id)
}) })
} }
/** /**
* 执行删除操作 * 删除
* @param areaId 要删除的地区ID * @param areaId
*/ */
const onDelete = (areaId) => { const onDelete = (areaId) => {
//
ElMessageBox.confirm('确定进行删除操作?', '提示', { ElMessageBox.confirm('确定进行删除操作?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
// HTTP
http({ http({
url: http.adornUrl('/admin/area/' + areaId), url: http.adornUrl('/admin/area/' + areaId),
method: 'delete', method: 'delete',
data: http.adornData({}) data: http.adornData({})
}).then(() => { }).then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
@ -157,37 +131,35 @@ const onDelete = (areaId) => {
} }
}) })
}) })
}).catch(() => { /* 用户取消删除 */ }) }).catch(() => { })
} }
// eslint-disable-next-line no-unused-vars
// onAddOrUpdate
const update = (node, data) => { const update = (node, data) => {
onAddOrUpdate(data.areaId) onAddOrUpdate(data.areaId)
} }
// onDelete // eslint-disable-next-line no-unused-vars
const remove = (node, data) => { const remove = (node, data) => {
onDelete(data.areaId) onDelete(data.areaId)
} }
//
const filterNode = (value, data) => { const filterNode = (value, data) => {
if (!value) return true // if (!value) return true
return data.areaName.indexOf(value) !== -1 // return data.areaName.indexOf(value) !== -1
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.mod-sys-area { .mod-sys-area {
.area-search-input { .area-search-input {
width: 30%; // 30% width: 30%;
} }
.area-add-btn { .area-add-btn {
float: right; // float: right;
} }
} }
/* 使用:deep选择器穿透样式作用于子组件 */
:deep(.el-tree-node) .addr-name { :deep(.el-tree-node) .addr-name {
width: 100%; // width: 100%;
} }
</style> </style>

@ -1,11 +1,9 @@
<template> <template>
<!-- 对话框组件 -->
<el-dialog <el-dialog
v-model="visible" v-model="visible"
:title="!dataForm.id ? '新增' : '修改'" :title="!dataForm.id ? '新增' : '修改'"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<!-- 表单组件 -->
<el-form <el-form
ref="dataFormRef" ref="dataFormRef"
:model="dataForm" :model="dataForm"
@ -13,7 +11,6 @@
label-width="80px" label-width="80px"
@keyup.enter="onSubmit()" @keyup.enter="onSubmit()"
> >
<!-- 参数名输入项 -->
<el-form-item <el-form-item
label="参数名" label="参数名"
prop="paramKey" prop="paramKey"
@ -23,7 +20,6 @@
placeholder="参数名" placeholder="参数名"
/> />
</el-form-item> </el-form-item>
<!-- 参数值输入项 -->
<el-form-item <el-form-item
label="参数值" label="参数值"
prop="paramValue" prop="paramValue"
@ -33,7 +29,6 @@
placeholder="参数值" placeholder="参数值"
/> />
</el-form-item> </el-form-item>
<!-- 备注输入项 -->
<el-form-item <el-form-item
label="备注" label="备注"
prop="remark" prop="remark"
@ -44,12 +39,13 @@
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 对话框底部操作按钮 -->
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="visible = false">取消</el-button> <!-- --> <el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit()"></el-button> <!-- 提交表单 --> <el-button
type="primary"
@click="onSubmit()"
>确定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -58,54 +54,36 @@
<script setup> <script setup>
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { Debounce } from '@/utils/debounce' import { Debounce } from '@/utils/debounce'
import { ref, reactive, nextTick, defineEmits, defineExpose } from 'vue'
//
const emit = defineEmits(['refreshDataList']) const emit = defineEmits(['refreshDataList'])
//
const visible = ref(false) const visible = ref(false)
// 使reactive
const dataForm = reactive({ const dataForm = reactive({
id: 0, // ID0 id: 0,
paramKey: '', // paramKey: '',
paramValue: '', // paramValue: '',
remark: '' // remark: ''
}) })
//
const dataRule = { const dataRule = {
paramKey: [ paramKey: [
{ required: true, message: '参数名不能为空', trigger: 'blur' }, // { required: true, message: '参数名不能为空', trigger: 'blur' },
{ pattern: /\s\S+|S+\s|\S/, message: '请输入正确的参数名', trigger: 'blur' } // { pattern: /\s\S+|S+\s|\S/, message: '请输入正确的参数名', trigger: 'blur' }
], ],
paramValue: [ paramValue: [
{ required: true, message: '参数值不能为空', trigger: 'blur' }, // { required: true, message: '参数值不能为空', trigger: 'blur' },
{ pattern: /\s\S+|S+\s|\S/, message: '请输入正确的参数值', trigger: 'blur' } // { pattern: /\s\S+|S+\s|\S/, message: '请输入正确的参数值', trigger: 'blur' }
] ]
} }
//
const dataFormRef = ref(null) const dataFormRef = ref(null)
// id
const init = (id) => { const init = (id) => {
dataForm.id = id || 0 // ID dataForm.id = id || 0
visible.value = true // visible.value = true
// 使nextTickDOM
nextTick(() => { nextTick(() => {
dataFormRef.value?.resetFields() // dataFormRef.value?.resetFields()
if (dataForm.id) { if (dataForm.id) {
// id
http({ http({
url: http.adornUrl(`/sys/config/info/${dataForm.id}`), url: http.adornUrl(`/sys/config/info/${dataForm.id}`),
method: 'get', method: 'get',
params: http.adornParams() params: http.adornParams()
}).then(({ data }) => { }).then(({ data }) => {
//
dataForm.paramKey = data.paramKey dataForm.paramKey = data.paramKey
dataForm.paramValue = data.paramValue dataForm.paramValue = data.paramValue
dataForm.remark = data.remark dataForm.remark = data.remark
@ -113,21 +91,16 @@ const init = (id) => {
} }
}) })
} }
// init
defineExpose({ init }) defineExpose({ init })
/** /**
* 表单提交 * 表单提交
*/ */
const onSubmit = Debounce(() => { const onSubmit = Debounce(() => {
//
dataFormRef.value?.validate((valid) => { dataFormRef.value?.validate((valid) => {
if (valid) { if (valid) {
// HTTP
http({ http({
url: http.adornUrl('/sys/config'), url: http.adornUrl('/sys/config'),
method: dataForm.id ? 'put' : 'post', // method: dataForm.id ? 'put' : 'post',
data: http.adornData({ data: http.adornData({
id: dataForm.id || undefined, id: dataForm.id || undefined,
paramKey: dataForm.paramKey, paramKey: dataForm.paramKey,
@ -135,14 +108,13 @@ const onSubmit = Debounce(() => {
remark: dataForm.remark remark: dataForm.remark
}) })
}).then(() => { }).then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
visible.value = false // visible.value = false
emit('refreshDataList') // emit('refreshDataList')
} }
}) })
}) })

@ -1,7 +1,5 @@
<template> <template>
<!-- 配置管理模块 -->
<div class="mod-config"> <div class="mod-config">
<!-- AvueCrud表格组件 -->
<avue-crud <avue-crud
ref="crudRef" ref="crudRef"
:page="page" :page="page"
@ -11,7 +9,6 @@
@selection-change="selectionChange" @selection-change="selectionChange"
@on-load="getDataList" @on-load="getDataList"
> >
<!-- 自定义左侧菜单按钮 -->
<template #menu-left> <template #menu-left>
<el-button <el-button
type="primary" type="primary"
@ -29,8 +26,6 @@
批量删除 批量删除
</el-button> </el-button>
</template> </template>
<!-- 自定义行内操作按钮 -->
<template #menu="scope"> <template #menu="scope">
<el-button <el-button
type="primary" type="primary"
@ -49,7 +44,7 @@
</template> </template>
</avue-crud> </avue-crud>
<!-- 添加或更新对话框组件 --> <!-- 弹窗, 新增 / 修改 -->
<add-or-update <add-or-update
v-if="addOrUpdateVisible" v-if="addOrUpdateVisible"
ref="addOrUpdateRef" ref="addOrUpdateRef"
@ -60,105 +55,81 @@
<script setup> <script setup>
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { tableOption } from '@/crud/sys/config.js' // import { tableOption } from '@/crud/sys/config.js'
import { ref, reactive, nextTick, defineExpose } from 'vue'
//
const dataList = ref([]) const dataList = ref([])
//
const page = reactive({ const page = reactive({
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 10 // pageSize: 10 //
}) })
/** /**
* 获取数据列表方法 * 获取数据列表
* @param pageParam 可选参数用于指定分页信息
* @param params 搜索条件参数
* @param done 分页加载完成回调函数
*/ */
const getDataList = (pageParam, params, done) => { const getDataList = (pageParam, params, done) => {
http({ http({
url: http.adornUrl('/sys/config/page'), // API url: http.adornUrl('/sys/config/page'),
method: 'get', // method: 'get',
params: http.adornParams( params: http.adornParams(
Object.assign( Object.assign(
{ {
current: pageParam == null ? page.currentPage : pageParam.currentPage, current: pageParam == null ? page.currentPage : pageParam.currentPage,
size: pageParam == null ? page.pageSize : pageParam.pageSize size: pageParam == null ? page.pageSize : pageParam.pageSize
}, },
params // params
) )
) )
}) })
.then(({ data }) => { .then(({ data }) => {
dataList.value = data.records // dataList.value = data.records
page.total = data.total // page.total = data.total
if (done) done() // if (done) done()
}) })
} }
/** /**
* 条件查询方法 * 条件查询
* @param params 搜索条件参数
* @param done 分页加载完成回调函数
*/ */
const onSearch = (params, done) => { const onSearch = (params, done) => {
getDataList(page, params, done) // getDataList(page, params, done)
} }
//
const dataListSelections = ref([]) const dataListSelections = ref([])
/** /**
* 多选变化方法 * 多选变化
* @param val 选中的数据项
*/ */
const selectionChange = (val) => { const selectionChange = (val) => {
dataListSelections.value = val // dataListSelections.value = val
} }
//
const addOrUpdateVisible = ref(false) const addOrUpdateVisible = ref(false)
//
const addOrUpdate = ref(null) const addOrUpdate = ref(null)
/** /**
* 触发新增或修改操作 * 新增 / 修改
* @param id 可选参数若提供则表示更新指定ID的配置信息
*/ */
const onAddOrUpdate = (id) => { const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true // addOrUpdateVisible.value = true
nextTick(() => { nextTick(() => {
addOrUpdate.value?.init(id) // addOrUpdate.value?.init(id)
}) })
} }
/** /**
* 删除配置信息 * 删除
* @param id 可选参数若提供则表示删除指定ID的配置信息
*/ */
const onDelete = (id) => { const onDelete = (id) => {
const ids = id ? [id] : dataListSelections.value?.map(item => item.id) // ID const ids = id ? [id] : dataListSelections.value?.map(item => {
return item.id
// })
ElMessageBox.confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', { ElMessageBox.confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
// HTTP
http({ http({
url: http.adornUrl('/sys/config'), url: http.adornUrl('/sys/config'),
method: 'delete', method: 'delete',
data: http.adornData(ids, false) data: http.adornData(ids, false)
}) })
.then(() => { .then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
@ -168,6 +139,6 @@ const onDelete = (id) => {
} }
}) })
}) })
}).catch(() => { /* 用户取消删除 */ }) }).catch(() => { })
} }
</script> </script>

@ -1,70 +1,57 @@
<template> <template>
<!-- 日志管理模块 -->
<div class="mod-log"> <div class="mod-log">
<!-- AvueCrud表格组件用于展示日志数据 -->
<avue-crud <avue-crud
ref="crudRef" <!-- 引用表格实例 --> ref="crudRef"
:page="page" <!-- 分页信息 --> :page="page"
:data="dataList" <!-- 表格数据 --> :data="dataList"
:option="tableOption" <!-- 表格选项配置 --> :option="tableOption"
@search-change="onSearch" <!-- 搜索条件变化事件 --> @search-change="onSearch"
@on-load="getDataList" <!-- 加载数据事件 --> @on-load="getDataList"
/> />
</div> </div>
</template> </template>
<script setup> <script setup>
import { tableOption } from '@/crud/sys/log.js' // import { tableOption } from '@/crud/sys/log.js'
import { ref, reactive, onMounted } from 'vue'
//
const dataList = ref([]) const dataList = ref([])
//
const page = reactive({ const page = reactive({
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 10 // pageSize: 10 //
}) })
//
onMounted(() => { onMounted(() => {
getDataList() getDataList()
}) })
/** /**
* 获取数据列表方法 * 获取数据列表
* @param pageParam 可选参数用于指定分页信息
* @param params 搜索条件参数
* @param done 分页加载完成回调函数
*/ */
const getDataList = (pageParam, params, done) => { const getDataList = (pageParam, params, done) => {
http({ http({
url: http.adornUrl('/sys/log/page'), // API url: http.adornUrl('/sys/log/page'),
method: 'get', // method: 'get',
params: http.adornParams( params: http.adornParams(
Object.assign( Object.assign(
{ {
current: pageParam == null ? page.currentPage : pageParam.currentPage, current: pageParam == null ? page.currentPage : pageParam.currentPage,
size: pageParam == null ? page.pageSize : pageParam.pageSize size: pageParam == null ? page.pageSize : pageParam.pageSize
}, },
params // params
) )
) )
}) })
.then(({ data }) => { .then(({ data }) => {
dataList.value = data.records // dataList.value = data.records
page.total = data.total // page.total = data.total
if (done) done() // if (done) done()
}) })
} }
/** /**
* 条件查询方法 * 条件查询
* @param params 搜索条件参数
* @param done 分页加载完成回调函数
*/ */
const onSearch = (params, done) => { const onSearch = (params, done) => {
getDataList(page, params, done) // getDataList(page, params, done)
} }
</script> </script>

@ -1,11 +1,9 @@
<template> <template>
<!-- 对话框组件 -->
<el-dialog <el-dialog
v-model="visible" v-model="visible"
:title="!dataForm.id ? '新增' : '修改'" :title="!dataForm.id ? '新增' : '修改'"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<!-- 表单组件 -->
<el-form <el-form
ref="dataFormRef" ref="dataFormRef"
:model="dataForm" :model="dataForm"
@ -13,7 +11,6 @@
label-width="80px" label-width="80px"
@keyup.enter="onSubmit()" @keyup.enter="onSubmit()"
> >
<!-- 类型选择项 -->
<el-form-item <el-form-item
label="类型" label="类型"
prop="type" prop="type"
@ -28,8 +25,6 @@
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<!-- 动态标签根据类型改变 -->
<el-form-item <el-form-item
:label="dataForm.typeList[dataForm.type] + '名称'" :label="dataForm.typeList[dataForm.type] + '名称'"
prop="name" prop="name"
@ -39,8 +34,6 @@
:placeholder="dataForm.typeList[dataForm.type] + '名称'" :placeholder="dataForm.typeList[dataForm.type] + '名称'"
/> />
</el-form-item> </el-form-item>
<!-- 上级菜单选择 -->
<el-form-item label="上级菜单"> <el-form-item label="上级菜单">
<el-cascader <el-cascader
v-model="selectedMenu" v-model="selectedMenu"
@ -52,8 +45,6 @@
@change="handleSelectMenuChange" @change="handleSelectMenuChange"
/> />
</el-form-item> </el-form-item>
<!-- 菜单路由输入仅当类型为1时显示 -->
<el-form-item <el-form-item
v-if="dataForm.type === 1" v-if="dataForm.type === 1"
label="菜单路由" label="菜单路由"
@ -64,8 +55,6 @@
placeholder="菜单路由" placeholder="菜单路由"
/> />
</el-form-item> </el-form-item>
<!-- 授权标识输入除类型0外显示 -->
<el-form-item <el-form-item
v-if="dataForm.type !== 0" v-if="dataForm.type !== 0"
label="授权标识" label="授权标识"
@ -76,8 +65,6 @@
placeholder="多个用逗号分隔, 如: user:list,user:create" placeholder="多个用逗号分隔, 如: user:list,user:create"
/> />
</el-form-item> </el-form-item>
<!-- 排序号输入除类型2外显示 -->
<el-form-item <el-form-item
v-if="dataForm.type !== 2" v-if="dataForm.type !== 2"
label="排序号" label="排序号"
@ -90,8 +77,6 @@
label="排序号" label="排序号"
/> />
</el-form-item> </el-form-item>
<!-- 菜单图标选择除类型2外显示 -->
<el-form-item <el-form-item
v-if="dataForm.type !== 2" v-if="dataForm.type !== 2"
label="菜单图标" label="菜单图标"
@ -145,12 +130,15 @@
</el-row> </el-row>
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 对话框底部操作按钮 -->
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="visible = false">取消</el-button> <!-- --> <el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit()"></el-button> <!-- 提交表单 --> <el-button
type="primary"
@click="onSubmit()"
>
确定
</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
@ -159,24 +147,16 @@
<script setup> <script setup>
import { treeDataTranslate, idList } from '@/utils' import { treeDataTranslate, idList } from '@/utils'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { ref, reactive, computed, onMounted, nextTick, defineEmits, defineExpose } from 'vue'
//
const emit = defineEmits(['refreshDataList']) const emit = defineEmits(['refreshDataList'])
//
const iconInputRef = ref(null) const iconInputRef = ref(null)
const iconListPopoverRef = ref(null) const iconListPopoverRef = ref(null)
const iconPopoverClass = computed(() => {
// return {
const iconPopoverClass = computed(() => ({
width: '396px' width: '396px'
})) }
})
//
const visible = ref(false) const visible = ref(false)
// 使reactive
const dataForm = reactive({ const dataForm = reactive({
id: 0, id: 0,
type: 1, type: 1,
@ -189,19 +169,15 @@ const dataForm = reactive({
icon: '', icon: '',
iconList: [] iconList: []
}) })
//
const menuList = ref([]) const menuList = ref([])
const selectedMenu = ref([]) const selectedMenu = ref([])
//
const menuListTreeProps = { const menuListTreeProps = {
value: 'menuId', value: 'menuId',
label: 'name', label: 'name',
checkStrictly: true checkStrictly: true
} }
// URL // eslint-disable-next-line no-unused-vars
const validateUrl = (rule, value, callback) => { const validateUrl = (rule, value, callback) => {
if (dataForm.type === 1 && !/\S/.test(value)) { if (dataForm.type === 1 && !/\S/.test(value)) {
callback(new Error('菜单URL不能为空')) callback(new Error('菜单URL不能为空'))
@ -209,8 +185,6 @@ const validateUrl = (rule, value, callback) => {
callback() callback()
} }
} }
//
const dataRule = ref({ const dataRule = ref({
name: [ name: [
{ required: true, message: '菜单名称不能为空', trigger: 'blur' }, { required: true, message: '菜单名称不能为空', trigger: 'blur' },
@ -221,11 +195,10 @@ const dataRule = ref({
] ]
}) })
//
onMounted(() => { onMounted(() => {
onLoadIcons() onLoadIcons()
}) })
const iconList = []
/** /**
* 加载图标 * 加载图标
*/ */
@ -233,42 +206,35 @@ const onLoadIcons = () => {
const icons = import.meta.glob('@/icons/svg/*.svg') const icons = import.meta.glob('@/icons/svg/*.svg')
for (const icon in icons) { for (const icon in icons) {
const iconName = icon.split('/src/icons/svg/')[1].split('.svg')[0] const iconName = icon.split('/src/icons/svg/')[1].split('.svg')[0]
dataForm.iconList.push(iconName) iconList.push(iconName)
} }
} }
//
const dataFormRef = ref(null) const dataFormRef = ref(null)
/**
* 初始化方法接收id作为参数
* @param id 菜单项ID
*/
const init = (id) => { const init = (id) => {
dataForm.id = id || 0 // ID dataForm.id = id || 0
http({ http({
url: http.adornUrl('/sys/menu/list'), url: http.adornUrl('/sys/menu/list'),
method: 'get', method: 'get',
params: http.adornParams() params: http.adornParams()
}) })
.then(({ data }) => { .then(({ data }) => {
menuList.value = treeDataTranslate(data, 'menuId') // menuList.value = treeDataTranslate(data, 'menuId')
}) })
.then(() => { .then(() => {
visible.value = true // visible.value = true
nextTick(() => { nextTick(() => {
dataFormRef.value?.resetFields() // dataFormRef.value?.resetFields()
}) })
}) })
.then(() => { .then(() => {
if (dataForm.id) { if (dataForm.id) {
// id //
http({ http({
url: http.adornUrl(`/sys/menu/info/${dataForm.id}`), url: http.adornUrl(`/sys/menu/info/${dataForm.id}`),
method: 'get', method: 'get',
params: http.adornParams() params: http.adornParams()
}).then(({ data }) => { }).then(({ data }) => {
//
dataForm.id = data.menuId dataForm.id = data.menuId
dataForm.type = data.type dataForm.type = data.type
dataForm.name = data.name dataForm.name = data.name
@ -280,39 +246,31 @@ const init = (id) => {
selectedMenu.value = idList(menuList.value, data.parentId, 'menuId', 'children').reverse() selectedMenu.value = idList(menuList.value, data.parentId, 'menuId', 'children').reverse()
}) })
} else { } else {
selectedMenu.value = [] // selectedMenu.value = []
} }
}) })
} }
defineExpose({ init }) defineExpose({ init })
/**
* 上级菜单选择变化处理
* @param val 选中的菜单路径
*/
const handleSelectMenuChange = (val) => { const handleSelectMenuChange = (val) => {
dataForm.parentId = val[val.length - 1] // parentIdID dataForm.parentId = val[val.length - 1]
} }
/** /**
* 图标选中处理 * 图标选中
* @param iconName 选中的图标名称 * @param iconName
*/ */
const iconActiveHandle = (iconName) => { const iconActiveHandle = (iconName) => {
dataForm.icon = iconName // dataForm.icon = iconName
} }
/** /**
* 表单提交 * 表单提交
*/ */
const onSubmit = Debounce(() => { const onSubmit = Debounce(() => {
//
dataFormRef.value?.validate((valid) => { dataFormRef.value?.validate((valid) => {
if (valid) { if (valid) {
// HTTP
http({ http({
url: http.adornUrl('/sys/menu'), url: http.adornUrl('/sys/menu'),
method: dataForm.id ? 'put' : 'post', // method: dataForm.id ? 'put' : 'post',
data: http.adornData({ data: http.adornData({
menuId: dataForm.id || undefined, menuId: dataForm.id || undefined,
type: dataForm.type, type: dataForm.type,
@ -325,14 +283,13 @@ const onSubmit = Debounce(() => {
}) })
}) })
.then(() => { .then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
visible.value = false // visible.value = false
emit('refreshDataList') // emit('refreshDataList')
} }
}) })
}) })

@ -1,13 +1,10 @@
<template> <template>
<!-- 菜单管理模块 -->
<div class="mod-menu"> <div class="mod-menu">
<!-- 搜索表单 -->
<el-form <el-form
:inline="true" :inline="true"
:model="dataForm" :model="dataForm"
> >
<el-form-item> <el-form-item>
<!-- 新增按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:menu:save')" v-if="isAuth('sys:menu:save')"
type="primary" type="primary"
@ -17,15 +14,12 @@
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 数据表格 -->
<el-table <el-table
:data="dataList" :data="dataList"
border border
style="width: 100%;" style="width: 100%;"
row-key="menuId" row-key="menuId"
> >
<!-- 名称列 -->
<el-table-column <el-table-column
prop="name" prop="name"
header-align="center" header-align="center"
@ -33,43 +27,51 @@
width="150" width="150"
label="名称" label="名称"
/> />
<!-- 图标列 -->
<el-table-column <el-table-column
header-align="center" header-align="center"
align="center" align="center"
label="图标" label="图标"
> >
<template #default="scope"> <!-- 自定义列内容 --> <template #default="scope">
<svg-icon <svg-icon
:icon-class="`icon-${scope.row.icon}`" :icon-class="`icon-${scope.row.icon}`"
/> />
</template> </template>
</el-table-column> </el-table-column>
<!-- 类型列 -->
<el-table-column <el-table-column
prop="type" prop="type"
header-align="center" header-align="center"
align="center" align="center"
label="类型" label="类型"
> >
<template #default="scope"> <!-- 自定义列内容 --> <template #default="scope">
<el-tag v-if="scope.row.type === 0"></el-tag> <!-- 根据类型动态渲染标签 --> <el-tag
<el-tag v-else-if="scope.row.type === 1" type="success">菜单</el-tag> v-if="scope.row.type === 0"
<el-tag v-else-if="scope.row.type === 2" type="info">按钮</el-tag> >
目录
</el-tag>
<el-tag
v-else-if="scope.row.type === 1"
type="success"
>
菜单
</el-tag>
<el-tag
v-else-if="scope.row.type === 2"
type="info"
>
按钮
</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<!-- 排序号列 -->
<el-table-column <el-table-column
prop="orderNum" prop="orderNum"
header-align="center" header-align="center"
align="center" align="center"
label="排序号" label="排序号"
/> />
<!-- 菜单URL列 -->
<el-table-column <el-table-column
prop="url" prop="url"
header-align="center" header-align="center"
@ -78,12 +80,10 @@
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
label="菜单URL" label="菜单URL"
> >
<template #default="scope"> <!-- 自定义列内容 --> <template #default="scope">
{{ scope.row.url || '-' }} <!-- 如果没有值则显示'-' --> {{ scope.row.url || '-' }}
</template> </template>
</el-table-column> </el-table-column>
<!-- 授权标识列 -->
<el-table-column <el-table-column
prop="perms" prop="perms"
header-align="center" header-align="center"
@ -92,12 +92,10 @@
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
label="授权标识" label="授权标识"
> >
<template #default="scope"> <!-- 自定义列内容 --> <template #default="scope">
{{ scope.row.perms || '-' }} <!-- 如果没有值则显示'-' --> {{ scope.row.perms || '-' }}
</template> </template>
</el-table-column> </el-table-column>
<!-- 操作列 -->
<el-table-column <el-table-column
fixed="right" fixed="right"
header-align="center" header-align="center"
@ -105,19 +103,19 @@
width="150" width="150"
label="操作" label="操作"
> >
<template #default="scope"> <!-- 自定义列内容 --> <template #default="scope">
<!-- 修改按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:menu:update')" v-if="isAuth('sys:menu:update')"
type="text" type="text"
@click="onAddOrUpdate(scope.row.menuId)" @click="onAddOrUpdate(scope.row.menuId)"
> >
修改 修改
</el-button> </el-button>
<!-- 删除按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:menu:delete')" v-if="isAuth('sys:menu:delete')"
type="text" type="text"
@click="onDelete(scope.row.menuId)" @click="onDelete(scope.row.menuId)"
> >
删除 删除
@ -125,7 +123,6 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<!-- 弹窗, 新增 / 修改 --> <!-- 弹窗, 新增 / 修改 -->
<add-or-update <add-or-update
v-if="addOrUpdateVisible" v-if="addOrUpdateVisible"
@ -137,75 +134,61 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, nextTick } from 'vue' import { treeDataTranslate, isAuth } from '@/utils'
import { treeDataTranslate, isAuth } from '@/utils' // import { ElMessage, ElMessageBox } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus' // import AddOrUpdate from './add-or-update.vue'
import AddOrUpdate from './add-or-update.vue' // /
//
const dataForm = ref({}) const dataForm = ref({})
//
onMounted(() => { onMounted(() => {
getDataList() getDataList()
}) })
//
const dataList = ref([]) const dataList = ref([])
/** /**
* 获取数据列表方法 * 获取数据列表
*/ */
const getDataList = () => { const getDataList = () => {
http({ http({
url: http.adornUrl('/sys/menu/table'), // API url: http.adornUrl('/sys/menu/table'),
method: 'get', // method: 'get',
params: http.adornParams() // params: http.adornParams()
}).then(({ data }) => { }).then(({ data }) => {
dataList.value = treeDataTranslate(data, 'menuId') // dataList.value = treeDataTranslate(data, 'menuId')
}) })
} }
// /
const addOrUpdateRef = ref(null) const addOrUpdateRef = ref(null)
//
const addOrUpdateVisible = ref(false) const addOrUpdateVisible = ref(false)
/** /**
* 新增 / 修改菜单项 * 新增 / 修改
* @param id 菜单项ID可选如果没有传入则表示新增 * @param id
*/ */
const onAddOrUpdate = (id) => { const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true // addOrUpdateVisible.value = true
nextTick(() => { nextTick(() => {
addOrUpdateRef.value?.init(id) // addOrUpdateRef.value?.init(id)
}) })
} }
/** /**
* 删除菜单项 * 删除
* @param id 菜单项ID * @param id
*/ */
const onDelete = (id) => { const onDelete = (id) => {
//
ElMessageBox.confirm(`确定对[id=${id}]进行[删除]操作?`, '提示', { ElMessageBox.confirm(`确定对[id=${id}]进行[删除]操作?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
// HTTP
http({ http({
url: http.adornUrl(`/sys/menu/${id}`), url: http.adornUrl(`/sys/menu/${id}`),
method: 'delete', method: 'delete',
data: http.adornData() data: http.adornData()
}).then(() => { }).then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
getDataList() // getDataList()
} }
}) })
}) })

@ -1,11 +1,9 @@
<template> <template>
<!-- 角色管理对话框 -->
<el-dialog <el-dialog
v-model="visible" v-model="visible"
:title="!dataForm.id ? '新增' : '修改'" :title="!dataForm.id ? '新增' : '修改'"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<!-- 表单 -->
<el-form <el-form
ref="dataFormRef" ref="dataFormRef"
:model="dataForm" :model="dataForm"
@ -13,7 +11,6 @@
label-width="80px" label-width="80px"
@keyup.enter="onSubmit()" @keyup.enter="onSubmit()"
> >
<!-- 角色名称输入框 -->
<el-form-item <el-form-item
label="角色名称" label="角色名称"
prop="roleName" prop="roleName"
@ -23,8 +20,6 @@
placeholder="角色名称" placeholder="角色名称"
/> />
</el-form-item> </el-form-item>
<!-- 备注输入框 -->
<el-form-item <el-form-item
label="备注" label="备注"
prop="remark" prop="remark"
@ -34,8 +29,6 @@
placeholder="备注" placeholder="备注"
/> />
</el-form-item> </el-form-item>
<!-- 授权菜单树 -->
<el-form-item label="授权"> <el-form-item label="授权">
<el-tree <el-tree
ref="menuListTreeRef" ref="menuListTreeRef"
@ -46,135 +39,98 @@
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 对话框底部按钮组 -->
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="visible = false">取消</el-button> <!-- --> <el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit()"></el-button> <!-- 确认按钮 --> <el-button
type="primary"
@click="onSubmit()"
>确定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { ref, reactive, nextTick } from 'vue' import { ElMessage } from 'element-plus'
import { ElMessage } from 'element-plus' // import { treeDataTranslate } from '@/utils'
import { treeDataTranslate } from '@/utils' // import { Debounce } from '@/utils/debounce'
import { Debounce } from '@/utils/debounce' //
//
const emit = defineEmits(['refreshDataList']) const emit = defineEmits(['refreshDataList'])
const tempKey = -666666 // key) tree. #
// keytree
const tempKey = -666666
//
const visible = ref(false) const visible = ref(false)
//
const menuList = ref([]) const menuList = ref([])
//
const menuListTreeProps = { const menuListTreeProps = {
label: 'name', // label: 'name',
children: 'children' // children: 'children'
} }
// 使reactive使
const dataForm = reactive({ const dataForm = reactive({
id: 0, // ID0 id: 0,
roleName: '', // roleName: '',
remark: '' // remark: ''
}) })
// 使reactive使
const dataRule = reactive({ const dataRule = reactive({
roleName: [ // roleName: [
{ required: true, message: '角色名称不能为空', trigger: 'blur' }, // { required: true, message: '角色名称不能为空', trigger: 'blur' },
{ pattern: /\s\S+|\S+\s|\S/, message: '请输入正确的角色名称', trigger: 'blur' } // { pattern: /\s\S+|S+\s|\S/, message: '请输入正确的角色名称', trigger: 'blur' }
], ],
remark: [ // remark: [
{ required: false, pattern: /\s\S+|\S+\s|\S/, message: '输入格式有误', trigger: 'blur' } // { required: false, pattern: /\s\S+|S+\s|\S/, message: '输入格式有误', trigger: 'blur' }
] ]
}) })
//
const dataFormRef = ref(null) const dataFormRef = ref(null)
//
const menuListTreeRef = ref(null) const menuListTreeRef = ref(null)
/**
* 初始化方法接收可选的角色ID参数
* @param id 角色ID可选
*/
const init = (id) => { const init = (id) => {
dataForm.id = id || 0 // id dataForm.id = id || 0
//
http({ http({
url: http.adornUrl('/sys/menu/table'), // API url: http.adornUrl('/sys/menu/table'),
method: 'get', // method: 'get',
params: http.adornParams() // params: http.adornParams()
}) })
.then(({ data }) => { .then(({ data }) => {
menuList.value = treeDataTranslate(data, 'menuId', 'parentId') // menuList.value = treeDataTranslate(data, 'menuId', 'parentId')
}) })
.then(() => { .then(() => {
visible.value = true // visible.value = true
return nextTick() // DOM nextTick(() => {
dataFormRef.value?.resetFields()
menuListTreeRef.value?.setCheckedKeys([])
}) })
.then(() => {
dataFormRef.value?.resetFields() //
menuListTreeRef.value?.setCheckedKeys([]) //
}) })
.then(() => { .then(() => {
if (dataForm.id) { // if (dataForm.id) {
http({ http({
url: http.adornUrl(`/sys/role/info/${dataForm.id}`), // API url: http.adornUrl(`/sys/role/info/${dataForm.id}`),
method: 'get', // method: 'get',
params: http.adornParams() // params: http.adornParams()
}) })
.then(({ data }) => { .then(({ data }) => {
dataForm.roleName = data.roleName // dataForm.roleName = data.roleName
dataForm.remark = data.remark // dataForm.remark = data.remark
// key
const idx = data.menuIdList.indexOf(tempKey) const idx = data.menuIdList.indexOf(tempKey)
if (idx !== -1) { if (idx !== -1) {
data.menuIdList.splice(idx, data.menuIdList.length - idx) data.menuIdList.splice(idx, data.menuIdList.length - idx)
} }
//
menuListTreeRef.value?.setCheckedKeys(data.menuIdList) menuListTreeRef.value?.setCheckedKeys(data.menuIdList)
}) })
} }
}) })
} }
// init便
defineExpose({ init }) defineExpose({ init })
/** /**
* 提交表单方法 * 表单提交
*/ */
const onSubmit = Debounce(() => { // 使 const onSubmit = Debounce(() => {
dataFormRef.value?.validate((valid) => { // dataFormRef.value?.validate((valid) => {
if (valid) { // if (valid) {
http({ http({
url: http.adornUrl('/sys/role'), // API url: http.adornUrl('/sys/role'),
method: dataForm.id ? 'put' : 'post', // id method: dataForm.id ? 'put' : 'post',
data: http.adornData({ data: http.adornData({
roleId: dataForm.id || undefined, // ID roleId: dataForm.id || undefined,
roleName: dataForm.roleName, // roleName: dataForm.roleName,
remark: dataForm.remark, // remark: dataForm.remark,
// ID menuIdList: [].concat(menuListTreeRef.value?.getCheckedKeys(), [tempKey], menuListTreeRef.value?.getHalfCheckedKeys())
menuIdList: [].concat(
menuListTreeRef.value?.getCheckedKeys(),
[tempKey],
menuListTreeRef.value?.getHalfCheckedKeys()
)
}) })
}) })
.then(() => { .then(() => {
@ -183,12 +139,13 @@ const onSubmit = Debounce(() => { // 使用防抖函数防止快速点击多次
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
visible.value = false // visible.value = false
emit('refreshDataList') // emit('refreshDataList')
} }
}) })
}) })
} }
}) })
}) })
</script> </script>

@ -1,7 +1,5 @@
<template> <template>
<!-- 角色管理模块 -->
<div class="mod-role"> <div class="mod-role">
<!-- 使用avue-crud创建CRUD表格 -->
<avue-crud <avue-crud
ref="crudRef" ref="crudRef"
:page="page" :page="page"
@ -11,9 +9,7 @@
@selection-change="selectionChange" @selection-change="selectionChange"
@on-load="getDataList" @on-load="getDataList"
> >
<!-- 左侧菜单栏 -->
<template #menu-left> <template #menu-left>
<!-- 新增按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:role:save')" v-if="isAuth('sys:role:save')"
type="primary" type="primary"
@ -23,7 +19,6 @@
新增 新增
</el-button> </el-button>
<!-- 批量删除按钮只有有权限且选择了项目时显示 -->
<el-button <el-button
v-if="isAuth('sys:role:delete')" v-if="isAuth('sys:role:delete')"
type="danger" type="danger"
@ -34,9 +29,7 @@
</el-button> </el-button>
</template> </template>
<!-- 行内菜单 --> <template #menu="scope">
<template #menu="scope"> <!-- 自定义行内菜单 -->
<!-- 编辑按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:role:update')" v-if="isAuth('sys:role:update')"
type="primary" type="primary"
@ -46,7 +39,6 @@
编辑 编辑
</el-button> </el-button>
<!-- 删除按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:role:delete')" v-if="isAuth('sys:role:delete')"
type="danger" type="danger"
@ -68,119 +60,94 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive } from 'vue' import { isAuth } from '@/utils'
import { isAuth } from '@/utils' // import { ElMessage, ElMessageBox } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus' // import { tableOption } from '@/crud/sys/role.js'
import { tableOption } from '@/crud/sys/role.js' // import AddOrUpdate from './add-or-update.vue'
import AddOrUpdate from './add-or-update.vue' // /
//
const dataList = ref([]) const dataList = ref([])
//
const dataListSelections = ref([]) const dataListSelections = ref([])
// 使reactive使
const page = reactive({ const page = reactive({
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 10 // pageSize: 10 //
}) })
/** /**
* 获取数据列表方法 * 获取数据列表
* @param pageParam 分页参数可选
* @param params 搜索参数可选
* @param done 加载完成回调可选
*/ */
const getDataList = (pageParam, params, done) => { const getDataList = (pageParam, params, done) => {
http({ http({
url: http.adornUrl('/sys/role/page'), // API url: http.adornUrl('/sys/role/page'),
method: 'get', // method: 'get',
params: http.adornParams( params: http.adornParams(
Object.assign( Object.assign(
{ {
current: pageParam == null ? page.currentPage : pageParam.currentPage, // current: pageParam == null ? page.currentPage : pageParam.currentPage,
size: pageParam == null ? page.pageSize : pageParam.pageSize // size: pageParam == null ? page.pageSize : pageParam.pageSize
}, },
params // params
) )
) )
}) })
.then(({ data }) => { .then(({ data }) => {
dataList.value = data.records // dataList.value = data.records
page.total = data.total // page.total = data.total
if (done) { if (done) {
done() // done()
} }
}) })
} }
/** /**
* 条件查询方法 * 条件查询
* @param params 搜索参数
* @param done 加载完成回调可选
*/ */
const onSearch = (params, done) => { const onSearch = (params, done) => {
getDataList(page, params, done) getDataList(page, params, done)
} }
/** /**
* 多选变化方法 * 多选变化
* @param val 选择的数据项
*/ */
const selectionChange = (val) => { const selectionChange = (val) => {
dataListSelections.value = val // dataListSelections.value = val
} }
//
const addOrUpdateVisible = ref(false) const addOrUpdateVisible = ref(false)
//
const addOrUpdateRef = ref(null) const addOrUpdateRef = ref(null)
/** /**
* 新增 / 修改角色信息 * 新增 / 修改
* @param id 角色ID可选如果没有传入则表示新增
*/ */
const onAddOrUpdate = (id) => { const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true // addOrUpdateVisible.value = true
nextTick(() => { nextTick(() => {
addOrUpdateRef.value?.init(id) // addOrUpdateRef.value?.init(id)
}) })
} }
/** /**
* 删除角色信息 * 删除
* @param id 角色ID可选如果传入则为单个删除否则为批量删除
*/ */
const onDelete = (id) => { const onDelete = (id) => {
const ids = id ? [id] : dataListSelections.value?.map(item => item.roleId) // ID const ids = id ? [id] : dataListSelections.value?.map(item => {
return item.roleId
// })
ElMessageBox.confirm(`确定进行[${id ? '删除' : '批量删除'}]操作?`, '提示', { ElMessageBox.confirm(`确定进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}) })
.then(() => { .then(() => {
// HTTP
http({ http({
url: http.adornUrl('/sys/role'), url: http.adornUrl('/sys/role'),
method: 'delete', method: 'delete',
data: http.adornData(ids, false) // ID data: http.adornData(ids, false)
}) })
.then(() => { .then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
getDataList() // getDataList()
} }
}) })
}) })
}).catch(() => { /* 用户取消删除操作 */ }) }).catch(() => { })
} }
</script> </script>

@ -1,11 +1,9 @@
<template> <template>
<!-- 用户管理对话框 -->
<el-dialog <el-dialog
v-model="visible" v-model="visible"
:title="!dataForm.id ? '新增' : '修改'" :title="!dataForm.id ? '新增' : '修改'"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<!-- 表单 -->
<el-form <el-form
ref="dataFormRef" ref="dataFormRef"
:model="dataForm" :model="dataForm"
@ -13,7 +11,6 @@
label-width="80px" label-width="80px"
@keyup.enter="onSubmit()" @keyup.enter="onSubmit()"
> >
<!-- 用户名输入框 -->
<el-form-item <el-form-item
label="用户名" label="用户名"
prop="userName" prop="userName"
@ -23,8 +20,6 @@
placeholder="登录帐号" placeholder="登录帐号"
/> />
</el-form-item> </el-form-item>
<!-- 密码输入框 -->
<el-form-item <el-form-item
label="密码" label="密码"
prop="password" prop="password"
@ -36,8 +31,6 @@
placeholder="密码" placeholder="密码"
/> />
</el-form-item> </el-form-item>
<!-- 确认密码输入框 -->
<el-form-item <el-form-item
label="确认密码" label="确认密码"
prop="comfirmPassword" prop="comfirmPassword"
@ -49,8 +42,6 @@
placeholder="确认密码" placeholder="确认密码"
/> />
</el-form-item> </el-form-item>
<!-- 邮箱输入框 -->
<el-form-item <el-form-item
label="邮箱" label="邮箱"
prop="email" prop="email"
@ -60,8 +51,6 @@
placeholder="邮箱" placeholder="邮箱"
/> />
</el-form-item> </el-form-item>
<!-- 手机号输入框 -->
<el-form-item <el-form-item
label="手机号" label="手机号"
prop="mobile" prop="mobile"
@ -72,193 +61,171 @@
placeholder="手机号" placeholder="手机号"
/> />
</el-form-item> </el-form-item>
<!-- 角色选择 -->
<el-form-item <el-form-item
label="角色" label="角色"
prop="roleIdList" prop="roleIdList"
> >
<el-checkbox-group v-model="dataForm.roleIdList"> <!-- ID --> <el-checkbox-group v-model="dataForm.roleIdList">
<el-checkbox <el-checkbox
v-for="role in roleList" v-for="role in roleList"
:key="role.roleId" :key="role.roleId"
:label="role.roleId" :label="role.roleId"
> >
{{ role.roleName }} <!-- 显示角色名称 --> {{ role.roleName }}
</el-checkbox> </el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-form-item> </el-form-item>
<!-- 状态选择 -->
<el-form-item <el-form-item
label="状态" label="状态"
prop="status" prop="status"
> >
<el-radio-group v-model="dataForm.status"> <!-- --> <el-radio-group v-model="dataForm.status">
<el-radio :label="0">禁用</el-radio> <!-- --> <el-radio :label="0">
<el-radio :label="1">正常</el-radio> <!-- --> 禁用
</el-radio>
<el-radio :label="1">
正常
</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 对话框底部按钮组 -->
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="visible = false">取消</el-button> <!-- --> <el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="onSubmit()"></el-button> <!-- 确认按钮 --> <el-button
type="primary"
@click="onSubmit()"
>确定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { ref, reactive, nextTick } from 'vue' import { ElMessage } from 'element-plus'
import { ElMessage } from 'element-plus' // import { isEmail, isMobile } from '@/utils/validate'
import { isEmail, isMobile } from '@/utils/validate' // import { Debounce } from '@/utils/debounce'
import { Debounce } from '@/utils/debounce' // import { encrypt } from '@/utils/crypto'
import { encrypt } from '@/utils/crypto' //
//
const emit = defineEmits(['refreshDataList']) const emit = defineEmits(['refreshDataList'])
//
const visible = ref(false) const visible = ref(false)
// 使reactive使
const dataForm = reactive({ const dataForm = reactive({
id: 0, // ID0 id: 0,
userName: '', // userName: '',
password: '', // password: '',
comfirmPassword: '', // comfirmPassword: '',
email: '', // email: '',
mobile: '', // mobile: '',
roleIdList: [], // ID roleIdList: [],
status: 1 // 1 status: 1
}) })
// // eslint-disable-next-line no-unused-vars
const validatePassword = (rule, value, callback) => { const validatePassword = (rule, value, callback) => {
if (!dataForm.id && !/\S/.test(value)) { // if (!dataForm.id && !/\S/.test(value)) {
callback(new Error('密码不能为空')) callback(new Error('密码不能为空'))
} else { } else {
callback() // callback()
} }
} }
// eslint-disable-next-line no-unused-vars
//
const validateComfirmPassword = (rule, value, callback) => { const validateComfirmPassword = (rule, value, callback) => {
if (!dataForm.id && !/\S/.test(value)) { // if (!dataForm.id && !/\S/.test(value)) {
dataForm.password = '' dataForm.password = ''
callback(new Error('确认密码不能为空')) callback(new Error('确认密码不能为空'))
} else if (dataForm.password !== value) { // } else if (dataForm.password !== value) {
callback(new Error('确认密码与密码输入不一致')) callback(new Error('确认密码与密码输入不一致'))
} else { } else {
callback() // callback()
} }
} }
// eslint-disable-next-line no-unused-vars
//
const validateEmail = (rule, value, callback) => { const validateEmail = (rule, value, callback) => {
if (!isEmail(value)) { // if (!isEmail(value)) {
callback(new Error('邮箱格式错误')) callback(new Error('邮箱格式错误'))
} else { } else {
callback() // callback()
} }
} }
// eslint-disable-next-line no-unused-vars
//
const validateMobile = (rule, value, callback) => { const validateMobile = (rule, value, callback) => {
if (!isMobile(value)) { // if (!isMobile(value)) {
callback(new Error('手机号格式错误')) callback(new Error('手机号格式错误'))
} else { } else {
callback() // callback()
} }
} }
const dataRule = {
// 使reactive使
const dataRule = reactive({
userName: [ userName: [
{ required: true, message: '用户名不能为空', trigger: 'blur' }, // { required: true, message: '用户名不能为空', trigger: 'blur' },
{ pattern: /\s\S+|\S+\s|\S/, message: '请输入正确的用户名', trigger: 'blur' } // { pattern: /\s\S+|S+\s|\S/, message: '请输入正确的用户名', trigger: 'blur' }
], ],
password: [ password: [
{ validator: validatePassword, trigger: 'blur' } // { validator: validatePassword, trigger: 'blur' }
], ],
comfirmPassword: [ comfirmPassword: [
{ validator: validateComfirmPassword, trigger: 'blur' } // { validator: validateComfirmPassword, trigger: 'blur' }
], ],
email: [ email: [
{ required: true, message: '邮箱不能为空', trigger: 'blur' }, // { required: true, message: '邮箱不能为空', trigger: 'blur' },
{ validator: validateEmail, trigger: 'blur' } // { validator: validateEmail, trigger: 'blur' }
], ],
mobile: [ mobile: [
{ required: true, message: '手机号不能为空', trigger: 'blur' }, // { required: true, message: '手机号不能为空', trigger: 'blur' },
{ validator: validateMobile, trigger: 'blur' } // { validator: validateMobile, trigger: 'blur' }
] ]
}) }
//
const roleList = ref([]) const roleList = ref([])
//
const dataFormRef = ref(null) const dataFormRef = ref(null)
/**
* 初始化方法接收可选的用户ID参数
* @param id 用户ID可选
*/
const init = (id) => { const init = (id) => {
dataForm.id = id || 0 // id dataForm.id = id || 0
//
http({ http({
url: http.adornUrl('/sys/role/list'), // API url: http.adornUrl('/sys/role/list'),
method: 'get', // method: 'get',
params: http.adornParams() // params: http.adornParams()
}).then(({ data }) => { }).then(({ data }) => {
roleList.value = data // roleList.value = data
}).then(() => {
visible.value = true //
return nextTick() // DOM
}).then(() => { }).then(() => {
dataFormRef.value?.resetFields() // visible.value = true
nextTick(() => {
dataFormRef.value?.resetFields()
})
}).then(() => { }).then(() => {
if (dataForm.id) { // if (dataForm.id) {
http({ http({
url: http.adornUrl(`/sys/user/info/${dataForm.id}`), // API url: http.adornUrl(`/sys/user/info/${dataForm.id}`),
method: 'get', // method: 'get',
params: http.adornParams() // params: http.adornParams()
}).then(({ data }) => { }).then(({ data }) => {
dataForm.userName = data.username // dataForm.userName = data.username
dataForm.email = data.email // dataForm.email = data.email
dataForm.mobile = data.mobile // dataForm.mobile = data.mobile
dataForm.roleIdList = data.roleIdList // ID dataForm.roleIdList = data.roleIdList
dataForm.status = data.status // dataForm.status = data.status
}) })
} }
}) })
} }
// init便
defineExpose({ init }) defineExpose({ init })
/** /**
* 提交表单方法 * 表单提交
*/ */
const onSubmit = Debounce(() => { // 使 const onSubmit = Debounce(() => {
dataFormRef.value?.validate((valid) => { // dataFormRef.value?.validate((valid) => {
if (valid) { // if (valid) {
http({ http({
url: http.adornUrl('/sys/user'), // API url: http.adornUrl('/sys/user'),
method: dataForm.id ? 'put' : 'post', // id method: dataForm.id ? 'put' : 'post',
data: http.adornData({ data: http.adornData({
userId: dataForm.id || undefined, // ID userId: dataForm.id || undefined,
username: dataForm.userName, // username: dataForm.userName,
password: encrypt(dataForm.password), // password: encrypt(dataForm.password),
email: dataForm.email, // email: dataForm.email,
mobile: dataForm.mobile, // mobile: dataForm.mobile,
status: dataForm.status, // status: dataForm.status,
roleIdList: dataForm.roleIdList // ID roleIdList: dataForm.roleIdList
}) })
}).then(() => { }).then(() => {
ElMessage({ ElMessage({
@ -266,12 +233,13 @@ const onSubmit = Debounce(() => { // 使用防抖函数防止快速点击多次
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
visible.value = false // visible.value = false
emit('refreshDataList') // emit('refreshDataList')
} }
}) })
}) })
} }
}) })
}) })
</script> </script>

@ -1,7 +1,5 @@
<template> <template>
<!-- 用户管理模块 -->
<div class="mod-user"> <div class="mod-user">
<!-- 使用avue-crud创建CRUD表格 -->
<avue-crud <avue-crud
ref="crudRef" ref="crudRef"
:page="page" :page="page"
@ -11,9 +9,7 @@
@selection-change="selectionChange" @selection-change="selectionChange"
@on-load="getDataList" @on-load="getDataList"
> >
<!-- 左侧菜单栏 -->
<template #menu-left> <template #menu-left>
<!-- 新增按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:user:save')" v-if="isAuth('sys:user:save')"
type="primary" type="primary"
@ -23,20 +19,19 @@
新增 新增
</el-button> </el-button>
<!-- 批量删除按钮只有有权限且选择了项目时显示 -->
<el-button <el-button
v-if="isAuth('sys:user:delete')" v-if="isAuth('sys:user:delete')"
type="danger" type="danger"
:disabled="dataListSelections.length <= 0" :disabled="dataListSelections.length <= 0"
@click="onDelete()" @click="onDelete()"
> >
批量删除 批量删除
</el-button> </el-button>
</template> </template>
<template
<!-- 行内菜单 --> #menu="scope"
<template #menu="scope"> <!-- 自定义行内菜单 --> >
<!-- 编辑按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:user:update')" v-if="isAuth('sys:user:update')"
type="primary" type="primary"
@ -46,7 +41,6 @@
编辑 编辑
</el-button> </el-button>
<!-- 删除按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('sys:user:delete')" v-if="isAuth('sys:user:delete')"
type="danger" type="danger"
@ -68,120 +62,94 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, nextTick } from 'vue' import { isAuth } from '@/utils'
import { isAuth } from '@/utils' // import { ElMessage, ElMessageBox } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus' // import { tableOption } from '@/crud/sys/user.js'
import { tableOption } from '@/crud/sys/user.js' // import AddOrUpdate from './add-or-update.vue'
import AddOrUpdate from './add-or-update.vue' // /
//
const dataList = ref([]) const dataList = ref([])
//
const dataListLoading = ref(false) const dataListLoading = ref(false)
//
const dataListSelections = ref([]) const dataListSelections = ref([])
//
const addOrUpdateVisible = ref(false) const addOrUpdateVisible = ref(false)
// 使reactive使
const page = reactive({ const page = reactive({
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 10 // pageSize: 10 //
}) })
/** /**
* 获取数据列表方法 * 获取数据列表
* @param pageParam 分页参数可选
* @param params 搜索参数可选
* @param done 加载完成回调可选
*/ */
const getDataList = (pageParam, params, done) => { const getDataList = (pageParam, params, done) => {
dataListLoading.value = true // true dataListLoading.value = true
http({ http({
url: http.adornUrl('/sys/user/page'), // API url: http.adornUrl('/sys/user/page'),
method: 'get', // method: 'get',
params: http.adornParams( params: http.adornParams(
Object.assign( Object.assign(
{ {
current: pageParam == null ? page.currentPage : pageParam.currentPage, // current: pageParam == null ? page.currentPage : pageParam.currentPage,
size: pageParam == null ? page.pageSize : pageParam.pageSize // size: pageParam == null ? page.pageSize : pageParam.pageSize
}, },
params // params
) )
) )
}).then(({ data }) => { }).then(({ data }) => {
dataList.value = data.records // dataList.value = data.records
page.total = data.total // page.total = data.total
dataListLoading.value = false // false dataListLoading.value = false
if (done) done() // if (done) done()
}) })
} }
/** /**
* 条件查询方法 * 条件查询
* @param params 搜索参数
* @param done 加载完成回调可选
*/ */
const onSearch = (params, done) => { const onSearch = (params, done) => {
getDataList(page, params, done) getDataList(page, params, done)
} }
/** /**
* 多选变化方法 * 多选变化
* @param val 选择的数据项
*/ */
const selectionChange = (val) => { const selectionChange = (val) => {
dataListSelections.value = val // dataListSelections.value = val
} }
//
const addOrUpdateRef = ref(null) const addOrUpdateRef = ref(null)
/** /**
* 新增 / 修改用户信息 * 新增 / 修改
* @param id 用户ID可选如果没有传入则表示新增
*/ */
const onAddOrUpdate = (id) => { const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true // addOrUpdateVisible.value = true
nextTick(() => { nextTick(() => {
addOrUpdateRef.value?.init(id) // addOrUpdateRef.value?.init(id)
}) })
} }
/** /**
* 删除用户信息 * 删除
* @param id 用户ID可选如果传入则为单个删除否则为批量删除
*/ */
const onDelete = (id) => { const onDelete = (id) => {
const userIds = id ? [id] : dataListSelections.value?.map(item => item.userId) // ID const userIds = id ? [id] : dataListSelections.value?.map(item => {
return item.userId
// })
ElMessageBox.confirm(`确定对[id=${userIds.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', { ElMessageBox.confirm(`确定对[id=${userIds.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
// HTTP
http({ http({
url: http.adornUrl('/sys/user'), url: http.adornUrl('/sys/user'),
method: 'delete', method: 'delete',
data: http.adornData(userIds, false) // ID data: http.adornData(userIds, false)
}).then(() => { }).then(() => {
//
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
getDataList() // getDataList()
} }
}) })
}) })
}).catch(() => { /* 用户取消删除操作 */ }) }).catch(() => { })
} }
</script> </script>

@ -1,11 +1,9 @@
<template> <template>
<!-- 用户管理对话框 -->
<el-dialog <el-dialog
v-model="visible" v-model="visible"
:title="!dataForm.userId ? '新增' : '修改'" :title="!dataForm.userId ? '新增' : '修改'"
:close-on-click-modal="false" :close-on-click-modal="false"
> >
<!-- 表单 -->
<el-form <el-form
ref="dataFormRef" ref="dataFormRef"
:model="dataForm" :model="dataForm"
@ -13,7 +11,6 @@
label-width="80px" label-width="80px"
@keyup.enter="onSubmit()" @keyup.enter="onSubmit()"
> >
<!-- 用户头像展示 -->
<el-form-item <el-form-item
label="用户头像" label="用户头像"
prop="pic" prop="pic"
@ -23,11 +20,11 @@
:src="dataForm.pic" :src="dataForm.pic"
class="image" class="image"
alt="" alt=""
/> >
<div v-else></div> <!-- --> <div v-else>
</div>
</el-form-item> </el-form-item>
<!-- 用户昵称输入框 -->
<el-form-item <el-form-item
label="用户昵称" label="用户昵称"
prop="nickName" prop="nickName"
@ -38,115 +35,105 @@
placeholder="用户昵称" placeholder="用户昵称"
/> />
</el-form-item> </el-form-item>
<!-- 状态选择 -->
<el-form-item <el-form-item
label="状态" label="状态"
prop="status" prop="status"
> >
<el-radio-group v-model="dataForm.status"> <!-- --> <el-radio-group v-model="dataForm.status">
<el-radio :label="0">禁用</el-radio> <!-- --> <el-radio :label="0">
<el-radio :label="1">正常</el-radio> <!-- --> 禁用
</el-radio>
<el-radio :label="1">
正常
</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-form> </el-form>
<!-- 对话框底部按钮组 -->
<template #footer> <template #footer>
<span class="dialog-footer"> <span
<el-button @click="visible = false">取消</el-button> <!-- --> class="dialog-footer"
<el-button type="primary" @click="onSubmit()"></el-button> <!-- 确认按钮 --> >
<el-button @click="visible = false">取消</el-button>
<el-button
type="primary"
@click="onSubmit()"
>确定</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import { ref, reactive, nextTick } from 'vue' import { ElMessage } from 'element-plus'
import { ElMessage } from 'element-plus' // import { Debounce } from '@/utils/debounce'
import { Debounce } from '@/utils/debounce' //
//
const emit = defineEmits(['refreshDataList']) const emit = defineEmits(['refreshDataList'])
//
const visible = ref(false) const visible = ref(false)
// 使ref使
const dataForm = ref({ const dataForm = ref({
userId: 0, // ID0 userId: 0,
nickName: '', // nickName: '',
pic: '', // pic: '',
status: 1 // 1 status: 1
}) })
// 使reactive使
const page = reactive({ const page = reactive({
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 10 // pageSize: 10 //
}) })
// 使
const dataRule = { const dataRule = {
nickName: [ nickName: [
{ required: true, message: '用户名不能为空', trigger: 'blur' } // { required: true, message: '用户名不能为空', trigger: 'blur' }
] ]
} }
//
const dataFormRef = ref(null) const dataFormRef = ref(null)
/**
* 初始化方法接收可选的用户ID参数
* @param id 用户ID可选
*/
const init = (id) => { const init = (id) => {
dataForm.value.userId = id || 0 // id dataForm.value.userId = id || 0
visible.value = true // visible.value = true
nextTick(() => { nextTick(() => {
dataFormRef.value?.resetFields() // dataFormRef.value?.resetFields()
}) })
if (dataForm.value.userId) { // if (dataForm.value.userId) {
http({ http({
url: http.adornUrl(`/admin/user/info/${dataForm.value.userId}`), // API url: http.adornUrl(`/admin/user/info/${dataForm.value.userId}`),
method: 'get', // method: 'get',
params: http.adornParams() // params: http.adornParams()
}).then(({ data }) => { })
dataForm.value = data // .then(({ data }) => {
dataForm.value = data
}) })
} }
} }
// init便
defineExpose({ init }) defineExpose({ init })
/** /**
* 提交表单方法 * 表单提交
*/ */
const onSubmit = Debounce(() => { // 使 const onSubmit = Debounce(() => {
dataFormRef.value?.validate((valid) => { // dataFormRef.value?.validate(valid => {
if (valid) { // if (valid) {
http({ http({
url: http.adornUrl('/admin/user'), // API url: http.adornUrl('/admin/user'),
method: dataForm.value.userId ? 'put' : 'post', // userId method: dataForm.value.userId ? 'put' : 'post',
data: http.adornData({ data: http.adornData({
userId: dataForm.value.userId || undefined, // ID userId: dataForm.value.userId || undefined,
nickName: dataForm.value.nickName, // nickName: dataForm.value.nickName,
status: dataForm.value.status // status: dataForm.value.status
}) })
}).then(() => { })
.then(() => {
ElMessage({ ElMessage({
message: '操作成功', message: '操作成功',
type: 'success', type: 'success',
duration: 1500, duration: 1500,
onClose: () => { onClose: () => {
visible.value = false // visible.value = false
emit('refreshDataList', page) // emit('refreshDataList', page)
} }
}) })
}) })
} }
}) })
}) })
</script> </script>

@ -1,7 +1,5 @@
<template> <template>
<!-- 用户管理模块 -->
<div class="mod-user"> <div class="mod-user">
<!-- 使用avue-crud创建CRUD表格 -->
<avue-crud <avue-crud
ref="crudRef" ref="crudRef"
:page="page" :page="page"
@ -11,17 +9,21 @@
@selection-change="selectionChange" @selection-change="selectionChange"
@on-load="getDataList" @on-load="getDataList"
> >
<!-- 自定义列模板用户头像 --> <template #pic="scope">
<template #pic="scope"> <!-- 自定义用户头像列 --> <span
<span v-if="scope.row.pic" class="avue-crud__img"> v-if="scope.row.pic"
<el-icon><Document /></el-icon> <!-- --> class="avue-crud__img"
>
<el-icon><Document /></el-icon>
</span> </span>
<span v-else>-</span> <!-- "-" --> <span v-else>-</span>
</template> </template>
<!-- 自定义列模板状态 --> <template #status="scope">
<template #status="scope"> <!-- 自定义状态列 --> <el-tag
<el-tag v-if="scope.row.status === 0" type="danger"> v-if="scope.row.status === 0"
type="danger"
>
禁用 禁用
</el-tag> </el-tag>
<el-tag v-else> <el-tag v-else>
@ -29,9 +31,7 @@
</el-tag> </el-tag>
</template> </template>
<!-- 自定义行内菜单 --> <template #menu="scope">
<template #menu="scope"> <!-- 自定义行内菜单 -->
<!-- 编辑按钮只有有权限时显示 -->
<el-button <el-button
v-if="isAuth('admin:user:update')" v-if="isAuth('admin:user:update')"
type="primary" type="primary"
@ -53,87 +53,68 @@
</template> </template>
<script setup> <script setup>
import { ref, reactive, nextTick } from 'vue' import { isAuth } from '@/utils'
import { isAuth } from '@/utils' // import { tableOption } from '@/crud/user/user.js'
import { tableOption } from '@/crud/user/user.js' // import AddOrUpdate from './add-or-update.vue'
import AddOrUpdate from './add-or-update.vue' // /
//
const dataList = ref([]) const dataList = ref([])
//
const dataListLoading = ref(false) const dataListLoading = ref(false)
//
const dataListSelections = ref([]) const dataListSelections = ref([])
//
const addOrUpdateVisible = ref(false) const addOrUpdateVisible = ref(false)
// 使reactive使
const page = reactive({ const page = reactive({
total: 0, // total: 0, //
currentPage: 1, // currentPage: 1, //
pageSize: 10 // pageSize: 10 //
}) })
/** /**
* 获取数据列表方法 * 获取数据列表
* @param pageParam 分页参数可选
* @param params 搜索参数可选
* @param done 加载完成回调可选
*/ */
const getDataList = (pageParam, params, done) => { const getDataList = (pageParam, params, done) => {
dataListLoading.value = true // true dataListLoading.value = true
http({ http({
url: http.adornUrl('/admin/user/page'), // API url: http.adornUrl('/admin/user/page'),
method: 'get', // method: 'get',
params: http.adornParams( params: http.adornParams(
Object.assign( Object.assign(
{ {
current: pageParam == null ? page.currentPage : pageParam.currentPage, // current: pageParam == null ? page.currentPage : pageParam.currentPage,
size: pageParam == null ? page.pageSize : pageParam.pageSize // size: pageParam == null ? page.pageSize : pageParam.pageSize
}, },
params // params
) )
) )
}).then(({ data }) => { })
dataList.value = data.records // .then(({ data }) => {
page.total = data.total // dataList.value = data.records
dataListLoading.value = false // false page.total = data.total
if (done) done() // dataListLoading.value = false
if (done) done()
}) })
} }
//
const addOrUpdateRef = ref(null) const addOrUpdateRef = ref(null)
/** /**
* 新增 / 修改用户信息 * 新增 / 修改
* @param id 用户ID可选如果没有传入则表示新增 * @param id
*/ */
const onAddOrUpdate = (id) => { const onAddOrUpdate = (id) => {
addOrUpdateVisible.value = true // addOrUpdateVisible.value = true
nextTick(() => { nextTick(() => {
addOrUpdateRef.value?.init(id) // addOrUpdateRef.value?.init(id)
}) })
} }
/** /**
* 条件查询方法 * 条件查询
* @param params 搜索参数
* @param done 加载完成回调可选
*/ */
const onSearch = (params, done) => { const onSearch = (params, done) => {
getDataList(page, params, done) getDataList(page, params, done)
} }
/** /**
* 多选变化方法 * 多选变化
* @param val 选择的数据项
*/ */
const selectionChange = (val) => { const selectionChange = (val) => {
dataListSelections.value = val // dataListSelections.value = val
} }
</script> </script>

Loading…
Cancel
Save