feat 新增快速校验hooks, 字典管理,系统参数管理

This commit is contained in:
xxm
2022-10-20 00:21:32 +08:00
parent 516d058176
commit 56edd85bd9
22 changed files with 1171 additions and 50 deletions

View File

@@ -46,7 +46,7 @@
},
// 默认展示几个
defaultItemCount: { type: Number, default: 2 },
// 所占栅格宽度
defaultItemMd: { type: Number, default: 6 },
// 禁用查询
disabledQuery: { type: Boolean, default: false },

View File

@@ -0,0 +1,13 @@
/**
* 字典项转换
*/
function dictConvert(dictCode: string, code) {}
/**
* 字典hooks
*/
export function useDict() {
return {
dictConvert,
}
}

View File

@@ -0,0 +1,19 @@
import { FormEditType } from '/@/enums/formTypeEnum'
import { unref } from "vue";
/**
* 服务器校验
*/
async function existsByServer(value, id, formEditType, existsFun, existsNotIdFun, errMsg = '该编码已存在!') {
if (!value) {
return Promise.resolve()
}
const res = unref(formEditType) === FormEditType.Edit ? await existsNotIdFun(value, id) : await existsFun(value)
return res.data ? Promise.reject(errMsg) : Promise.resolve()
}
export function useValidate() {
return {
existsByServer,
}
}

View File

@@ -2,14 +2,10 @@
<a-drawer title="代码生成参数配置" width="50%" :visible="visible" :destroyOnClose="true" :maskClosable="false" @close="handleCancel">
<a-form ref="formRef" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="功能模块名称" name="module">
<a-row>
<a-col :span="18">
<a-input v-model:value="form.module" />
</a-col>
<a-col :span="6">
<a-button style="width: 100%" @click="genParams">生成其他参数</a-button>
</a-col>
</a-row>
<a-input-group compact>
<a-input v-model:value="form.module" style="width: calc(100% - 115px)" />
<a-button type="primary" @click="genParams">生成其他参数</a-button>
</a-input-group>
</a-form-item>
<a-form-item label="基础包名称" name="basePack">
<a-input v-model:value="form.basePack" />

View File

@@ -1,11 +1,11 @@
<template>
<div>
<div class="m-3 p-3 pt-5 bg-white">
<b-query v-model="model.queryParam" :fields="fields" :default-item-md="8" @query="queryPage" @reset="resetQueryParams" />
<b-query :query-params="model.queryParam" :fields="fields" @query="queryPage" @reset="resetQueryParams" />
</div>
<div class="m-3 p-3 bg-white">
<vxe-toolbar ref="xToolbar" custom zoom :refresh="{ query: queryPage }" />
<vxe-table ref="xTable" row-id="id" :loading="loading" :data="pagination.records">
<vxe-table ref="xTable" row-id="id" :loading="loading" :data="pagination.records">
<vxe-column type="seq" title="序号" width="60" />
<vxe-column field="tableName" title="表名称" />
<vxe-column field="engine" title="引擎类型" />
@@ -44,9 +44,10 @@
const { handleTableChange, resetQueryParams, pageQueryResHandel, pagination, pages, model, loading } = useTablePage(queryPage)
// 查询条件
const fields = [
// { field: 'tableName', type: STRING, name: '名称', placeholder: '请输入表名称' },
// { field: 'tableComment', type: STRING, name: '描述', placeholder: '请输入表描述' },
{ field: 'tableName', type: STRING, name: '名称', placeholder: '请输入表名称' },
{ field: 'tableComment', type: STRING, name: '描述', placeholder: '请输入表描述' },
] as QueryField[]
let xTable = $ref<VxeTableInstance>()

View File

@@ -63,6 +63,7 @@
import { FormEditType } from '/@/enums/formTypeEnum'
import { findAll, LoginType } from '/@/views/modules/system/loginType/LoginType.api'
import { $ref } from 'vue/macros'
import { useValidate } from '/@/hooks/bootx/useValidate'
const {
initFormModel,
@@ -78,6 +79,8 @@
showable,
formEditType,
} = useFormEdit()
const { existsByServer } = useValidate()
const loginTypes = ref([] as Array<LoginType>)
const form = ref({
id: null,
@@ -97,15 +100,6 @@
name: [{ required: true, message: '请输入应用名称' }],
enable: [{ required: true, message: '请选择启用状态' }],
} as Record<string, Rule[]>)
// 校验编码重复
async function validateCode() {
const { code, id } = form.value
if (!code) {
return Promise.resolve()
}
const res = formEditType.value === FormEditType.Edit ? await existsByCodeNotId(code, id) : await existsByCode(code)
return res.data ? Promise.reject('该编码已存在!') : Promise.resolve()
}
const formRef: FormInstance = $ref()
// 表单
@@ -158,6 +152,12 @@
resetFields()
})
}
// 校验编码重复
async function validateCode() {
const { code, id } = form.value
return existsByServer(code, id, formEditType, existsByCode, existsByCodeNotId)
}
defineExpose({
init,
})

View File

