Compare commits

..

2 Commits

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

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

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

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

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

@ -1,162 +1,182 @@
<template>
<!-- 对话框组件 -->
<el-dialog
v-model="visible"
:title="!dataForm.id ? '新增' : '修改'"
:close-on-click-modal="false"
:title="!dataForm.id ? '新增' : '修改'"
:close-on-click-modal="false"
>
<el-form
ref="dataFormRef"
:model="dataForm"
:rules="dataRule"
label-width="80px"
@keyup.enter="onSubmit()"
>
<el-form-item
label="类型"
prop="type"
>
<el-radio-group v-model="dataForm.type">
<el-radio
v-for="(type, index) in dataForm.typeList"
:key="index"
:label="index"
>
{{ type }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
:label="dataForm.typeList[dataForm.type] + '名称'"
prop="name"
>
<el-input
v-model="dataForm.name"
:placeholder="dataForm.typeList[dataForm.type] + '名称'"
/>
</el-form-item>
<el-form-item label="上级菜单">
<el-cascader
v-model="selectedMenu"
expand-trigger="hover"
:options="menuList"
:props="menuListTreeProps"
change-on-select
:clearable="true"
@change="handleSelectMenuChange"
/>
</el-form-item>
<el-form-item
v-if="dataForm.type === 1"
label="菜单路由"
prop="url"
>
<el-input
v-model="dataForm.url"
placeholder="菜单路由"
/>
</el-form-item>
<el-form-item
v-if="dataForm.type !== 0"
label="授权标识"
prop="perms"
<!-- 表单组件 -->
<el-form
ref="dataFormRef"
:model="dataForm"
:rules="dataRule"
label-width="80px"
@keyup.enter="onSubmit()"
>
<!-- 类型选择项 -->
<el-form-item
label="类型"
prop="type"
>
<el-radio-group v-model="dataForm.type">
<el-radio
v-for="(type, index) in dataForm.typeList"
:key="index"
:label="index"
>
{{ type }}
</el-radio>
</el-radio-group>
</el-form-item>
<!-- 动态标签根据类型改变 -->
<el-form-item
:label="dataForm.typeList[dataForm.type] + '名称'"
prop="name"
>
<el-input
v-model="dataForm.name"
:placeholder="dataForm.typeList[dataForm.type] + '名称'"
/>
</el-form-item>
<!-- 上级菜单选择 -->
<el-form-item label="上级菜单">
<el-cascader
v-model="selectedMenu"
expand-trigger="hover"
:options="menuList"
:props="menuListTreeProps"
change-on-select
:clearable="true"
@change="handleSelectMenuChange"
/>
</el-form-item>
<!-- 菜单路由输入仅当类型为1时显示 -->
<el-form-item
v-if="dataForm.type === 1"
label="菜单路由"
prop="url"
>
<el-input
v-model="dataForm.url"
placeholder="菜单路由"
/>
</el-form-item>
<!-- 授权标识输入除类型0外显示 -->
<el-form-item
v-if="dataForm.type !== 0"
label="授权标识"
prop="perms"
>
<el-input
v-model="dataForm.perms"
placeholder="多个用逗号分隔, 如: user:list,user:create"
/>
</el-form-item>
<!-- 排序号输入除类型2外显示 -->
<el-form-item
v-if="dataForm.type !== 2"
label="排序号"
prop="orderNum"
>
<el-input-number
v-model="dataForm.orderNum"
controls-position="right"
:min="0"
label="排序号"
/>
</el-form-item>
<!-- 菜单图标选择除类型2外显示 -->
<el-form-item
v-if="dataForm.type !== 2"
label="菜单图标"
prop="icon"
>
<el-row>
<el-col :span="22">
<el-input
v-model="dataForm.perms"
placeholder="多个用逗号分隔, 如: user:list,user:create"
ref="iconInputRef"
v-model="dataForm.icon"
:virtual-ref="iconListPopoverRef"
placeholder="菜单图标名称"
clearable
/>
</el-form-item>
<el-form-item
v-if="dataForm.type !== 2"
label="排序号"
prop="orderNum"
>
<el-input-number
v-model="dataForm.orderNum"
controls-position="right"
:min="0"
label="排序号"
/>
</el-form-item>
<el-form-item
v-if="dataForm.type !== 2"
label="菜单图标"
prop="icon"
>
<el-row>
<el-col :span="22">
<el-input
ref="iconInputRef"
v-model="dataForm.icon"
:virtual-ref="iconListPopoverRef"
placeholder="菜单图标名称"
clearable
/>
<el-popover
ref="iconListPopoverRef"
style="width: 390px"
:virtual-ref="iconInputRef"
placement="bottom-start"
trigger="click"
:popper-style="iconPopoverClass"
virtual-triggering
>
<el-button
v-for="(item, index) in iconList"
:key="index"
style="padding: 8px; margin: 8px 0 0 8px"
:class="{ 'is-active': item === dataForm.icon }"
@click="iconActiveHandle(item)"
>
<svg-icon
:icon-class="`${item}`"
/>
</el-button>
</el-popover>
</el-col>
<el-col
:span="2"
class="icon-list__tips"
<el-popover
ref="iconListPopoverRef"
style="width: 390px"
:virtual-ref="iconInputRef"
placement="bottom-start"
trigger="click"
:popper-style="iconPopoverClass"
virtual-triggering
>
<el-button
v-for="(item, index) in iconList"
:key="index"
style="padding: 8px; margin: 8px 0 0 8px"
:class="{ 'is-active': item === dataForm.icon }"
@click="iconActiveHandle(item)"
>
<el-tooltip
placement="top"
effect="light"
>
<template #content>
<div>全站推荐使用SVG Sprite, 详细请参考:icons/index.js 描述</div>
</template>
<i class="el-icon-warning" />
</el-tooltip>
</el-col>
</el-row>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">取消</el-button>
<el-button
type="primary"
@click="onSubmit()"
<svg-icon
:icon-class="`${item}`"
/>
</el-button>
</el-popover>
</el-col>
<el-col
:span="2"
class="icon-list__tips"
>
<el-tooltip
placement="top"
effect="light"
>
确定
</el-button>
<template #content>
<div>全站推荐使用SVG Sprite, 详细请参考:icons/index.js 描述</div>
</template>
<i class="el-icon-warning" />
</el-tooltip>
</el-col>
</el-row>
</el-form-item>
</el-form>
<!-- 对话框底部操作按钮 -->
<template #footer>
<span class="dialog-footer">
<el-button @click="visible = false">取消</el-button> <!-- -->
<el-button type="primary" @click="onSubmit()"></el-button> <!-- 提交表单 -->
</span>
</template>
</template>
</el-dialog>
</template>
<script setup>
import { treeDataTranslate, idList } from '@/utils'
import { ElMessage } from 'element-plus'
import { ref, reactive, computed, onMounted, nextTick, defineEmits, defineExpose } from 'vue'
//
const emit = defineEmits(['refreshDataList'])
//
const iconInputRef = ref(null)
const iconListPopoverRef = ref(null)
const iconPopoverClass = computed(() => {
return {
width: '396px'
}
})
//
const iconPopoverClass = computed(() => ({
width: '396px'
}))
//
const visible = ref(false)
// 使reactive
const dataForm = reactive({
id: 0,
type: 1,
@ -169,15 +189,19 @@ const dataForm = reactive({
icon: '',
iconList: []
})
//
const menuList = ref([])
const selectedMenu = ref([])
//
const menuListTreeProps = {
value: 'menuId',
label: 'name',
checkStrictly: true
}
// eslint-disable-next-line no-unused-vars
// URL
const validateUrl = (rule, value, callback) => {
if (dataForm.type === 1 && !/\S/.test(value)) {
callback(new Error('菜单URL不能为空'))
@ -185,6 +209,8 @@ const validateUrl = (rule, value, callback) => {
callback()
}
}
//
const dataRule = ref({
name: [
{ required: true, message: '菜单名称不能为空', trigger: 'blur' },
@ -195,10 +221,11 @@ const dataRule = ref({
]
})
//
onMounted(() => {
onLoadIcons()
})
const iconList = []
/**
* 加载图标
*/
@ -206,35 +233,42 @@ const onLoadIcons = () => {
const icons = import.meta.glob('@/icons/svg/*.svg')
for (const icon in icons) {
const iconName = icon.split('/src/icons/svg/')[1].split('.svg')[0]
iconList.push(iconName)
dataForm.iconList.push(iconName)
}
}
//
const dataFormRef = ref(null)
/**
* 初始化方法接收id作为参数
* @param id 菜单项ID
*/
const init = (id) => {
dataForm.id = id || 0
dataForm.id = id || 0 // ID
http({
url: http.adornUrl('/sys/menu/list'),
method: 'get',
params: http.adornParams()
})
.then(({ data }) => {
menuList.value = treeDataTranslate(data, 'menuId')
menuList.value = treeDataTranslate(data, 'menuId') //
})
.then(() => {
visible.value = true
visible.value = true //
nextTick(() => {
dataFormRef.value?.resetFields()
dataFormRef.value?.resetFields() //
})
})
.then(() => {
if (dataForm.id) {
//
// id
http({
url: http.adornUrl(`/sys/menu/info/${dataForm.id}`),
method: 'get',
params: http.adornParams()
}).then(({ data }) => {
//
dataForm.id = data.menuId
dataForm.type = data.type
dataForm.name = data.name
@ -246,31 +280,39 @@ const init = (id) => {
selectedMenu.value = idList(menuList.value, data.parentId, 'menuId', 'children').reverse()
})
} else {
selectedMenu.value = []
selectedMenu.value = [] //
}
})
}
defineExpose({ init })
/**
* 上级菜单选择变化处理
* @param val 选中的菜单路径
*/
const handleSelectMenuChange = (val) => {
dataForm.parentId = val[val.length - 1]
dataForm.parentId = val[val.length - 1] // parentIdID
}
/**
* 图标选中
* @param iconName
* 图标选中处理
* @param iconName 选中的图标名称
*/
const iconActiveHandle = (iconName) => {
dataForm.icon = iconName
dataForm.icon = iconName //
}
/**
* 表单提交
*/
const onSubmit = Debounce(() => {
//
dataFormRef.value?.validate((valid) => {
if (valid) {
// HTTP
http({
url: http.adornUrl('/sys/menu'),
method: dataForm.id ? 'put' : 'post',
method: dataForm.id ? 'put' : 'post', //
data: http.adornData({
menuId: dataForm.id || undefined,
type: dataForm.type,
@ -283,13 +325,14 @@ const onSubmit = Debounce(() => {
})
})
.then(() => {
//
ElMessage({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
visible.value = false
emit('refreshDataList')
visible.value = false //
emit('refreshDataList') //
}
})
})

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

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

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

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

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

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

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

Loading…
Cancel
Save