完成字典

main
expressgy 3 months ago
parent 01571bffd1
commit eff6f9626f
  1. 2
      src/components/AntDesignVue/CustomAntDesignVue/Button/AckCreateAntdButton.vue
  2. 31
      src/components/AntDesignVue/CustomAntDesignVue/Button/TableRemoveButton.vue
  3. 15
      src/components/AntDesignVue/CustomAntDesignVue/Button/TableUpdateButton.vue
  4. 4
      src/components/AntDesignVue/CustomAntDesignVue/index.js
  5. 3
      src/components/AntDesignVue/index.js
  6. 26
      src/views/Auth/Dict/DictForm.vue
  7. 10
      src/views/Auth/Dict/DictTable.vue
  8. 3
      src/views/Auth/Dict/DictTree.vue
  9. 140
      src/views/Auth/Dict/index.vue

@ -16,7 +16,7 @@ const handleClick = () => {
</script> </script>
<template> <template>
<AButton type="primary" :loading="!canClick" @click="handleClick" :icon="h(CheckOutlined)">确认创建</AButton> <AButton type="primary" :loading="!canClick" @click="handleClick" :icon="h(CheckOutlined)">确认</AButton>
</template> </template>
<style scoped></style> <style scoped></style>

@ -0,0 +1,31 @@
<script setup name="TableRemoveButton">
import { DeleteOutlined } from '@ant-design/icons-vue';
import { h } from 'vue';
defineOptions({
name: 'TableRemoveButton',
});
const props = defineProps({
ackDelete: {
type: Function,
required: true,
default: () => {},
},
});
</script>
<template>
<APopconfirm
title="确认删除此条数据吗?"
ok-text="确认"
cancel-text="取消"
@confirm="props.ackDelete"
style="width: 200px"
placement="left"
okType="danger"
>
<AButton shape="circle" danger :icon="h(DeleteOutlined)" />
</APopconfirm>
</template>
<style scoped></style>

@ -0,0 +1,15 @@
<script setup name="TableUpdateButton">
import { FormOutlined } from '@ant-design/icons-vue';
import { h } from 'vue';
defineOptions({
name: 'TableUpdateButton',
});
</script>
<template>
<AButton shape="circle" :icon="h(FormOutlined)" />
</template>
<style scoped>
</style>

@ -17,6 +17,8 @@ import AntdModalTemplate from './AntdModalTemplate/index.vue';
import IconSelect from './IconSelect/index.vue'; import IconSelect from './IconSelect/index.vue';
import CustomIconSelect from './IconSelect/customIconSelect.vue'; import CustomIconSelect from './IconSelect/customIconSelect.vue';
import TableColumChoose from '@/components/AntDesignVue/CustomAntDesignVue/TableColumChoose/index.vue'; import TableColumChoose from '@/components/AntDesignVue/CustomAntDesignVue/TableColumChoose/index.vue';
import TableRemoveButton from '@/components/AntDesignVue/CustomAntDesignVue/Button/TableRemoveButton.vue';
import TableUpdateButton from '@/components/AntDesignVue/CustomAntDesignVue/Button/TableUpdateButton.vue';
// console.log(AntdModalTemplate); // console.log(AntdModalTemplate);
@ -28,7 +30,7 @@ export default function setupCustomAntdComponents(app) {
AntdModalTemplate, AntdModalTemplate,
IconSelect, IconSelect,
CustomIconSelect, CustomIconSelect,
TableColumChoose TableColumChoose,TableRemoveButton,TableUpdateButton
]; ];
for (let component of customComponentList) { for (let component of customComponentList) {
app.component(component.name, component); app.component(component.name, component);

@ -28,7 +28,7 @@ import {
Input, Input,
Radio, Radio,
RadioGroup, RadioGroup,
InputNumber, Affix, Anchor, AnchorLink, Tree, InputSearch, Tooltip, Drawer, Checkbox, CheckboxGroup, InputNumber, Affix, Anchor, AnchorLink, Tree, InputSearch, Tooltip, Drawer, Checkbox, CheckboxGroup, Popconfirm,
} from 'ant-design-vue'; } from 'ant-design-vue';
import 'ant-design-vue/dist/reset.css'; import 'ant-design-vue/dist/reset.css';
@ -72,6 +72,7 @@ export function setupCustomAntDesignVueComponents(app) {
Drawer, // ! 抽屉 Drawer, // ! 抽屉
Checkbox, // ! 多选 Checkbox, // ! 多选
CheckboxGroup, CheckboxGroup,
Popconfirm, // ! 气泡确认框
]; ];
for (let component of componentList) { for (let component of componentList) {
app.component(component.name, component); app.component(component.name, component);

@ -38,10 +38,6 @@ const props = defineProps({
}); });
// ! ref // ! ref
const formRef = ref(null); const formRef = ref(null);
// ! Form
const form = reactive({
...props.data.formData,
});
// ! // !
const serviceKeyDisabled = ref(false); const serviceKeyDisabled = ref(false);
// ! // !
@ -57,7 +53,7 @@ const rules = reactive({
orderNum: [], orderNum: [],
}); });
// ! pid // ! pid
watch(form, (newVal, oldVal) => { watch(props.data.formData, (newVal, oldVal) => {
if (newVal.pid != '') { if (newVal.pid != '') {
const dictList = baseDataStore.state.dictList.filter((item) => { const dictList = baseDataStore.state.dictList.filter((item) => {
return item.dictId == newVal.pid; return item.dictId == newVal.pid;
@ -118,14 +114,14 @@ function clearInput() {
<template> <template>
<AntdModalTemplate> <AntdModalTemplate>
<AForm ref="formRef" :model="form" :rules="rules" name="DictForm" :label-col="{ span: 8 }" layout="vertical"> <AForm ref="formRef" :model="props.data.formData" :rules="rules" name="DictForm" :label-col="{ span: 8 }" layout="vertical">
<AFormItem label="上级字典" name="pid"> <AFormItem label="上级字典" name="pid">
<AFlex gap="small"> <AFlex gap="small">
<ACascader <ACascader
flex="1" flex="1"
allowClear allowClear
showSearch showSearch
v-model:value="form.pid" v-model:value="props.data.formData.pid"
:options="baseDataStore.state.dictTree" :options="baseDataStore.state.dictTree"
:multiple="false" :multiple="false"
placeholder="请选择上级字典" placeholder="请选择上级字典"
@ -141,7 +137,7 @@ function clearInput() {
placeholder="请选择所属服务" placeholder="请选择所属服务"
ref="serviceKey" ref="serviceKey"
:disabled="serviceKeyDisabled" :disabled="serviceKeyDisabled"
v-model:value="form.serviceKey" v-model:value="props.data.formData.serviceKey"
:options="baseDataStore.state.serviceList" :options="baseDataStore.state.serviceList"
:field-names="{ label: 'serviceName', value: 'serviceKey', options: 'children' }" :field-names="{ label: 'serviceName', value: 'serviceKey', options: 'children' }"
/> />
@ -150,34 +146,34 @@ function clearInput() {
</AFormItem> </AFormItem>
<AFormItem label="字典标识" name="dictKey"> <AFormItem label="字典标识" name="dictKey">
<AInput style="width: 100%" v-model:value="form.dictKey" placeholder="请输入字典标识" :maxlength="32" showCount /> <AInput style="width: 100%" v-model:value="props.data.formData.dictKey" placeholder="请输入字典标识" :maxlength="32" showCount />
</AFormItem> </AFormItem>
<AFormItem label="字典名称" name="dictName"> <AFormItem label="字典名称" name="dictName">
<AInput style="width: 100%" v-model:value="form.dictName" placeholder="请输入字典名称" :maxlength="32" showCount /> <AInput style="width: 100%" v-model:value="props.data.formData.dictName" placeholder="请输入字典名称" :maxlength="32" showCount />
</AFormItem> </AFormItem>
<AFormItem label="字典类型" name="dictType"> <AFormItem label="字典类型" name="dictType">
<ASelect placeholder="请选择字典类型" ref="dictType" v-model:value="form.dictType" :options="baseDataStore.state.dictTypeList" /> <ASelect placeholder="请选择字典类型" ref="dictType" v-model:value="props.data.formData.dictType" :options="baseDataStore.state.dictTypeList" />
</AFormItem> </AFormItem>
<AFormItem label="字典图标" name="dictIcon"> <AFormItem label="字典图标" name="dictIcon">
<CustomIconSelect v-model:value="form.dictIcon" /> <CustomIconSelect v-model:value="props.data.formData.dictIcon" />
</AFormItem> </AFormItem>
<AFormItem label="字典描述" name="dictDesc"> <AFormItem label="字典描述" name="dictDesc">
<ATextarea style="width: 100%" v-model:value="form.dictDesc" :rows="3" placeholder="请输入字典描述" :maxlength="255" showCount /> <ATextarea style="width: 100%" v-model:value="props.data.formData.dictDesc" :rows="3" placeholder="请输入字典描述" :maxlength="255" showCount />
</AFormItem> </AFormItem>
<AFormItem label="原始数据Root" name="root"> <AFormItem label="原始数据Root" name="root">
<ARadioGroup v-model:value="form.root" name="radioGroup"> <ARadioGroup v-model:value="props.data.formData.root" name="radioGroup">
<ARadio :value="true"></ARadio> <ARadio :value="true"></ARadio>
<ARadio :value="false"></ARadio> <ARadio :value="false"></ARadio>
</ARadioGroup> </ARadioGroup>
</AFormItem> </AFormItem>
<AFormItem label="排序" name="orderNum"> <AFormItem label="排序" name="orderNum">
<AInputNumber v-model:value="form.orderNum"> <AInputNumber v-model:value="props.data.formData.orderNum">
<template #addonAfter><SettingOutlined /></template> <template #addonAfter><SettingOutlined /></template>
</AInputNumber> </AInputNumber>
</AFormItem> </AFormItem>

@ -1,7 +1,6 @@
<script setup> <script setup>
import { h, onMounted, ref, watch } from 'vue'; import { h, onMounted, ref, watch } from 'vue';
import { useBaseDataStore } from '@/stores/baseData.js'; import { useBaseDataStore } from '@/stores/baseData.js';
import { DeleteTwotone, EditTwotone } from '@vicons/antd';
import { IconPool } from '@/components/AntDesignVue/Icon/index.js'; import { IconPool } from '@/components/AntDesignVue/Icon/index.js';
const baseDataStore = useBaseDataStore(); const baseDataStore = useBaseDataStore();
@ -16,6 +15,8 @@ const props = defineProps({
required: true, required: true,
default: () => ({ default: () => ({
handleTableChange: () => {}, handleTableChange: () => {},
handleRemoveAck: () => {},
handleUpdate: () => {}
}), }),
}, },
columnList: { columnList: {
@ -139,7 +140,12 @@ function handleResizeColumn(w, col) {
:scroll="{ scrollToFirstRowOnChange: true }" :scroll="{ scrollToFirstRowOnChange: true }"
> >
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column?.key === 'action'"></template> <template v-if="column?.key === 'action'">
<ASpace>
<TableRemoveButton :ackDelete="() => props.methods.handleRemoveAck(record)"/>
<TableUpdateButton @click="props.methods.handleUpdate(record)"/>
</ASpace>
</template>
</template> </template>
</ATable> </ATable>
</template> </template>

@ -1,7 +1,6 @@
<script setup> <script setup>
import { useBaseDataStore } from '@/stores/baseData.js'; import { useBaseDataStore } from '@/stores/baseData.js';
import {DownOutlined, SmileOutlined} from '@vicons/antd'; import { onMounted, reactive } from 'vue';
import { onMounted, reactive, ref, watch } from 'vue';
import { IconPool } from '@/components/AntDesignVue/Icon/index.js'; import { IconPool } from '@/components/AntDesignVue/Icon/index.js';
const baseDataStore = useBaseDataStore(); const baseDataStore = useBaseDataStore();

@ -1,18 +1,27 @@
<script setup name="DictPage"> <script setup name="DictPage">
import { onMounted, reactive, h, watch } from 'vue'; import { onMounted, reactive, watch } from 'vue';
import DictForm from './DictForm.vue'; import DictForm from './DictForm.vue';
import { CoreDict } from '@/api/index.js'; import { CoreDict } from '@/api/index.js';
import { useMessage } from 'naive-ui'; import { useMessage } from 'naive-ui';
import DictTable from '@/views/Auth/Dict/DictTable.vue'; import DictTable from '@/views/Auth/Dict/DictTable.vue';
import DictTree from '@/views/Auth/Dict/DictTree.vue'; import DictTree from '@/views/Auth/Dict/DictTree.vue';
import { BgColorsOutlined } from '@ant-design/icons-vue'; import { useBaseDataStore } from '@/stores/baseData.js';
import { IconPool } from '@/components/AntDesignVue/Icon/index.js'; const baseDataStore = useBaseDataStore();
const Message = useMessage(); const Message = useMessage();
//
let searchCount = 0;
// ! // !
const formData = reactive({ const formData = reactive({
//
modelName: '创建字典',
// //
status: false, status: false,
//
isUpdate: false,
// ID
dictId: undefined,
// //
formData: { formData: {
pid: 0, pid: 0,
@ -36,15 +45,15 @@ const formData = reactive({
// //
handleAck: (data) => handleCreateAck(data), handleAck: (data) => handleCreateAck(data),
// //
handleCancel: () => { handleCancel: clearFormData,
formData.status = false;
},
}); });
// ! // !
const tableData = reactive({ const tableData = reactive({
dataSource: [], dataSource: [],
methods: { methods: {
handleTableChange: () => {}, handleTableChange: () => {},
handleRemoveAck,
handleUpdate,
}, },
pageInfo: { pageInfo: {
pageSize: 10, pageSize: 10,
@ -71,19 +80,64 @@ const tableData = reactive({
{ title: '更新时间', key: 'updatetime', status: true }, { title: '更新时间', key: 'updatetime', status: true },
{ title: '更新人', key: 'updateName', status: true }, { title: '更新人', key: 'updateName', status: true },
{ title: '操作', key: 'action', status: true }, { title: '操作', key: 'action', status: true },
] ],
}); });
// todo
// todo
// todo
// ! // !
async function handleCreateAck(data) { async function handleCreateAck(data) {
await CoreDict.createDict(data); await CoreDict.createDict(data);
Message.success('添加字典成功!'); Message.success('添加字典成功!');
formData.status = false; clearSearchData();
clearFormData();
getPage();
}
// !
async function handleRemoveAck(data) {
await CoreDict.removeDict(data.dictId);
Message.success('删除字典成功!');
if (tableData.dataSource.length == 1 && tableData.pageInfo.pageNumber > 1) {
tableData.pageInfo.pageNumber--;
}
getPage();
} }
// !
async function handleUpdate(data) {
formData.modelName = '更新字典';
formData.status = true;
formData.isUpdate = true;
formData.dictId = data.dictId;
formData.formData.pid = data.pid;
formData.formData.dictKey = data.dictKey;
formData.formData.dictDesc = data.dictDesc;
formData.formData.dictName = data.dictName;
formData.formData.dictIcon = data.dictIcon;
formData.formData.dictType = data.dictType;
formData.formData.serviceKey = data.serviceKey;
formData.formData.root = data.root;
formData.formData.orderNum = data.orderNum;
formData.handleAck = handleUpdateAck;
}
// !
async function handleUpdateAck(data) {
await CoreDict.updateDict(formData.dictId, data);
Message.success('更新字典成功!');
clearFormData();
getPage();
}
// !
watch(tableData.pageInfo, () => {
if (searchCount === 0) {
searchCount++;
getPage();
setTimeout(() => {
searchCount = 0;
}, 750);
} else {
searchCount++;
}
});
// ! // !
async function getPage() { async function getPage() {
baseDataStore.getDictList();
const resd = await CoreDict.getDict(tableData.pageInfo); const resd = await CoreDict.getDict(tableData.pageInfo);
tableData.dataSource = resd.rowData; tableData.dataSource = resd.rowData;
tableData.total = Number(resd.total); tableData.total = Number(resd.total);
@ -94,8 +148,42 @@ const handlePageChange = (page, pageSize) => {
tableData.pageInfo.pageNumber = page; tableData.pageInfo.pageNumber = page;
getPage(); getPage();
}; };
// !
function clearSearchData() {
tableData.pageInfo = {
pageSize: 10,
pageNumber: 1,
isList: false,
isAsc: false,
dictInfo: undefined,
dictType: undefined,
root: undefined,
serviceKey: undefined,
status: undefined,
};
}
// !
function clearFormData() {
formData.modelName = '创建字典';
formData.isUpdate = false;
formData.status = false;
formData.dictId = undefined;
formData.handleAck = handleCreateAck;
formData.formData.pid = 0;
formData.formData.dictKey = '';
formData.formData.dictDesc = '';
formData.formData.dictName = '';
formData.formData.dictIcon = '';
formData.formData.dictType = 1;
formData.formData.serviceKey = undefined;
formData.formData.root = false;
formData.formData.orderNum = 0;
}
onMounted(() => { onMounted(() => {
getPage(); getPage();
if (baseDataStore.state.serviceList.length == 0) {
baseDataStore.getServiceList();
}
}); });
</script> </script>
@ -104,16 +192,34 @@ onMounted(() => {
<template #header> <template #header>
<ASpace> <ASpace>
<CreateAntdButton name="字典" @click="formData.status = true" /> <CreateAntdButton name="字典" @click="formData.status = true" />
<TableColumChoose v-model:columnList="tableData.tableColumnList"/> <TableColumChoose v-model:columnList="tableData.tableColumnList" />
<AInputSearch v-model:value="tableData.pageInfo.dictInfo" placeholder="字典名称/标识/描述" style="width: 200px" @search="getPage" />
<ASelect placeholder="请选择字典类型" allowClear v-model:value="tableData.pageInfo.dictType" :options="baseDataStore.state.dictTypeList" />
<ASelect
placeholder="请选择所属服务"
allowClear
v-model:value="tableData.pageInfo.serviceKey"
:options="baseDataStore.state.serviceList"
:field-names="{ label: 'serviceName', value: 'serviceKey', options: 'children' }"
/>
<ASelect
placeholder="是否为原始数据"
allowClear
v-model:value="tableData.pageInfo.root"
:options="[
{ label: '是', value: 1 },
{ label: '否', value: 0 },
]"
/>
</ASpace> </ASpace>
</template> </template>
<template #main> <template #main>
<div class="dickBody"> <div class="dickBody">
<div class="tree"> <div class="tree">
<DictTree/> <DictTree />
</div> </div>
<div class="table"> <div class="table">
<DictTable :methods="tableData.methods" :dataSource="tableData.dataSource" :columnList="tableData.tableColumnList"/> <DictTable :methods="tableData.methods" :dataSource="tableData.dataSource" :columnList="tableData.tableColumnList" />
</div> </div>
</div> </div>
</template> </template>
@ -139,12 +245,12 @@ onMounted(() => {
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.dickBody{ .dickBody {
position: relative; position: relative;
height: 100%; height: 100%;
width: 100%; width: 100%;
display: flex; display: flex;
& > div.tree{ & > div.tree {
position: relative; position: relative;
flex-shrink: 0; flex-shrink: 0;
max-height: 100%; max-height: 100%;
@ -152,7 +258,7 @@ onMounted(() => {
border-right: 1px solid #cdcdcd; border-right: 1px solid #cdcdcd;
padding-right: 5px; padding-right: 5px;
} }
& > div.table{ & > div.table {
position: relative; position: relative;
flex: 1; flex: 1;
max-height: 100%; max-height: 100%;

Loading…
Cancel
Save