@@ -0,0 +1,92 @@
import { defHttp } from '/@/utils/http/axios'
import { PageResult, Result } from '/#/axios'
import { BaseEntity } from '/#/web'
/**
* 分页
*/
export const page = (params) => {
return defHttp.get<Result<PageResult<Dict>>>({
url: '/dict/page',
params,
})
}
/**
* 获取单条
*/
export const get = (id) => {
return defHttp.get<Result<Dict>>({
url: '/dict/findById',
params: { id },
})
}
/**
* 添加
*/
export const add = (obj: Dict) => {
return defHttp.post({
url: '/dict/add',
data: obj,
})
}
/**
* 更新
*/
export const update = (obj: Dict) => {
return defHttp.post({
url: '/dict/update',
data: obj,
})
}
/**
* 删除
*/
export const del = (id) => {
return defHttp.delete({
url: '/dict/delete',
params: { id },
})
}
/**
* 查询全部
*/
export const findAll = () => {
return defHttp.get<Result<Array<Dict>>>({
url: '/dict/findAll',
})
}
/**
* 编码是否存在
*/
export function existsByCode(code) {
return defHttp.get<Result<boolean>>({
url: '/dict/existsByCode',
params: { code },
})
}
export function existsByCodeNotId(code, id) {
return defHttp.get<Result<boolean>>({
url: '/dict/existsByCodeNotId',
params: { code, id },
})
}
/**
* 字典
*/
export interface Dict extends BaseEntity {
// 编码
code: string
// 名称
name: string
// 分类标签
groupTag: string
// 备注
remark: string
}

View File

@@ -0,0 +1,131 @@
<template>
<basic-modal
v-bind="$attrs"
:loading="confirmLoading"
:width="modalWidth"
:title="title"
:visible="visible"
:mask-closable="showable"
@cancel="handleCancel"
>
<a-form class="small-from-item" ref="formRef" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="主键" :hidden="true">
<a-input v-model:value="form.id" :disabled="showable" />
</a-form-item>
<a-form-item label="编码" name="code">
<a-input v-model:value="form.code" :disabled="showable" placeholder="请输入编码" />
</a-form-item>
<a-form-item label="名称" name="name">
<a-input v-model:value="form.name" :disabled="showable" placeholder="请输入名称" />
</a-form-item>
<a-form-item label="分类标签" name="groupTag">
<a-input v-model:value="form.groupTag" :disabled="showable" placeholder="请输入分类标签" />
</a-form-item>
<a-form-item label="备注" name="remark">
<a-input v-model:value="form.remark" :disabled="showable" placeholder="请输入备注" />
</a-form-item>
</a-form>
<template #footer>
<a-space>
<a-button key="cancel" @click="handleCancel">取消</a-button>
<a-button v-if="!showable" key="forward" :loading="confirmLoading" type="primary" @click="handleOk">保存</a-button>
</a-space>
</template>
</basic-modal>
</template>
<script lang="ts" setup>
import { nextTick, reactive } from 'vue'
import { $ref } from 'vue/macros'
import useFormEdit from '/@/hooks/bootx/useFormEdit'
import { add, get, update, existsByCode, existsByCodeNotId, Dict } from './Dict.api'
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
import { FormEditType } from '/@/enums/formTypeEnum'
import { BasicModal } from '/@/components/Modal'
import { useValidate } from '/@/hooks/bootx/useValidate'
const {
initFormModel,
handleCancel,
search,
labelCol,
wrapperCol,
modalWidth,
title,
confirmLoading,
visible,
editable,
showable,
formEditType,
} = useFormEdit()
const { existsByServer } = useValidate()
// 表单
const formRef = $ref<FormInstance>()
let form = $ref({
id: null,
code: '',
name: '',
groupTag: '',
remark: '',
} as Dict)
// 校验
const rules = reactive({
code: [
{ required: true, message: '请输入字典编码', trigger: ['blur', 'change'] },
{ validator: validateCode, trigger: 'blur' },
],
name: [{ required: true, message: '请输入字典名称', trigger: ['blur', 'change'] }],
} as Record<string, Rule[]>)
// 事件
const emits = defineEmits(['ok'])
// 入口
function init(id, editType: FormEditType) {
initFormModel(id, editType)
resetForm()
getInfo(id, editType)
}
// 获取信息
function getInfo(id, editType: FormEditType) {
if ([FormEditType.Edit, FormEditType.Show].includes(editType)) {
confirmLoading.value = true
get(id).then(({ data }) => {
form = data
confirmLoading.value = false
})
} else {
confirmLoading.value = false
}
}
// 保存
function handleOk() {
formRef.validate().then(async () => {
confirmLoading.value = true
if (formEditType.value === FormEditType.Add) {
await add(form)
} else if (formEditType.value === FormEditType.Edit) {
await update(form)
}
confirmLoading.value = false
handleCancel()
emits('ok')
})
}
// 重置表单的校验
function resetForm() {
nextTick(() => {
formRef.resetFields()
})
}
// 校验编码重复
async function validateCode() {
const { code, id } = form
return existsByServer(code, id, formEditType, existsByCode, existsByCodeNotId)
}
defineExpose({
init,
})
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,96 @@
import { defHttp } from '/@/utils/http/axios'
import { PageResult, Result } from '/#/axios'
import { BaseEntity } from '/#/web'
/**
* 分页
*/
export const page = (params) => {
return defHttp.get<Result<PageResult<DictItem>>>({
url: '/dict/item/pageByDictionaryId',
params,
})
}
/**
* 获取单条
*/
export const get = (id) => {
return defHttp.get<Result<DictItem>>({
url: '/dict/item/findById',
params: { id },
})
}
/**
* 添加
*/
export const add = (obj: DictItem) => {
return defHttp.post({
url: '/dict/item/add',
data: obj,
})
}
/**
* 更新
*/
export const update = (obj: DictItem) => {
return defHttp.post({
url: '/dict/item/update',
data: obj,
})
}
/**
* 删除
*/
export const del = (id) => {
return defHttp.delete({
url: '/dict/item/delete',
params: { id },
})
}
/**
* 查询全部
*/
export const findAll = () => {
return defHttp.get<Result<Array<DictItem>>>({
url: '/dict/item/findAll',
})
}
/**
* 编码是否存在
*/
export function existsByCode(code) {
return defHttp.get<Result<boolean>>({
url: '/dict/item/existsByCode',
params: { code },
})
}
export function existsByCodeNotId(code, id) {
return defHttp.get<Result<boolean>>({
url: '/dict/item/existsByCodeNotId',
params: { code, id },
})
}
/**
* 字典项
*/
export interface DictItem extends BaseEntity {
// 字典id
dictId: number | null
// 字典code
dictCode: string | null
// 字典项code
code: string
// 字典项名称
name: string
// 排序
sortNo: number
// 备注
remark: string
}

