配置管理
This commit is contained in:
parent
c5aeb378d4
commit
2f7dd027c1
@ -10,13 +10,6 @@ export function getConfigList(params?) {
|
||||
params,
|
||||
});
|
||||
}
|
||||
export function getConfigAllList(params?) {
|
||||
return http.request({
|
||||
url: '/config/list',
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 根据ID获取详情
|
||||
*/
|
||||
@ -26,6 +19,15 @@ export function getConfigDetail(id) {
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 刷新缓存
|
||||
*/
|
||||
export function refreshCache() {
|
||||
return http.request({
|
||||
url: '/config/refreshCache',
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 添加配置
|
||||
*/
|
||||
@ -64,4 +66,63 @@ export function configBatchDelete(data:any) {
|
||||
method: 'DELETE',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: 配置项列表
|
||||
*/
|
||||
export function getConfigItemList(params?) {
|
||||
return http.request({
|
||||
url: '/config/item/page',
|
||||
method: 'GET',
|
||||
params,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 根据ID获取详情
|
||||
*/
|
||||
export function getConfigItemDetail(id) {
|
||||
return http.request({
|
||||
url: '/config/item/detail/'+id,
|
||||
method: 'get',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 添加配置项
|
||||
*/
|
||||
export function configItemAdd(data:any) {
|
||||
return http.request({
|
||||
url: '/config/item/add',
|
||||
method: 'POST',
|
||||
data,
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 更新配置项
|
||||
*/
|
||||
export function configItemUpdate(data:any) {
|
||||
return http.request({
|
||||
url: '/config/item/update',
|
||||
method: 'PUT',
|
||||
data
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 删除配置项
|
||||
*/
|
||||
export function configItemDelete(id) {
|
||||
return http.request({
|
||||
url: '/config/item/delete/'+id,
|
||||
method: 'DELETE',
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @description: 批量删除配置项
|
||||
*/
|
||||
export function configItemBatchDelete(data:any) {
|
||||
return http.request({
|
||||
url: '/config/item/batchDelete',
|
||||
method: 'DELETE',
|
||||
data
|
||||
});
|
||||
}
|
@ -312,6 +312,7 @@
|
||||
size: unref(getTableSize),
|
||||
stripe: unref(getStriped),
|
||||
'max-height': getDeviceHeight.value,
|
||||
height:getDeviceHeight.value,
|
||||
};
|
||||
});
|
||||
|
||||
|
206
src/utils/validate.ts
Normal file
206
src/utils/validate.ts
Normal file
@ -0,0 +1,206 @@
|
||||
/**
|
||||
* 判断是否为空
|
||||
* @param val 数据
|
||||
*/
|
||||
export const validateNull = (val: any) => {
|
||||
if (typeof val === 'boolean') {
|
||||
return false;
|
||||
}
|
||||
if (typeof val === 'number') {
|
||||
return false;
|
||||
}
|
||||
if (val instanceof Array) {
|
||||
if (val.length === 0) return true;
|
||||
} else if (val instanceof Object) {
|
||||
if (JSON.stringify(val) === '{}') return true;
|
||||
} else {
|
||||
if (val === 'null' || val == null || val === 'undefined' || val === undefined || val === '') return true;
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const rule = {
|
||||
/**
|
||||
* 校验 请输入中文、英文、数字包括下划线
|
||||
* 名称校验
|
||||
*/
|
||||
validatorNameCn(rule: any, value: any, callback: any) {
|
||||
const acount = /^[\u4E00-\u9FA5A-Za-z0-9_]+$/;
|
||||
if (value && !acount.test(value)) {
|
||||
callback(new Error('请输入中文、英文、数字包括下划线'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 校验 请输入大写英文、下划线
|
||||
* 名称校验
|
||||
*/
|
||||
validatorCapital(rule: any, value: any, callback: any) {
|
||||
const acount = /^[A-Z_]+$/;
|
||||
if (value && !acount.test(value)) {
|
||||
callback(new Error('请输入大写英文、下划线'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 校验 请输入小写英文、下划线
|
||||
* 名称校验
|
||||
*/
|
||||
validatorLowercase(rule: any, value: any, callback: any) {
|
||||
const acount = /^[a-z_]+$/;
|
||||
if (value && !acount.test(value)) {
|
||||
callback(new Error('请输入小写英文、下划线'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 校验 请输入小写英文
|
||||
* 名称校验
|
||||
*/
|
||||
validatorLower(rule: any, value: any, callback: any) {
|
||||
const acount = /^[a-z]+$/;
|
||||
if (value && !acount.test(value)) {
|
||||
callback(new Error('请输入小写英文'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 校验首尾空白字符的正则表达式
|
||||
*
|
||||
*/
|
||||
checkSpace(rule: any, value: any, callback: any) {
|
||||
const longrg = /[^\s]+$/;
|
||||
if (!longrg.test(value)) {
|
||||
callback(new Error('请输入非空格信息'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 校验手机号
|
||||
*/
|
||||
validatePhone(rule: any, value: any, callback: any) {
|
||||
var isPhone = /^1(3\d|4[5-9]|5[0-35-9]|6[2567]|7[0-8]|8\d|9[0-35-9])\d{8}$/;
|
||||
|
||||
if (value.indexOf('****') >= 0) {
|
||||
return callback();
|
||||
}
|
||||
|
||||
if (!isPhone.test(value)) {
|
||||
callback(new Error('请输入合法手机号'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
|
||||
/* 数字 */
|
||||
number(rule, value, callback) {
|
||||
validateFn('number', rule, value, callback, '包含非数字字符');
|
||||
},
|
||||
|
||||
/* 字母 */
|
||||
letter(rule, value, callback) {
|
||||
validateFn('letter', rule, value, callback, '包含非字母字符');
|
||||
},
|
||||
|
||||
/* 字母和数字 */
|
||||
letterAndNumber(rule, value, callback) {
|
||||
validateFn('letterAndNumber', rule, value, callback, '只能输入字母或数字');
|
||||
},
|
||||
|
||||
/* 手机号码 */
|
||||
mobilePhone(rule, value, callback) {
|
||||
validateFn('mobilePhone', rule, value, callback, '手机号码格式有误');
|
||||
},
|
||||
|
||||
/* 字母开头,仅可包含数字 */
|
||||
letterStartNumberIncluded(rule, value, callback) {
|
||||
validateFn('letterStartNumberIncluded', rule, value, callback, '必须以字母开头,可包含数字');
|
||||
},
|
||||
|
||||
/* 禁止中文输入 */
|
||||
noChinese(rule, value, callback) {
|
||||
validateFn('noChinese', rule, value, callback, '不可输入中文字符');
|
||||
},
|
||||
|
||||
/* 必须中文输入 */
|
||||
chinese(rule, value, callback) {
|
||||
validateFn('chinese', rule, value, callback, '只能输入中文字符');
|
||||
},
|
||||
|
||||
/* 电子邮箱 */
|
||||
email(rule, value, callback) {
|
||||
validateFn('email', rule, value, callback, '邮箱格式有误');
|
||||
},
|
||||
|
||||
/* URL网址 */
|
||||
url(rule, value, callback) {
|
||||
validateFn('url', rule, value, callback, 'URL格式有误');
|
||||
},
|
||||
|
||||
regExp(rule, value, callback) {
|
||||
if (validateNull(value) || value.length <= 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
const pattern = new RegExp(rule.regExp);
|
||||
|
||||
if (!pattern.test(value)) {
|
||||
const errTxt = rule.errorMsg || 'invalid value';
|
||||
callback(new Error(errTxt));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc [自定义校验规则]
|
||||
* @example
|
||||
* import { validateRule } from "@/utils/validateRules";
|
||||
* rules: [
|
||||
* { validator: validateRule.emailValue, trigger: 'blur'}
|
||||
* ]
|
||||
*/
|
||||
|
||||
export const getRegExp = function (validatorName) {
|
||||
const commonRegExp = {
|
||||
number: '^[-]?\\d+(\\.\\d+)?$',
|
||||
letter: '^[A-Za-z]+$',
|
||||
letterAndNumber: '^[A-Za-z0-9]+$',
|
||||
mobilePhone: '^[1][3-9][0-9]{9}$',
|
||||
letterStartNumberIncluded: '^[A-Za-z]+[A-Za-z\\d]*$',
|
||||
noChinese: '^[^\u4e00-\u9fa5]+$',
|
||||
chinese: '^[\u4e00-\u9fa5]+$',
|
||||
email: '^([-_A-Za-z0-9.]+)@([_A-Za-z0-9]+\\.)+[A-Za-z0-9]{2,3}$',
|
||||
url: '(https?|ftp|file)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]'
|
||||
};
|
||||
return commonRegExp[validatorName];
|
||||
};
|
||||
|
||||
const validateFn = (validatorName, rule, value, callback, defaultErrorMsg) => {
|
||||
if (validateNull(value) || value.length <= 0) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
const reg = new RegExp(getRegExp(validatorName));
|
||||
|
||||
if (!reg.test(value)) {
|
||||
const errTxt = rule.errorMsg || defaultErrorMsg;
|
||||
callback(new Error(errTxt));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
@ -12,13 +12,5 @@ export const columns = [
|
||||
{
|
||||
label: '排序',
|
||||
prop: 'sort',
|
||||
},
|
||||
{
|
||||
label: '创建人',
|
||||
prop: 'createUser',
|
||||
},
|
||||
{
|
||||
label: '创建时间',
|
||||
prop: 'createTime',
|
||||
},
|
||||
}
|
||||
];
|
||||
|
99
src/views/data/config/columnsItem.ts
Normal file
99
src/views/data/config/columnsItem.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import { h } from 'vue';
|
||||
import { ElTag } from 'element-plus';
|
||||
export const columns = [
|
||||
{
|
||||
type: 'selection',
|
||||
},
|
||||
{
|
||||
label: '配置项名称',
|
||||
prop: 'name',
|
||||
},
|
||||
{
|
||||
label: '配置项编码',
|
||||
prop: 'code',
|
||||
},
|
||||
{
|
||||
label: '配置项值',
|
||||
prop: 'value',
|
||||
},
|
||||
{
|
||||
label: '配置项类型',
|
||||
prop: 'type',
|
||||
render(record) {
|
||||
let typeText = ''
|
||||
switch (record.row.type) {
|
||||
case 'hidden':
|
||||
typeText='隐藏'
|
||||
break;
|
||||
case 'readonly':
|
||||
typeText='只读文本'
|
||||
break;
|
||||
case 'number':
|
||||
typeText='数字'
|
||||
break;
|
||||
case 'text':
|
||||
typeText='单行文本'
|
||||
break;
|
||||
case 'textarea':
|
||||
typeText='多行文本'
|
||||
break;
|
||||
case 'password':
|
||||
typeText='密码'
|
||||
break;
|
||||
case 'radio':
|
||||
typeText='单选框'
|
||||
break;
|
||||
case 'checkbox':
|
||||
typeText='复选框'
|
||||
break;
|
||||
case 'select':
|
||||
typeText='下拉框(单选)'
|
||||
break;
|
||||
case 'selects':
|
||||
typeText='下拉框(多选)'
|
||||
break;
|
||||
case 'icon':
|
||||
typeText='字体图标'
|
||||
break;
|
||||
case 'date':
|
||||
typeText='日期'
|
||||
break;
|
||||
case 'datetime':
|
||||
typeText='时间'
|
||||
break;
|
||||
case 'image':
|
||||
typeText='单张图片'
|
||||
break;
|
||||
case 'images':
|
||||
typeText='多张图片'
|
||||
break;
|
||||
case 'file':
|
||||
typeText='单个文件'
|
||||
case 'files':
|
||||
typeText='多个文件'
|
||||
break;
|
||||
case 'ueditor':
|
||||
typeText='富文本编辑器'
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return h('span', typeText || '-');
|
||||
},
|
||||
},
|
||||
{
|
||||
label: '配置项状态',
|
||||
prop: 'status',
|
||||
render(record) {
|
||||
return h(
|
||||
ElTag,
|
||||
{
|
||||
type: record.row.status ==1 ? 'success' : 'danger',
|
||||
},
|
||||
{
|
||||
default: () => (record.row.status ==1 ? '正常' : '停用'),
|
||||
},
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
127
src/views/data/config/configItem.vue
Normal file
127
src/views/data/config/configItem.vue
Normal file
@ -0,0 +1,127 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<BasicTable :columns="columns" :request="loadDataTable" :row-key="(row) => row.id" ref="tableRef"
|
||||
:actionColumn="actionColumn" @selection-change="onSelectionChange">
|
||||
<template #tableTitle>
|
||||
<el-space>
|
||||
<el-input type="text" v-model="params.name" placeholder="请输入配置项名称">
|
||||
<template #prefix>
|
||||
<el-icon class="el-input__icon">
|
||||
<SearchOutlined />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-button type="primary" @click="reloadTable"> 查询 </el-button>
|
||||
<el-button type="primary" @click="handleAdd">新建</el-button>
|
||||
<el-button type="danger" :disabled="!selectionData.length"@click="handleDelete()">删除</el-button>
|
||||
</el-space>
|
||||
</template>
|
||||
</BasicTable>
|
||||
<editDialog v-if="editVisible" :configId="configId" :configItemId="configItemId" v-model:visible="editVisible" @success="reloadTable">
|
||||
</editDialog>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, h, nextTick, watch, defineAsyncComponent } from 'vue';
|
||||
import { SearchOutlined } from '@vicons/antd';
|
||||
import { TableAction } from '@/components/Table';
|
||||
import { getConfigItemList, configItemDelete, configItemBatchDelete } from '@/api/data/config';
|
||||
import { columns } from './columnsItem';
|
||||
import { message, confirm } from "@/utils/auth";
|
||||
const editDialog = defineAsyncComponent(() =>
|
||||
import('./editItem.vue')
|
||||
)
|
||||
const tableRef = ref();
|
||||
const editVisible = ref(false)
|
||||
const selectionData = ref([])
|
||||
const configItemId = ref(0)
|
||||
const params = ref({
|
||||
name: '',
|
||||
});
|
||||
const props = defineProps({
|
||||
configId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
watch(
|
||||
() => props.configId,
|
||||
async (value) => {
|
||||
if(value){
|
||||
await nextTick()
|
||||
reloadTable()
|
||||
}
|
||||
}
|
||||
)
|
||||
const actionColumn = reactive({
|
||||
lable: 150,
|
||||
title: '操作',
|
||||
prop: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'text',
|
||||
actions: [
|
||||
{
|
||||
label: '编辑',
|
||||
type: 'warning',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'danger',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
}
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
//刷新字典项值列表
|
||||
function reloadTable() {
|
||||
tableRef.value.reload({ pageNo: 1 });
|
||||
}
|
||||
|
||||
//加载字典项值列表
|
||||
const loadDataTable = async (res) => {
|
||||
const result = await getConfigItemList({ ...params.value, configId:props.configId, ...res });
|
||||
return result;
|
||||
};
|
||||
//新建字典
|
||||
const handleAdd = async () => {
|
||||
configItemId.value=0
|
||||
await nextTick();
|
||||
editVisible.value=true
|
||||
};
|
||||
//编辑字典
|
||||
const handleEdit = async (record: Recordable) => {
|
||||
configItemId.value=record.row.id
|
||||
await nextTick();
|
||||
editVisible.value=true
|
||||
};
|
||||
//删除字典项
|
||||
async function handleDelete(record: Recordable) {
|
||||
let ids = []
|
||||
if (!record) {
|
||||
ids = selectionData.value.map(({ id }) => id);
|
||||
}
|
||||
await confirm('确定要删除?');
|
||||
record ? await configItemDelete(record.row.id) : await configItemBatchDelete(ids);
|
||||
message("删除成功");
|
||||
reloadTable()
|
||||
}
|
||||
|
||||
function onSelectionChange(value) {
|
||||
selectionData.value = value
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
233
src/views/data/config/editItem.vue
Normal file
233
src/views/data/config/editItem.vue
Normal file
@ -0,0 +1,233 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="props.visible"
|
||||
:title="props.configItemId?'编辑配置项':'新增配置项'"
|
||||
width="500"
|
||||
:close-on-click-modal="false"
|
||||
:before-close="dialogClose"
|
||||
>
|
||||
<el-form
|
||||
class="ls-form"
|
||||
ref="formRef"
|
||||
:model="formData"
|
||||
label-width="100px"
|
||||
>
|
||||
<el-form-item
|
||||
label="配置项名称"
|
||||
prop="name"
|
||||
:rules="{ required: true, message: '请输入配置项名称', trigger: 'blur' }"
|
||||
>
|
||||
<el-input
|
||||
class="ls-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入配置项名称"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="配置项编码"
|
||||
prop="code"
|
||||
:rules="{ required: true, message: '请输入配置项编码', trigger: 'blur' }"
|
||||
>
|
||||
<el-input
|
||||
class="ls-input"
|
||||
v-model="formData.code"
|
||||
placeholder="请输入配置项编码"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="配置项值"
|
||||
prop="value"
|
||||
>
|
||||
<el-input
|
||||
class="ls-input"
|
||||
v-model="formData.value"
|
||||
placeholder="请输入配置项值"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="配置项类型" prop="type" class="flex-1" :rules="{ required: true, message: '请选择配置项类型', trigger: 'change' }">
|
||||
<el-select v-model="formData.type" class="flex-1" clearable placeholder="请选择配置项类型">
|
||||
<el-option v-for="(item, index) in typeList" :key="index" :label="item.name" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
label="配置项源"
|
||||
prop="options"
|
||||
>
|
||||
<el-input
|
||||
class="ls-input"
|
||||
v-model="formData.options"
|
||||
placeholder="请输入配置项数据源"
|
||||
clearable
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="排序" prop="sort">
|
||||
<el-input-number v-model="formData.sort"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="配置项状态" prop="status">
|
||||
<el-radio-group v-model="formData.status" name="status">
|
||||
<el-radio :value="1">正常</el-radio>
|
||||
<el-radio :value="2">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="note">
|
||||
<el-input v-model="formData.note" type="textarea" placeholder="请输入备注" clearable />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="dialogClose">取消</el-button>
|
||||
<el-button :loading="subLoading" type="primary" @click="submit">
|
||||
确定
|
||||
</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import type {FormInstance} from "element-plus";
|
||||
import {getConfigItemDetail,configItemAdd,configItemUpdate} from "@/api/data/config";
|
||||
import {onMounted, ref,reactive, shallowRef} from "vue";
|
||||
import {message} from "@/utils/auth";
|
||||
import {useLockFn} from "@/utils/useLockFn";
|
||||
|
||||
const emit = defineEmits(["success", "update:visible"]);
|
||||
const formRef = shallowRef<FormInstance>();
|
||||
const formData = reactive({
|
||||
id: "",
|
||||
name: "",
|
||||
code:"",
|
||||
value: "",
|
||||
sort: 0,
|
||||
options:'',
|
||||
type:'',
|
||||
status:1,
|
||||
note:''
|
||||
});
|
||||
const typeList = ref([
|
||||
{
|
||||
name:'隐藏',
|
||||
value:'hidden'
|
||||
},
|
||||
{
|
||||
name:'只读文本',
|
||||
value:'readonly'
|
||||
},
|
||||
{
|
||||
name:'数字',
|
||||
value:'number'
|
||||
},
|
||||
{
|
||||
name:'单行文本',
|
||||
value:'text'
|
||||
},
|
||||
{
|
||||
name:'多行文本',
|
||||
value:'textarea'
|
||||
},
|
||||
{
|
||||
name:'密码',
|
||||
value:'password'
|
||||
},
|
||||
{
|
||||
name:'单选框',
|
||||
value:'radio'
|
||||
},
|
||||
{
|
||||
name:'复选框',
|
||||
value:'checkbox'
|
||||
},
|
||||
{
|
||||
name:'下拉框(单选)',
|
||||
value:'select'
|
||||
},
|
||||
{
|
||||
name:'下拉框(多选)',
|
||||
value:'selects'
|
||||
},
|
||||
{
|
||||
name:'字体图标',
|
||||
value:'icon'
|
||||
},
|
||||
{
|
||||
name:'日期',
|
||||
value:'date'
|
||||
},
|
||||
{
|
||||
name:'时间',
|
||||
value:'datetime'
|
||||
},
|
||||
{
|
||||
name:'单张图片',
|
||||
value:'image'
|
||||
},
|
||||
{
|
||||
name:'多张图片',
|
||||
value:'images'
|
||||
},
|
||||
{
|
||||
name:'单个文件',
|
||||
value:'file'
|
||||
},
|
||||
{
|
||||
name:'多个文件',
|
||||
value:'files'
|
||||
},
|
||||
{
|
||||
name:'富文本编辑器',
|
||||
value:'ueditor'
|
||||
},
|
||||
])
|
||||
|
||||
const props = defineProps({
|
||||
visible: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false
|
||||
},
|
||||
configId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
},
|
||||
configItemId: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await formRef.value?.validate();
|
||||
props.configItemId ? await configItemUpdate({...formData,configId:props.configId}) : await configItemAdd({...formData,configId:props.configId});
|
||||
message("操作成功");
|
||||
emit("update:visible", false);
|
||||
emit("success");
|
||||
};
|
||||
|
||||
const dialogClose = () => {
|
||||
emit("update:visible", false);
|
||||
};
|
||||
|
||||
const { isLock:subLoading,lockFn: submit } = useLockFn(handleSubmit);
|
||||
|
||||
|
||||
const setFormData = async () => {
|
||||
const data = await getConfigItemDetail(props.configItemId);
|
||||
for (const key in formData) {
|
||||
if (data[key] != null && data[key] != undefined) {
|
||||
//@ts-ignore
|
||||
formData[key] = data[key];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (props.configItemId) {
|
||||
setFormData();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
@ -1,157 +1,142 @@
|
||||
<template>
|
||||
<PageWrapper>
|
||||
<el-card :bordered="false" class="pt-3 mb-3 proCard">
|
||||
<BasicForm @register="register" @submit="handleSubmit" @reset="handleReset"></BasicForm>
|
||||
</el-card>
|
||||
<el-card :bordered="false" class="proCard">
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="tableRef"
|
||||
:actionColumn="actionColumn"
|
||||
@selection-change="onSelectionChange"
|
||||
>
|
||||
<template #tableTitle>
|
||||
<el-button type="primary" @click="handleAdd">
|
||||
<template #icon>
|
||||
<el-icon class="el-input__icon">
|
||||
<PlusOutlined />
|
||||
</el-icon>
|
||||
</template>
|
||||
添加配置
|
||||
</el-button>
|
||||
<el-button type="danger" @click="handleDelete()" :disabled="!selectionData.length">
|
||||
<template #icon>
|
||||
<el-icon class="el-input__icon">
|
||||
<Delete />
|
||||
</el-icon>
|
||||
</template>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
</BasicTable>
|
||||
</el-card>
|
||||
|
||||
<editDialog
|
||||
v-if="editVisible"
|
||||
:configId="configId"
|
||||
v-model:visible="editVisible"
|
||||
@success="reloadTable"
|
||||
>
|
||||
<el-row :gutter="10" class="mt-3">
|
||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="8" class="mb-4">
|
||||
<el-card shadow="hover" class="border-0">
|
||||
<template #header>
|
||||
<el-row>
|
||||
<el-col :span="20">
|
||||
<el-input type="text" v-model="params.name" clearable placeholder="请输入配置名称">
|
||||
<template #prefix>
|
||||
<el-icon class="el-input__icon">
|
||||
<SearchOutlined />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="4" style="text-align: right;">
|
||||
<el-button type="primary" @click="reloadTable"> 查询 </el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div style="margin-top:15px;">
|
||||
<el-button type="primary" @click="addConfig">新建</el-button>
|
||||
<el-button type="danger" :disabled="!selectionData.length" @click="handleDelete()">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<BasicTable :columns="columns" :showTableSetting="false" :request="loadDataTable" :row-key="(row) => row.id"
|
||||
ref="tableRef" :actionColumn="actionColumn" @selection-change="onSelectionChange" highlight-current-row
|
||||
@row-click="onCheckedRow" />
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="16" class="mb-4">
|
||||
<el-card shadow="hover" class="mb-4 border-0 proCard">
|
||||
<configItem :configId="configId" v-if="configItemShow"></configItem>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<editDialog v-if="editVisible" :configId="configId" v-model:visible="editVisible" @success="reloadTable">
|
||||
</editDialog>
|
||||
</PageWrapper>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, ref, h,nextTick,defineAsyncComponent } from 'vue';
|
||||
import { ColProps } from 'element-plus';
|
||||
import { schemas } from './querySchemas';
|
||||
import { useForm } from '@/components/Form/index';
|
||||
import { TableAction } from '@/components/Table';
|
||||
import { getConfigList,configDelete,configBatchDelete } from '@/api/data/config';
|
||||
import { columns } from './columns';
|
||||
import { PlusOutlined } from '@vicons/antd';
|
||||
import {message,confirm} from "@/utils/auth";
|
||||
const editDialog = defineAsyncComponent(() =>
|
||||
import('./edit.vue')
|
||||
import { ref, reactive, h, nextTick, defineAsyncComponent } from 'vue';
|
||||
import { SearchOutlined } from '@vicons/antd';
|
||||
import { TableAction } from '@/components/Table';
|
||||
import { getConfigList, configDelete, configBatchDelete } from '@/api/data/config';
|
||||
import { columns } from './columns';
|
||||
import configItem from './configItem.vue';
|
||||
import { message, confirm } from "@/utils/auth";
|
||||
const editDialog = defineAsyncComponent(() =>
|
||||
import('./edit.vue')
|
||||
)
|
||||
const configId =ref(0)
|
||||
const editVisible=ref(false)
|
||||
const selectionData = ref([])
|
||||
const tableRef = ref();
|
||||
const formParams = reactive({
|
||||
name:'',
|
||||
status:'',
|
||||
type:''
|
||||
});
|
||||
const actionColumn = reactive({
|
||||
width: 250,
|
||||
label: '操作',
|
||||
prop: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction, {
|
||||
style: 'button',
|
||||
actions: [
|
||||
{
|
||||
label: '编辑',
|
||||
type: 'warning',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
// auth: ['basic_list'],
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'danger',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
// 根据业务控制是否显示 isShow 和 auth 是并且关系
|
||||
ifShow: () => {
|
||||
return true;
|
||||
},
|
||||
// 根据权限控制是否显示: 有权限,会显示,支持多个
|
||||
// auth: ['basic_list'],
|
||||
},
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
const configId = ref(0)
|
||||
const configItemShow = ref(false)
|
||||
const tableRef = ref();
|
||||
const editVisible = ref(false)
|
||||
const selectionData = ref([])
|
||||
const params = ref({
|
||||
name: '',
|
||||
});
|
||||
|
||||
const loadDataTable = async (res: any) => {
|
||||
const result = await getConfigList({ ...formParams, ...res });
|
||||
return result;
|
||||
};
|
||||
const actionColumn = reactive({
|
||||
lable: 150,
|
||||
title: '操作',
|
||||
prop: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
style: 'text',
|
||||
actions: [
|
||||
{
|
||||
label: '编辑',
|
||||
type: 'warning',
|
||||
onClick: handleEdit.bind(null, record),
|
||||
},
|
||||
{
|
||||
label: '删除',
|
||||
type: 'danger',
|
||||
onClick: handleDelete.bind(null, record),
|
||||
}
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
function reloadTable() {
|
||||
tableRef.value.reload({pageNo:1});
|
||||
}
|
||||
const [register, {}] = useForm({
|
||||
labelWidth: 80,
|
||||
layout: 'horizontal',
|
||||
colProps: { span: 6 } as ColProps,
|
||||
submitOnReset:true,
|
||||
schemas
|
||||
});
|
||||
function handleSubmit(values: Recordable) {
|
||||
handleReset()
|
||||
for (const key in values) {
|
||||
formParams[key] = values[key]
|
||||
}
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
function handleReset() {
|
||||
for (const key in formParams) {
|
||||
formParams[key] ='';
|
||||
}
|
||||
}
|
||||
const handleAdd = async () => {
|
||||
//新建字典
|
||||
const addConfig = async () => {
|
||||
configId.value=0
|
||||
await nextTick();
|
||||
editVisible.value=true
|
||||
};
|
||||
|
||||
//编辑字典
|
||||
const handleEdit = async (record: Recordable) => {
|
||||
configId.value=record.row.id
|
||||
await nextTick();
|
||||
editVisible.value=true
|
||||
};
|
||||
//选择字典项
|
||||
function onCheckedRow(row) {
|
||||
configId.value = row.id
|
||||
}
|
||||
|
||||
//刷新字典项值列表
|
||||
function reloadTable() {
|
||||
tableRef.value.reload({ pageNo: 1 });
|
||||
}
|
||||
|
||||
//加载字典项值列表;
|
||||
const loadDataTable = async (res) => {
|
||||
const result = await getConfigList({ ...params.value, ...res });
|
||||
configId.value = result?.records[0]?.id
|
||||
configItemShow.value = true
|
||||
nextTick(() => {
|
||||
const tables = tableRef.value.getTableRef();
|
||||
tables.setCurrentRow(result?.records[0])
|
||||
})
|
||||
return result;
|
||||
};
|
||||
|
||||
//删除字典项
|
||||
async function handleDelete(record: Recordable) {
|
||||
let ids = []
|
||||
if(!record){
|
||||
ids = selectionData.value.map(({id}) => id);
|
||||
}
|
||||
await confirm('确定要删除?');
|
||||
record? await configDelete(record.row.id):await configBatchDelete(ids);
|
||||
message("删除成功");
|
||||
reloadTable()
|
||||
}
|
||||
function onSelectionChange(value){
|
||||
selectionData.value = value
|
||||
let ids = []
|
||||
if (!record) {
|
||||
ids = selectionData.value.map(({ id }) => id);
|
||||
}
|
||||
await confirm('确定要删除?');
|
||||
record ? await configDelete(record.row.id) : await configBatchDelete(ids);
|
||||
message("删除成功");
|
||||
reloadTable()
|
||||
}
|
||||
function onSelectionChange(value) {
|
||||
selectionData.value = value
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,11 +0,0 @@
|
||||
import { FormSchema } from '@/components/Form/index';
|
||||
export const schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'name',
|
||||
component: 'Input',
|
||||
label: '配置名称',
|
||||
componentProps: {
|
||||
placeholder: '请输入配置名称',
|
||||
},
|
||||
}
|
||||
];
|
Loading…
Reference in New Issue
Block a user