|
@@ -0,0 +1,411 @@
|
|
|
|
|
+<script setup lang="ts">
|
|
|
|
|
+import {
|
|
|
|
|
+ type PlusColumn,
|
|
|
|
|
+ PlusDialogForm,
|
|
|
|
|
+ PlusPage,
|
|
|
|
|
+ type PlusPageInstance,
|
|
|
|
|
+ useTable
|
|
|
|
|
+} from "plus-pro-components";
|
|
|
|
|
+import {
|
|
|
|
|
+ addSystemDictData,
|
|
|
|
|
+ deleteSystemDictData,
|
|
|
|
|
+ getDictTypeOptionSelect,
|
|
|
|
|
+ getSystemDictDataById,
|
|
|
|
|
+ getSystemDictDataList,
|
|
|
|
|
+ updateSystemDictData
|
|
|
|
|
+} from "@/api/system/dict";
|
|
|
|
|
+import { computed, onMounted, reactive, ref, toRefs } from "vue";
|
|
|
|
|
+import { useRoute, useRouter } from "vue-router";
|
|
|
|
|
+import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
|
|
+import { cloneDeep } from "lodash-es";
|
|
|
|
|
+import { isString } from "@pureadmin/utils";
|
|
|
|
|
+import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
|
|
|
|
+
|
|
|
|
|
+defineOptions({
|
|
|
|
|
+ name: "DictData"
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const route = useRoute();
|
|
|
|
|
+const router = useRouter();
|
|
|
|
|
+
|
|
|
|
|
+const defaultValues = {
|
|
|
|
|
+ dictType: isString(route.query.dictType)
|
|
|
|
|
+ ? (route.query.dictType as string)
|
|
|
|
|
+ : ""
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+onMounted(() => {});
|
|
|
|
|
+
|
|
|
|
|
+const plusPageInstance = ref<PlusPageInstance | null>(null);
|
|
|
|
|
+
|
|
|
|
|
+const getList = async (query: Record<string, any>) => {
|
|
|
|
|
+ let res = await getSystemDictDataList(query);
|
|
|
|
|
+ return {
|
|
|
|
|
+ data: res.rows,
|
|
|
|
|
+ total: res.total
|
|
|
|
|
+ };
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const multipleSelection = ref([]);
|
|
|
|
|
+
|
|
|
|
|
+const handleSelectionChange = (val: string[]) => {
|
|
|
|
|
+ multipleSelection.value = val;
|
|
|
|
|
+ console.log(multipleSelection.value);
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const handleDelete = () => {
|
|
|
|
|
+ // 删除前确认
|
|
|
|
|
+ ElMessageBox.confirm("是否确认删除选中数据?", "删除确认", {
|
|
|
|
|
+ confirmButtonText: "确认",
|
|
|
|
|
+ cancelButtonText: "取消",
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ draggable: true
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let dictCodes = multipleSelection.value.map(
|
|
|
|
|
+ item => item.dictCode
|
|
|
|
|
+ ) as string[];
|
|
|
|
|
+ let res = await deleteSystemDictData(dictCodes.join(","));
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success("删除成功");
|
|
|
|
|
+ refresh();
|
|
|
|
|
+ multipleSelection.value = [];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ ElMessage.error("删除失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ // 取消删除
|
|
|
|
|
+ });
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 重新请求列表接口
|
|
|
|
|
+const refresh = () => {
|
|
|
|
|
+ plusPageInstance.value?.getList();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const dialogTitle = computed(() => (state.isCreate ? "新增" : "编辑"));
|
|
|
|
|
+
|
|
|
|
|
+const dictNameList = ref<Array<{ label: string; value: string }>>([]);
|
|
|
|
|
+
|
|
|
|
|
+onMounted(async () => {
|
|
|
|
|
+ // 获取字典名称下拉选项
|
|
|
|
|
+ let res = await getDictTypeOptionSelect();
|
|
|
|
|
+ dictNameList.value = res.data;
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const tableConfig: PlusColumn[] = [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "字典编码",
|
|
|
|
|
+ prop: "dictCode",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ width: 120,
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "字典名称",
|
|
|
|
|
+ prop: "dictType",
|
|
|
|
|
+ valueType: "select",
|
|
|
|
|
+ width: 150,
|
|
|
|
|
+ options: computed(() => dictNameList.value),
|
|
|
|
|
+ optionsMap: {
|
|
|
|
|
+ label: "dictName",
|
|
|
|
|
+ value: "dictType"
|
|
|
|
|
+ },
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: false
|
|
|
|
|
+ },
|
|
|
|
|
+ hideInTable: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "字典标签",
|
|
|
|
|
+ prop: "dictLabel",
|
|
|
|
|
+ valueType: "input"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "字典键值",
|
|
|
|
|
+ prop: "dictValue",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "字典排序",
|
|
|
|
|
+ prop: "dictSort",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ type: "number"
|
|
|
|
|
+ },
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "状态",
|
|
|
|
|
+ prop: "status",
|
|
|
|
|
+ valueType: "tag",
|
|
|
|
|
+ fieldProps: value => ({
|
|
|
|
|
+ type: value === "0" ? "primary" : "danger"
|
|
|
|
|
+ }),
|
|
|
|
|
+ fieldSlots: {
|
|
|
|
|
+ default: ({ value }) => (value === "0" ? "正常" : "停用")
|
|
|
|
|
+ },
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "状态",
|
|
|
|
|
+ prop: "status",
|
|
|
|
|
+ valueType: "select",
|
|
|
|
|
+ options: [
|
|
|
|
|
+ { label: "正常", value: "0" },
|
|
|
|
|
+ { label: "停用", value: "1" }
|
|
|
|
|
+ ],
|
|
|
|
|
+ hideInTable: true,
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ clearable: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "备注",
|
|
|
|
|
+ prop: "remark",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ hideInSearch: true
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "创建时间",
|
|
|
|
|
+ prop: "createTime",
|
|
|
|
|
+ valueType: "date-picker",
|
|
|
|
|
+ hideInSearch: true,
|
|
|
|
|
+ width: 180
|
|
|
|
|
+ }
|
|
|
|
|
+];
|
|
|
|
|
+
|
|
|
|
|
+const { buttons } = useTable();
|
|
|
|
|
+
|
|
|
|
|
+buttons.value = [
|
|
|
|
|
+ {
|
|
|
|
|
+ // 修改
|
|
|
|
|
+ text: "修改",
|
|
|
|
|
+ code: "edit",
|
|
|
|
|
+ // props v0.1.16 版本新增函数类型
|
|
|
|
|
+ props: {
|
|
|
|
|
+ type: "primary"
|
|
|
|
|
+ },
|
|
|
|
|
+ onClick(params) {
|
|
|
|
|
+ getSystemDictDataById(params.row.dictCode).then(res => {
|
|
|
|
|
+ form.value = res.data;
|
|
|
|
|
+ state.isCreate = false;
|
|
|
|
|
+ state.dialogVisible = true;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ // 删除
|
|
|
|
|
+ text: "删除",
|
|
|
|
|
+ code: "delete",
|
|
|
|
|
+ // props v0.1.16 版本新增计算属性支持
|
|
|
|
|
+ props: computed(() => ({ type: "danger" })),
|
|
|
|
|
+ confirm: {
|
|
|
|
|
+ options: {
|
|
|
|
|
+ draggable: true,
|
|
|
|
|
+ message: "确定删除此数据吗?"
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ onConfirm: async params => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ let res = await deleteSystemDictData(params.row.dictCode);
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success("删除成功");
|
|
|
|
|
+ refresh();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ ElMessage.error("删除失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+];
|
|
|
|
|
+
|
|
|
|
|
+const handleCreate = () => {
|
|
|
|
|
+ console.log("handleCreate");
|
|
|
|
|
+ form.value = {
|
|
|
|
|
+ dictType: defaultValues.dictType,
|
|
|
|
|
+ status: "0"
|
|
|
|
|
+ };
|
|
|
|
|
+ state.isCreate = true;
|
|
|
|
|
+ state.dialogVisible = true;
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const handleCloseTag = () => {
|
|
|
|
|
+ const path = router.currentRoute.value.path;
|
|
|
|
|
+ useMultiTagsStoreHook().handleTags("splice", path);
|
|
|
|
|
+ router.back();
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+interface State {
|
|
|
|
|
+ dialogVisible: boolean;
|
|
|
|
|
+ detailsVisible: boolean;
|
|
|
|
|
+ confirmLoading: boolean;
|
|
|
|
|
+ selectedIds: number[];
|
|
|
|
|
+ isCreate: boolean;
|
|
|
|
|
+ form: Record<string, any>;
|
|
|
|
|
+ rules: Record<string, any>;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const state = reactive<State>({
|
|
|
|
|
+ dialogVisible: false,
|
|
|
|
|
+ detailsVisible: false,
|
|
|
|
|
+ confirmLoading: false,
|
|
|
|
|
+ selectedIds: [],
|
|
|
|
|
+ isCreate: true,
|
|
|
|
|
+ form: {
|
|
|
|
|
+ status: "0"
|
|
|
|
|
+ },
|
|
|
|
|
+ rules: {
|
|
|
|
|
+ dictName: [{ required: true, message: "请输入字典名称", trigger: "blur" }],
|
|
|
|
|
+ dictType: [{ required: true, message: "请输入字典类型", trigger: "blur" }]
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+const columns: PlusColumn[] = [
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "字典类型",
|
|
|
|
|
+ prop: "dictType",
|
|
|
|
|
+ valueType: "input",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ disabled: true
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "数据标签",
|
|
|
|
|
+ prop: "dictLabel",
|
|
|
|
|
+ valueType: "input"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "数据键值",
|
|
|
|
|
+ prop: "dictValue",
|
|
|
|
|
+ valueType: "input"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "样式属性",
|
|
|
|
|
+ prop: "cssClass",
|
|
|
|
|
+ valueType: "input"
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "显示排序",
|
|
|
|
|
+ prop: "dictSort",
|
|
|
|
|
+ valueType: "input-number",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ min: 0
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "状态",
|
|
|
|
|
+ prop: "status",
|
|
|
|
|
+ valueType: "radio",
|
|
|
|
|
+ fieldProps: {
|
|
|
|
|
+ options: [
|
|
|
|
|
+ { label: "正常", value: "0" },
|
|
|
|
|
+ { label: "停用", value: "1" }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ label: "备注",
|
|
|
|
|
+ prop: "remark",
|
|
|
|
|
+ valueType: "textarea"
|
|
|
|
|
+ }
|
|
|
|
|
+];
|
|
|
|
|
+
|
|
|
|
|
+const handleSubmit = async () => {
|
|
|
|
|
+ state.confirmLoading = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ let payload = cloneDeep(form.value);
|
|
|
|
|
+ let res: any;
|
|
|
|
|
+ if (state.isCreate) {
|
|
|
|
|
+ res = await addSystemDictData(payload);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ res = await updateSystemDictData(payload);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (res.code === 200) {
|
|
|
|
|
+ ElMessage.success(state.isCreate ? "新增成功" : "修改成功");
|
|
|
|
|
+ state.dialogVisible = false;
|
|
|
|
|
+ refresh();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error(res.msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ ElMessage.error(state.isCreate ? "新增失败" : "修改失败");
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ state.confirmLoading = false;
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const { form, confirmLoading, rules, dialogVisible } = toRefs(state);
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <PlusPage
|
|
|
|
|
+ ref="plusPageInstance"
|
|
|
|
|
+ :columns="tableConfig"
|
|
|
|
|
+ :request="getList"
|
|
|
|
|
+ :pageInfoMap="{ page: 'pageNum', pageSize: 'pageSize' }"
|
|
|
|
|
+ :table="{
|
|
|
|
|
+ actionBar: { buttons, type: 'link', width: 140 },
|
|
|
|
|
+ adaptive: { offsetBottom: 50 },
|
|
|
|
|
+ isSelection: true,
|
|
|
|
|
+ rowKey: 'dictCode',
|
|
|
|
|
+ onSelectionChange: handleSelectionChange
|
|
|
|
|
+ }"
|
|
|
|
|
+ :search="{
|
|
|
|
|
+ defaultValues: defaultValues,
|
|
|
|
|
+ showNumber: 3
|
|
|
|
|
+ }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #table-title>
|
|
|
|
|
+ <el-row class="button-row">
|
|
|
|
|
+ <el-button size="default" type="success" @click="handleCreate">
|
|
|
|
|
+ 新增
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ :disabled="multipleSelection.length === 0"
|
|
|
|
|
+ @click="handleDelete"
|
|
|
|
|
+ >
|
|
|
|
|
+ 删除
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ size="default"
|
|
|
|
|
+ type="warning"
|
|
|
|
|
+ plain
|
|
|
|
|
+ @click="handleCloseTag"
|
|
|
|
|
+ >
|
|
|
|
|
+ 关闭
|
|
|
|
|
+ </el-button>
|
|
|
|
|
+ </el-row>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </PlusPage>
|
|
|
|
|
+ <!-- 弹窗编辑 -->
|
|
|
|
|
+ <PlusDialogForm
|
|
|
|
|
+ ref="dialogForm"
|
|
|
|
|
+ v-model="form"
|
|
|
|
|
+ v-model:visible="dialogVisible"
|
|
|
|
|
+ :form="{
|
|
|
|
|
+ columns,
|
|
|
|
|
+ labelPosition: 'right',
|
|
|
|
|
+ labelWidth: 100,
|
|
|
|
|
+ rules,
|
|
|
|
|
+ rowProps: { gutter: 20 },
|
|
|
|
|
+ colProps: { span: 12 },
|
|
|
|
|
+ defaultValues: defaultValues
|
|
|
|
|
+ }"
|
|
|
|
|
+ :dialog="{ title: dialogTitle + '字典数据', width: 600, confirmLoading }"
|
|
|
|
|
+ @confirm="handleSubmit"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped lang="scss"></style>
|