View File

@@ -0,0 +1,139 @@
<template>
<basic-modal
v-bind="$attrs"
:loading="confirmLoading"
:width="modalWidth"
:title="title"
:visible="visible"
:mask-closable="showable"
@cancel="handleCancel"
>
<a-form class="small-from-item" ref="formRef" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="主键" :hidden="true">
<a-input v-model:value="form.id" :disabled="showable" />
</a-form-item>
<a-form-item label="字典编码" name="dictCode">
<a-input v-model:value="form.dictCode" disabled />
</a-form-item>
<a-form-item label="字典项编码" name="code">
<a-input v-model:value="form.code" :disabled="showable" placeholder="请输入字典项code" />
</a-form-item>
<a-form-item label="字典项名称" name="name">
<a-input v-model:value="form.name" :disabled="showable" placeholder="请输入字典项名称" />
</a-form-item>
<a-form-item label="排序" name="sortNo">
<a-input-number v-model:value="form.sortNo" :disabled="showable" placeholder="请输入排序" />
</a-form-item>
<a-form-item label="备注" name="remark">
<a-textarea v-model:value="form.remark" :disabled="showable" placeholder="请输入备注" />
</a-form-item>
</a-form>
<template #footer>
<a-space>
<a-button key="cancel" @click="handleCancel">取消</a-button>
<a-button v-if="!showable" key="forward" :loading="confirmLoading" type="primary" @click="handleOk">保存</a-button>
</a-space>
</template>
</basic-modal>
</template>
<script lang="ts" setup>
import { nextTick, reactive } from 'vue'
import { $ref } from 'vue/macros'
import useFormEdit from '/@/hooks/bootx/useFormEdit'
import { add, get, update, existsByCode, existsByCodeNotId, DictItem } from './DictItem.api'
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
import { FormEditType } from '/@/enums/formTypeEnum'
import { BasicModal } from '/@/components/Modal'
import { Dict } from '/@/views/modules/system/dict/Dict.api'
import { useValidate } from '/@/hooks/bootx/useValidate'
const {
initFormModel,
handleCancel,
search,
labelCol,
wrapperCol,
modalWidth,
title,
confirmLoading,
visible,
editable,
showable,
formEditType,
} = useFormEdit()
const { existsByServer } = useValidate()
// 表单
const formRef = $ref<FormInstance>()
let form = $ref({
id: null,
dictId: null,
dictCode: null,
code: '',
name: '',
sortNo: 0,
remark: '',
} as DictItem)
// 校验
const rules = reactive({
code: [
{ required: true, message: '请输入字典项编码', trigger: ['blur', 'change'] },
{ validator: validateCode, trigger: 'blur' },
],
name: [{ required: true, message: '请输入字典项名称', trigger: ['blur', 'change'] }],
} as Record<string, Rule[]>)
// 事件
const emits = defineEmits(['ok'])
// 入口
function init(id, editType: FormEditType, dict: Dict) {
initFormModel(id, editType)
resetForm()
form.dictId = dict.id as number
form.dictCode = dict.code
getInfo(id, editType)
}
// 获取信息
function getInfo(id, editType: FormEditType) {
if ([FormEditType.Edit, FormEditType.Show].includes(editType)) {
confirmLoading.value = true
get(id).then(({ data }) => {
form = data
confirmLoading.value = false
})
} else {
confirmLoading.value = false
}
}
// 保存
function handleOk() {
formRef.validate().then(async () => {
confirmLoading.value = true
if (formEditType.value === FormEditType.Add) {
await add(form)
} else if (formEditType.value === FormEditType.Edit) {
await update(form)
}
confirmLoading.value = false
handleCancel()
emits('ok')
})
}
// 校验编码重复
async function validateCode() {
const { code, id } = form
return existsByServer(code, id, formEditType, existsByCode, existsByCodeNotId)
}
// 重置表单的校验
function resetForm() {
nextTick(() => {
formRef.resetFields()
})
}
defineExpose({
init,
})
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,125 @@
<template>
<a-drawer
forceRender
title="字典列表"
:visible="visible"
:maskClosable="true"
width="60%"
placement="right"
:closable="true"
@close="visible = false"
>
<vxe-toolbar ref="xToolbar" custom :refresh="{ query: queryPage }">
<template #buttons>
<a-space>
<a-button type="primary" @click="add">新建</a-button>
</a-space>
</template>
</vxe-toolbar>
<vxe-table row-id="id" ref="xTable" :data="pagination.records" :loading="loading">
<vxe-column type="seq" width="60" />
<vxe-column field="code" title="字典项编码" />
<vxe-column field="name" title="字典项名称" />
<vxe-column field="sortNo" title="排序" />
<vxe-column field="remark" title="备注" />
<vxe-column field="createTime" title="创建时间" />
<vxe-column fixed="right" width="150" :showOverflow="false" title="操作">
<template #default="{ row }">
<span>
<a href="javascript:" @click="show(row)">查看</a>
</span>
<a-divider type="vertical" />
<span>
<a href="javascript:" @click="edit(row)">编辑</a>
</span>
<a-divider type="vertical" />
<a-popconfirm title="是否删除" @confirm="remove(row)" okText="是" cancelText="否">
<a href="javascript:" style="color: red">删除</a>
</a-popconfirm>
</template>
</vxe-column>
</vxe-table>
<vxe-pager
size="medium"
:loading="loading"
:current-page="pagination.current"
:page-size="pagination.size"
:total="pagination.total"
@page-change="handleTableChange"
/>
<dict-item-edit ref="dictItemEdit" @ok="queryPage" />
</a-drawer>
</template>
<script lang="ts" setup>
import { nextTick, onMounted, ref } from 'vue'
import { $ref } from 'vue/macros'
import { del, page } from './DictItem.api'
import useTablePage from '/@/hooks/bootx/useTablePage'
import DictItemEdit from './DictItemEdit.vue'
import { VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
import { FormEditType } from '/@/enums/formTypeEnum'
import { useMessage } from '/@/hooks/web/useMessage'
import { QueryField } from '/@/components/Bootx/Query/Query'
import { Dict } from '/@/views/modules/system/dict/Dict.api'
// 使用hooks
const { handleTableChange, pageQueryResHandel, resetQueryParams, pagination, pages, model, loading } = useTablePage(queryPage)
const { notification, createWarningModal, createMessage } = useMessage()
// 查询条件
const fields = [] as QueryField[]
let visible = $ref(false)
let dictInfo = $ref<Dict>()
const xTable = $ref<VxeTableInstance>()
const xToolbar = $ref<VxeToolbarInstance>()
const dictItemEdit = $ref<any>()
nextTick(() => {
xTable.connect(xToolbar)
})
function init(dict) {
visible = true
dictInfo = dict
queryPage()
}
// 分页查询
function queryPage() {
loading.value = true
page({
...model.queryParam,
...pages,
dictId: dictInfo.id,
}).then(({ data }) => {
pageQueryResHandel(data)
})
}
// 新增
function add() {
dictItemEdit.init(null, FormEditType.Add, dictInfo)
}
// 查看
function edit(record) {
dictItemEdit.init(record.id, FormEditType.Edit, dictInfo)
}
// 查看
function show(record) {
dictItemEdit.init(record.id, FormEditType.Show, dictInfo)
}
// 删除
function remove(record) {
del(record.id).then(() => {
createMessage.success('删除成功')
})
queryPage()
}
defineExpose({
init,
})
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,128 @@
<template>
<div>
<div class="m-3 p-3 pt-5 bg-white">
<b-query :query-params="model.queryParam" :fields="fields" @query="queryPage" @reset="resetQueryParams" />
</div>
<div class="m-3 p-3 bg-white">
<vxe-toolbar ref="xToolbar" custom :refresh="{ query: queryPage }">
<template #buttons>
<a-space>
<a-button type="primary" @click="add">新建</a-button>
</a-space>
</template>
</vxe-toolbar>
<vxe-table row-id="id" ref="xTable" :data="pagination.records" :loading="loading">
<vxe-column type="seq" width="60" />
<vxe-column field="code" title="编码" />
<vxe-column field="name" title="名称" />
<vxe-column field="groupTag" title="分类标签" />
<vxe-column field="remark" title="备注" />
<vxe-column field="createTime" title="创建时间" />
<vxe-column fixed="right" width="220" :showOverflow="false" title="操作">
<template #default="{ row }">
<span>
<a href="javascript:" @click="show(row)">查看</a>
</span>
<a-divider type="vertical" />
<span>
<a href="javascript:" @click="edit(row)">编辑</a>
</span>
<a-divider type="vertical" />
<span>
<a href="javascript:" @click="itemList(row)">字典配置</a>
</span>
<a-divider type="vertical" />
<a-popconfirm title="是否删除" @confirm="remove(row)" okText="是" cancelText="否">
<a href="javascript:" style="color: red">删除</a>
</a-popconfirm>
</template>
</vxe-column>
</vxe-table>
<vxe-pager
size="medium"
:loading="loading"
:current-page="pagination.current"
:page-size="pagination.size"
:total="pagination.total"
@page-change="handleTableChange"
/>
<dict-edit ref="dictEdit" @ok="queryPage" />
<dict-item-list ref="dictItemList" />
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { $ref } from 'vue/macros'
import { del, page } from './Dict.api'
import useTablePage from '/@/hooks/bootx/useTablePage'
import DictEdit from './DictEdit.vue'
import { VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
import BQuery from '/@/components/Bootx/Query/BQuery.vue'
import { FormEditType } from '/@/enums/formTypeEnum'
import { useMessage } from '/@/hooks/web/useMessage'
import { QueryField, STRING } from '/@/components/Bootx/Query/Query'
import DictItemList from './DictItemList.vue'
// 使用hooks
const { handleTableChange, pageQueryResHandel, resetQueryParams, pagination, pages, model, loading } = useTablePage(queryPage)
const { notification, createMessage } = useMessage()
// 查询条件
const fields = [
{ field: 'code', type: STRING, name: '字典编码', placeholder: '请输入字典编码' },
{ field: 'name', type: STRING, name: '字典名称', placeholder: '请输入字典名称' },
{ field: 'groupTag', type: STRING, name: '分组标签', placeholder: '请输入分组标签' },
] as QueryField[]
const xTable = $ref<VxeTableInstance>()
const xToolbar = $ref<VxeToolbarInstance>()
const dictEdit = $ref<any>()
const dictItemList = $ref<any>()
onMounted(() => {
vxeBind()
queryPage()
})
function vxeBind() {
xTable.connect(xToolbar)
}
// 分页查询
function queryPage() {
loading.value = true
page({
...model.queryParam,
...pages,
}).then(({ data }) => {
pageQueryResHandel(data)
})
}
// 新增
function add() {
dictEdit.init(null, FormEditType.Add)
}
// 查看
function edit(record) {
dictEdit.init(record.id, FormEditType.Edit)
}
// 查看
function show(record) {
dictEdit.init(record.id, FormEditType.Show)
}
// 明细列表查看
function itemList(record) {
dictItemList.init(record)
}
// 删除
function remove(record) {
del(record.id).then(() => {
createMessage.success('删除成功')
})
queryPage()
}
</script>
<style lang="less" scoped></style>

View File

@@ -75,6 +75,8 @@
import { FormEditType } from '/@/enums/formTypeEnum'
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
import { $ref } from 'vue/macros'
import { useValidate } from '/@/hooks/bootx/useValidate'
const { existsByServer } = useValidate()
const {
initFormModel,
@@ -112,11 +114,7 @@
// 校验编码重复
async function validateCode() {
const { code, id } = form.value
if (!code) {
return Promise.resolve()
}
const res = formEditType.value === FormEditType.Edit ? await existsByCodeNotId(code, id) : await existsByCode(code)
return res.data ? Promise.reject('该编码已存在!') : Promise.resolve()
return existsByServer(code, id, formEditType, existsByCode, existsByCodeNotId)
}
// 事件

View File

@@ -32,9 +32,11 @@
import { nextTick } from 'vue'
import { add, get, Resource, update } from './Menu.api'
import { BasicModal } from '/@/components/Modal/'
import { useValidate } from '/@/hooks/bootx/useValidate'
const { initFormModel, handleCancel, search, labelCol, wrapperCol, title, confirmLoading, visible, editable, showable, formEditType } =
useFormEdit()
const { existsByServer } = useValidate()
let form = $ref({
id: null,

View File

@@ -0,0 +1,95 @@
import { defHttp } from '/@/utils/http/axios'
import { PageResult, Result } from '/#/axios'
import { BaseEntity } from '/#/web'
/**
* 分页
*/
export const page = (params) => {
return defHttp.get<Result<PageResult<SystemParam>>>({
url: '/system/param/page',
params,
})
}
/**
* 获取单条
*/
export const get = (id) => {
return defHttp.get<Result<SystemParam>>({
url: '/system/param/findById',
params: { id },
})
}
/**
* 添加
*/
export const add = (obj: SystemParam) => {
return defHttp.post({
url: '/system/param/add',
data: obj,
})
}
/**
* 更新
*/
export const update = (obj: SystemParam) => {
return defHttp.post({
url: '/system/param/update',
data: obj,
})
}
/**
* 删除
*/
export const del = (id) => {
return defHttp.delete({
url: '/system/param/delete',
params: { id },
})
}
/**
* 查询全部
*/
export const findAll = () => {
return defHttp.get<Result<Array<SystemParam>>>({
url: '/system/param/findAll',
})
}
/**
* 编码是否被使用
*/
export const existsByKey = (key: string) => {
return defHttp.get<Result<boolean>>({
url: '/system/param/existsByKey',
params: { key },
})
}
export const existsByKeyNotId = (key: string, id) => {
return defHttp.get<Result<boolean>>({
url: '/system/param/existsByKeyNotId',
params: { key, id },
})
}
/**
* 系统参数配置
*/
export interface SystemParam extends BaseEntity {
// 参数名称
name: string
// 参数键名
paramKey: string
// 参数值
value: string
// 参数类型
type: number
// 内置参数
internal: boolean
// 备注
remark: string
}

View File

@@ -0,0 +1,147 @@
<template>
<basic-modal
v-bind="$attrs"
:loading="confirmLoading"
:width="modalWidth"
:title="title"
:visible="visible"
:mask-closable="showable"
@cancel="handleCancel"
>
<a-form class="small-from-item" ref="formRef" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
<a-form-item label="主键" :hidden="true">
<a-input v-model:value="form.id" :disabled="showable" />
</a-form-item>
<a-form-item label="参数名称" name="name">
<a-input v-model:value="form.name" :disabled="showable" placeholder="请输入参数名称" />
</a-form-item>
<a-form-item label="参数键名" name="paramKey">
<a-input v-model:value="form.paramKey" :disabled="showable" placeholder="请输入参数键名" />
</a-form-item>
<a-form-item label="参数值" name="value">
<a-input v-model:value="form.value" :disabled="showable" placeholder="请输入参数值" />
</a-form-item>
<a-form-item label="参数类型" name="type">
<a-select
allowClear
:options="paramTypeList"
style="width: 220px"
:disabled="showable"
v-model="form.type"
placeholder="请选择状态"
/>
</a-form-item>
<a-form-item label="备注" name="remark">
<a-textarea v-model:value="form.remark" :disabled="showable" placeholder="请输入备注" />
</a-form-item>
</a-form>
<template #footer>
<a-space>
<a-button key="cancel" @click="handleCancel">取消</a-button>
<a-button v-if="!showable" key="forward" :loading="confirmLoading" type="primary" @click="handleOk">保存</a-button>
</a-space>
</template>
</basic-modal>
</template>
<script lang="ts" setup>
import { nextTick, reactive } from 'vue'
import { $ref } from 'vue/macros'
import useFormEdit from '/@/hooks/bootx/useFormEdit'
import { add, get, update, existsByKey, existsByKeyNotId, SystemParam } from './SystemParam.api'
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
import { FormEditType } from '/@/enums/formTypeEnum'
import { BasicModal } from '/@/components/Modal'
import { useValidate } from '/@/hooks/bootx/useValidate'
const {
initFormModel,
handleCancel,
search,
labelCol,
wrapperCol,
modalWidth,
title,
confirmLoading,
visible,
editable,
showable,
formEditType,
} = useFormEdit()
const { existsByServer } = useValidate()
// 表单
const formRef = $ref<FormInstance>()
let form = $ref({
id: null,
name: '',
paramKey: '',
value: '',
type: 2,
internal: false,
remark: '',
} as SystemParam)
// 参数类型
let paramTypeList = $ref([])
// 校验
const rules = reactive({
name: [{ required: true, message: '参数名称必填', trigger: ['blur', 'change'] }],
paramKey: [
{ required: true, message: '参数键名必填', trigger: ['blur', 'change'] },
{ validator: validateKey, trigger: 'blur' },
],
value: [{ required: true, message: '参数内容必填', trigger: ['blur', 'change'] }],
type: [{ required: true, message: '参数类型必填', trigger: ['blur', 'change'] }],
} as Record<string, Rule[]>)
// 事件
const emits = defineEmits(['ok'])
// 入口
function init(id, editType: FormEditType) {
initFormModel(id, editType)
resetForm()
getInfo(id, editType)
}
// 获取信息
function getInfo(id, editType: FormEditType) {
if ([FormEditType.Edit, FormEditType.Show].includes(editType)) {
confirmLoading.value = true
get(id).then(({ data }) => {
form = data
confirmLoading.value = false
})
} else {
confirmLoading.value = false
}
}
// 保存
function handleOk() {
formRef.validate().then(async () => {
confirmLoading.value = true
if (formEditType.value === FormEditType.Add) {
await add(form)
} else if (formEditType.value === FormEditType.Edit) {
await update(form)
}
confirmLoading.value = false
handleCancel()
emits('ok')
})
}
// 重置表单的校验
function resetForm() {
nextTick(() => {
formRef.resetFields()
})
}
// 校验key值
async function validateKey() {
const { paramKey, id } = form
return existsByServer(paramKey, id, formEditType.value, existsByKey, existsByKeyNotId, '该Key已存在')
}
defineExpose({
init,
})
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,129 @@
<template>
<div>
<div class="m-3 p-3 pt-5 bg-white">
<b-query :query-params="model.queryParam" :fields="fields" @query="queryPage" @reset="resetQueryParams" />
</div>
<div class="m-3 p-3 bg-white">
<vxe-toolbar ref="xToolbar" custom :refresh="{ query: queryPage }">
<template #buttons>
<a-space>
<a-button type="primary" @click="add">新建</a-button>
</a-space>
</template>
</vxe-toolbar>
<vxe-table row-id="id" ref="xTable" :data="pagination.records" :loading="loading">
<vxe-column type="seq" width="60" />
<vxe-column field="name" title="参数名称" />
<vxe-column field="paramKey" title="参数键名" />
<vxe-column field="value" title="参数值" />
<vxe-column field="type" title="参数类型">
<template #default="{ row }">
<a-tag>{{ dictConvert('ParamType', row.type) }}</a-tag>
</template>
</vxe-column>
<vxe-column field="internal" title="内置参数">
<template #default="{ row }">
<a-tag v-if="row.internal" color="red"></a-tag>
<a-tag v-else color="green"></a-tag>
</template>
</vxe-column>
<vxe-column field="remark" title="备注" />
<vxe-column field="createTime" title="创建时间" />
<vxe-column fixed="right" width="150" :showOverflow="false" title="操作">
<template #default="{ row }">
<span>
<a href="javascript:" @click="show(row)">查看</a>
</span>
<a-divider type="vertical" />
<span>
<a href="javascript:" @click="edit(row)">编辑</a>
</span>
<a-divider type="vertical" />
<a-popconfirm title="是否删除" @confirm="remove(row)" okText="是" cancelText="否">
<a href="javascript:" style="color: red">删除</a>
</a-popconfirm>
</template>
</vxe-column>
</vxe-table>
<vxe-pager
size="medium"
:loading="loading"
:current-page="pagination.current"
:page-size="pagination.size"
:total="pagination.total"
@page-change="handleTableChange"
/>
<system-param-edit ref="systemParamEdit" @ok="queryPage" />
</div>
</div>
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue'
import { $ref } from 'vue/macros'
import { del, page } from './SystemParam.api'
import useTablePage from '/@/hooks/bootx/useTablePage'
import SystemParamEdit from './SystemParamEdit.vue'
import { VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
import BQuery from '/@/components/Bootx/Query/BQuery.vue'
import { FormEditType } from '/@/enums/formTypeEnum'
import { useMessage } from '/@/hooks/web/useMessage'
import { QueryField, STRING } from '/@/components/Bootx/Query/Query'
import { useDict } from '/@/hooks/bootx/useDict'
// 使用hooks
const { handleTableChange, pageQueryResHandel, resetQueryParams, pagination, pages, model, loading } = useTablePage(queryPage)
const { notification, createMessage } = useMessage()
const { dictConvert } = useDict()
// 查询条件
const fields = [
{ field: 'name', type: STRING, name: '参数名称', placeholder: '请输入字典名称' },
{ field: 'paramKey', type: STRING, name: '分组标签', placeholder: '请输入分组标签' },
] as QueryField[]
const xTable = $ref<VxeTableInstance>()
const xToolbar = $ref<VxeToolbarInstance>()
const systemParamEdit = $ref<any>()
onMounted(() => {
vxeBind()
queryPage()
})
function vxeBind() {
xTable.connect(xToolbar)
}
// 分页查询
function queryPage() {
loading.value = true
page({
...model.queryParam,
...pages,
}).then(({ data }) => {
pageQueryResHandel(data)
})
}
// 新增
function add() {
systemParamEdit.init(null, FormEditType.Add)
}
// 查看
function edit(record) {
systemParamEdit.init(record.id, FormEditType.Edit)
}
// 查看
function show(record) {
systemParamEdit.init(record.id, FormEditType.Show)
}
// 删除
function remove(record) {
del(record.id).then(() => {
createMessage.success('删除成功')
})
queryPage()
}
</script>
<style lang="less" scoped></style>

View File

@@ -76,14 +76,12 @@ export const existsByCodeNotId = (code: string, id) => {
export const existsByName = (name: string) => {
return defHttp.get<Result<boolean>>({
url: '/role/existsByName',
method: 'GET',
params: { name },
})
}
export const existsByNameNotId = (name: string, id) => {
return defHttp.get<Result<boolean>>({
url: '/role/existsByNameNotId',
method: 'GET',
params: { name, id },
})
}

View File

@@ -31,9 +31,12 @@
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
import { FormEditType } from '/@/enums/formTypeEnum'
import { BasicModal } from '/@/components/Modal'
import { useValidate } from '/@/hooks/bootx/useValidate'
const { initFormModel, handleCancel, search, labelCol, wrapperCol, title, confirmLoading, visible, editable, showable, formEditType } =
useFormEdit()
const { existsByServer } = useValidate()
// 表单
const formRef = $ref<FormInstance>()
let form = $ref({
@@ -94,19 +97,11 @@
}
async function validateCode() {
const { code, id } = form
if (!code) {
return Promise.resolve()
}
const res = formEditType.value === FormEditType.Edit ? await existsByCodeNotId(code, id) : await existsByCode(code)
return res.data ? Promise.reject('该编码已存在!') : Promise.resolve()
return existsByServer(code, id, formEditType.value, existsByCode, existsByCodeNotId)
}
async function validateName() {
const { name, id } = form
if (!name) {
return Promise.resolve()
}
const res = formEditType.value === FormEditType.Edit ? await existsByNameNotId(name, id) : await existsByName(name)
return res.data ? Promise.reject('该编码已存在!') : Promise.resolve()
return existsByServer(name, id, formEditType.value, existsByName, existsByNameNotId)
}
defineExpose({
init,

View File

@@ -17,7 +17,7 @@
<vxe-column field="name" title="名称" />
<vxe-column field="remark" title="说明" />
<vxe-column field="createTime" title="创建时间" />
<vxe-column fixed="right" width="150" :showOverflow="false" title="操作">
<vxe-column fixed="right" width="210" :showOverflow="false" title="操作">
<template #default="{ row }">
<span>
<a href="javascript:" @click="show(row)">查看</a>
@@ -30,6 +30,20 @@
<a-popconfirm title="是否删除" @confirm="remove(row)" okText="是" cancelText="否">
<a href="javascript:" style="color: red">删除</a>
</a-popconfirm>
<a-divider type="vertical" />
<a-dropdown>
<a class="ant-dropdown-link"> 授权 <Icon icon="ant-design:down-outlined" :size="12" /> </a>
<template #overlay>
<a-menu>
<a-menu-item>
<a href="javascript:" @click="handleRoleMenu(row)">菜单授权</a>
</a-menu-item>
<a-menu-item>
<a href="javascript:" @click="handleRolePath(row)">请求授权</a>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
</vxe-column>
</vxe-table>
@@ -57,9 +71,12 @@
import { useMessage } from '/@/hooks/web/useMessage'
import { $ref } from 'vue/macros'
import { QueryField, STRING } from '/@/components/Bootx/Query/Query'
import Icon from '/@/components/Icon/src/Icon.vue'
// 使用hooks
const { handleTableChange, pageQueryResHandel, resetQueryParams, pagination, pages, model, loading } = useTablePage(queryPage)
const { notification } = useMessage()
const roleEdit = ref()
// 查询条件
const fields = [
@@ -99,9 +116,11 @@
function show(record) {
roleEdit.value.init(record.id, FormEditType.Show)
}
// 菜单授权处理
function handleRoleMenu(record) {}
// 请求授权处理
function handleRolePath(record) {}
// 删除
const { notification } = useMessage()
function remove(record) {
del(record.id).then(() => {
notification.success({ message: '删除成功' })

View File

@@ -46,12 +46,12 @@
import { nextTick, reactive } from 'vue'
import { $ref } from 'vue/macros'
import useFormEdit from '/@/hooks/bootx/useFormEdit'
import { add, get, update, DataScope } from './DataScope.api'
import { add, get, update, existsByCode, existsByCodeNotId, existsByName, existsByNameNotId, DataScope } from './DataScope.api'
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
import { FormEditType } from '/@/enums/formTypeEnum'
import { BasicModal } from '/@/components/Modal'
import { STRING } from '/@/components/Bootx/Query/Query'
import { existsByCode, existsByCodeNotId, existsByName, existsByNameNotId } from '/@/views/modules/system/role/Role.api'
import { useValidate } from '/@/hooks/bootx/useValidate'
const {
initFormModel,
@@ -68,6 +68,7 @@
showable,
formEditType,
} = useFormEdit()
const { existsByServer } = useValidate()
// 表单
const formRef = $ref<FormInstance>()
let form = $ref({
@@ -132,6 +133,7 @@
}
async function validateCode() {
const { code, id } = form
return existsByServer(code, id, formEditType.value, existsByCode, existsByCodeNotId)
if (!code) {
return Promise.resolve()
}
@@ -140,11 +142,7 @@
}
async function validateName() {
const { name, id } = form
if (!name) {
return Promise.resolve()
}
const res = formEditType.value === FormEditType.Edit ? await existsByNameNotId(name, id) : await existsByName(name)
return res.data ? Promise.reject('该编码已存在!') : Promise.resolve()
return existsByServer(name, id, formEditType.value, existsByName, existsByNameNotId)
}
defineExpose({
init,

View File

@@ -1,7 +1,7 @@
<template>
<div>
<div class="m-3 p-3 pt-5 bg-white">
<b-query :query-params="model.queryParam" :fields="fields" @query="queryPage" @reset="resetQueryParams" />
<b-query :query-params="model.queryParam" :default-item-md="8" :fields="fields" @query="queryPage" @reset="resetQueryParams" />
</div>
<div class="m-3 p-3 bg-white">
<vxe-toolbar ref="xToolbar" custom :refresh="{ query: queryPage }">