|
|
@@ -9,81 +9,85 @@
|
|
|
<el-input v-model="formData.dictCode" />
|
|
|
</el-form-item>
|
|
|
|
|
|
- <el-form-item label="字典分类" prop="dictCategoryType">
|
|
|
- <el-select v-model="formData.dictCategoryType" placeholder="请选择">
|
|
|
- <!-- <el-option label="分类1" value="category1"></el-option> -->
|
|
|
- <!-- <el-option label="分类2" value="category2"></el-option> -->
|
|
|
+ <el-form-item label="字典分类" prop="dictType">
|
|
|
+ <el-select v-model="formData.dictType" placeholder="请选择">
|
|
|
+ <el-option v-for="(item, index) in dictionaryTypeOptions" :key="index" :label="item.label"
|
|
|
+ :value="item.value" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
<div class="subDictWrapper">
|
|
|
<div class="el-form-item__label" style="width: 100px">字典项</div>
|
|
|
<div class="subDictList">
|
|
|
<div>
|
|
|
- <div v-for="(item, index) in formData.dictItems" :key="index" class="dict-item-group">
|
|
|
+ <div v-for="(item, index) in formData.sysDictDataList" :key="index" class="dict-item-group">
|
|
|
+ <!-- 移动按钮 -->
|
|
|
<div class="dict-item-header">
|
|
|
- <el-button v-if="formData.dictItems.length > 1" type="danger" link @click="removeDictItem(index)">
|
|
|
- <el-icon><Delete /></el-icon> 删除
|
|
|
- </el-button>
|
|
|
+ <div class="move-buttons">
|
|
|
+ <el-button v-if="index > 0" type="primary" link @click="moveDictItem(index, 'up')">
|
|
|
+ <el-icon>
|
|
|
+ <Top />
|
|
|
+ </el-icon>
|
|
|
+ </el-button>
|
|
|
+ <el-button v-if="index < formData.sysDictDataList.length - 1" type="primary" link
|
|
|
+ @click="moveDictItem(index, 'down')">
|
|
|
+ <el-icon>
|
|
|
+ <Bottom />
|
|
|
+ </el-icon>
|
|
|
+ </el-button>
|
|
|
+ <el-button v-if="formData.sysDictDataList.length > 1" type="danger" link
|
|
|
+ @click="removeDictItem(index)">
|
|
|
+ <el-icon>
|
|
|
+ <Delete />
|
|
|
+ </el-icon>删除
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- <el-form-item
|
|
|
- :label="`字典项值`"
|
|
|
- :prop="`dictItems.${index}.value`"
|
|
|
- :rules="[{ required: true, message: '请输入字典项值', trigger: 'blur' }]"
|
|
|
- >
|
|
|
- <el-input v-model="item.value" placeholder="请输入" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item
|
|
|
- :label="`字典项编码`"
|
|
|
- :prop="`dictItems.${index}.code`"
|
|
|
- :rules="[{ required: true, message: '请输入字典项编码', trigger: 'blur' }]"
|
|
|
- >
|
|
|
- <el-input v-model="item.code" placeholder="请输入" />
|
|
|
+
|
|
|
+ <el-form-item :label="`字典项值`" :prop="`sysDictDataList.${index}.itemValue`"
|
|
|
+ :rules="[{ required: true, message: '请输入字典项值', trigger: 'blur' }]">
|
|
|
+ <el-input v-model="item.itemValue" placeholder="请输入" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item
|
|
|
- :label="`显示排序`"
|
|
|
- :prop="`dictItems.${index}.sortOrder`"
|
|
|
- :rules="[{ required: true, message: '请输入显示排序', trigger: 'blur' }]"
|
|
|
- >
|
|
|
- <el-input-number v-model="item.sortOrder" :min="1" placeholder="请输入" />
|
|
|
+ <el-form-item :label="`字典项编码`" :prop="`sysDictDataList.${index}.itemCode`"
|
|
|
+ :rules="[{ required: true, message: '请输入字典项编码', trigger: 'blur' }]">
|
|
|
+ <el-input v-model="item.itemCode" placeholder="请输入" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="图标">
|
|
|
- <el-upload
|
|
|
- action="#"
|
|
|
- list-type="picture-card"
|
|
|
- :auto-upload="false"
|
|
|
+ <el-upload
|
|
|
+ auto-upload="false"
|
|
|
+ :action="actionUrl"
|
|
|
+ list-type="picture-card"
|
|
|
:limit="1"
|
|
|
- :on-preview="(file) => handlePictureCardPreview(file, index)"
|
|
|
- :on-remove="() => handleRemove(index)"
|
|
|
+ :on-preview="(file) => handlePictureCardPreview(file, index)" :on-remove="() => handleRemove(index)"
|
|
|
:on-change="(file, fileList) => handleChange(file, fileList, index)"
|
|
|
- >
|
|
|
- <el-icon><Plus /></el-icon>
|
|
|
+
|
|
|
+ >
|
|
|
+ <el-icon>
|
|
|
+ <Plus />
|
|
|
+ </el-icon>
|
|
|
</el-upload>
|
|
|
- </el-form-item> </div
|
|
|
- ></div>
|
|
|
+ </el-form-item>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<el-form-item>
|
|
|
<el-button type="primary" link @click="addDictItem">
|
|
|
- <el-icon><CirclePlus /></el-icon> 新增字典分类
|
|
|
+ <el-icon>
|
|
|
+ <CirclePlus />
|
|
|
+ </el-icon> 新增字典分类
|
|
|
</el-button>
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="字典描述" prop="description">
|
|
|
- <el-input
|
|
|
- v-model="formData.description"
|
|
|
- type="textarea"
|
|
|
- :rows="3"
|
|
|
- placeholder="请描述灾害处置过程, 不超过1000字"
|
|
|
- maxlength="1000"
|
|
|
- show-word-limit
|
|
|
- />
|
|
|
+ <el-input v-model="formData.description" type="textarea" :rows="3" placeholder="请描述灾害处置过程, 不超过1000字"
|
|
|
+ maxlength="1000" show-word-limit />
|
|
|
</el-form-item>
|
|
|
|
|
|
<el-form-item label="状态" prop="status">
|
|
|
<el-radio-group v-model="formData.status">
|
|
|
- <el-radio-button label="enabled">启用</el-radio-button>
|
|
|
- <el-radio-button label="disabled">停用</el-radio-button>
|
|
|
+ <el-radio-button v-for="item in dictionaryStatusOptions" :key="item.value" :value="item.value">{{ item.label
|
|
|
+ }}</el-radio-button>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
|
|
|
@@ -95,254 +99,336 @@
|
|
|
</el-drawer>
|
|
|
|
|
|
<el-dialog v-model="dialogVisible">
|
|
|
- <img w-full :src="dialogImageUrl" alt="Preview Image" />
|
|
|
+ <div class="dialog-content">
|
|
|
+ <img :src="dialogImageUrl" alt="Preview Image" />
|
|
|
+ </div>
|
|
|
</el-dialog>
|
|
|
</template>
|
|
|
|
|
|
<script lang="ts" setup>
|
|
|
- import { ref, reactive, PropType, watch } from 'vue';
|
|
|
- import {
|
|
|
- ElForm,
|
|
|
- ElFormItem,
|
|
|
- ElInput,
|
|
|
- ElSelect,
|
|
|
- ElOption,
|
|
|
- ElButton,
|
|
|
- ElRadioGroup,
|
|
|
- ElRadioButton,
|
|
|
- ElInputNumber,
|
|
|
- ElUpload,
|
|
|
- ElIcon,
|
|
|
- ElDialog,
|
|
|
- ElDivider,
|
|
|
- FormInstance,
|
|
|
- FormRules,
|
|
|
- UploadProps,
|
|
|
- UploadUserFile,
|
|
|
- } from 'element-plus';
|
|
|
- import { Plus, Delete, CirclePlus, Minus, Picture } from '@element-plus/icons-vue';
|
|
|
-
|
|
|
- interface DictItem {
|
|
|
- id?: string | number; // 可选,用于编辑时
|
|
|
- value: string;
|
|
|
- code: string;
|
|
|
- sortOrder: number | undefined;
|
|
|
- iconFile?: UploadUserFile | null; // 用于存储上传的文件对象
|
|
|
- iconUrl?: string; // 用于显示已上传的图片
|
|
|
- }
|
|
|
+import { ref, reactive, PropType, watch, computed } from 'vue';
|
|
|
+import {
|
|
|
+ ElForm,
|
|
|
+ ElFormItem,
|
|
|
+ ElInput,
|
|
|
+ ElSelect,
|
|
|
+ ElOption,
|
|
|
+ ElButton,
|
|
|
+ ElRadioGroup,
|
|
|
+ ElRadioButton,
|
|
|
+ ElInputNumber,
|
|
|
+ ElUpload,
|
|
|
+ ElIcon,
|
|
|
+ ElDialog,
|
|
|
+ ElDivider,
|
|
|
+ FormInstance,
|
|
|
+ FormRules,
|
|
|
+ UploadProps,
|
|
|
+ UploadUserFile,
|
|
|
+} from 'element-plus';
|
|
|
+import { Plus, Delete, CirclePlus, Minus, Picture, Top, Bottom } from '@element-plus/icons-vue';
|
|
|
+import { dictionaryTypeOptions, DictionaryStatus, dictionaryStatusOptions } from '../constants';
|
|
|
+import { queryDictTypeDetail, uploadPresetImageApi } from '@/api/dict'
|
|
|
+import { getHeaders } from '@/utils/http/axios';
|
|
|
+import { useGlobSetting } from '@/hooks/setting';
|
|
|
+import urlJoin from 'url-join';
|
|
|
|
|
|
- interface FormData {
|
|
|
- id?: string | number; // 可选,用于编辑时
|
|
|
- dictName: string;
|
|
|
- dictCode: string;
|
|
|
- dictCategoryType: string;
|
|
|
- dictItems: DictItem[];
|
|
|
- description: string;
|
|
|
- status: 'enabled' | 'disabled';
|
|
|
- }
|
|
|
+interface SysDictDataItem {
|
|
|
+ id?: string | number; // 可选,用于编辑时
|
|
|
+ dictId: string | number | undefined; // 关联的字典ID
|
|
|
+ dictCode: string;
|
|
|
+ itemValue: string;
|
|
|
+ itemCode: string;
|
|
|
+ itemSort: number | undefined;
|
|
|
+ isDefault: 0 | 1,
|
|
|
+ imageUrl?: string; // 用于显示已上传的图片
|
|
|
+ status: DictionaryStatus.disabled | DictionaryStatus.enabled;
|
|
|
+}
|
|
|
|
|
|
- const props = defineProps({
|
|
|
- initialData: {
|
|
|
- type: Object as PropType<Partial<FormData>>,
|
|
|
- default: () => ({}),
|
|
|
- },
|
|
|
- // 可根据需要添加其他 props,例如区分是新增还是编辑模式
|
|
|
- isEditMode: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- });
|
|
|
+interface FormData {
|
|
|
+ dictId?: string | number; // 可选,用于编辑时
|
|
|
+ dictName: string;
|
|
|
+ dictCode: string;
|
|
|
+ dictType: string;
|
|
|
+ sysDictDataList: SysDictDataItem[];
|
|
|
+ description: string;
|
|
|
+ status: DictionaryStatus.disabled | DictionaryStatus.enabled;
|
|
|
+}
|
|
|
|
|
|
- const emit = defineEmits(['submit', 'close']);
|
|
|
+const props = defineProps({
|
|
|
+ dictCode: {
|
|
|
+ type: String,
|
|
|
+ default: '',
|
|
|
+ }
|
|
|
+});
|
|
|
|
|
|
- const handleClose = () => {
|
|
|
- emit('close');
|
|
|
- };
|
|
|
+const { urlPrefix } = useGlobSetting();
|
|
|
+const actionUrl = computed(() => {
|
|
|
+ return urlJoin(urlPrefix!, `/admin/minio/uploadFile`);
|
|
|
+});
|
|
|
|
|
|
- const formRef = ref<FormInstance>();
|
|
|
- const formData = reactive<FormData>({
|
|
|
- dictName: '',
|
|
|
- dictCode: '',
|
|
|
- dictCategoryType: '',
|
|
|
- dictItems: [
|
|
|
- {
|
|
|
- value: '',
|
|
|
- code: '',
|
|
|
- sortOrder: 5, // 默认排序值
|
|
|
- iconFile: null,
|
|
|
- },
|
|
|
- ],
|
|
|
- description: '',
|
|
|
- status: 'enabled',
|
|
|
- ...props.initialData, // 使用 initialData 初始化表单
|
|
|
- });
|
|
|
+const emit = defineEmits(['submit', 'close']);
|
|
|
+const handleClose = () => {
|
|
|
+ emit('close');
|
|
|
+};
|
|
|
|
|
|
- // 监听 initialData 的变化,用于编辑时填充表单
|
|
|
- watch(
|
|
|
- () => props.initialData,
|
|
|
- (newData) => {
|
|
|
- if (newData) {
|
|
|
- Object.assign(formData, {
|
|
|
- ...formData, // 保留现有响应式链接
|
|
|
- ...newData,
|
|
|
- dictItems: newData.dictItems
|
|
|
- ? newData.dictItems.map((item) => ({ ...item }))
|
|
|
- : [{ value: '', code: '', sortOrder: 5, iconFile: null }],
|
|
|
- });
|
|
|
- }
|
|
|
+const formRef = ref<FormInstance>();
|
|
|
+const formData = reactive<FormData>({
|
|
|
+ dictName: '',
|
|
|
+ dictCode: '',
|
|
|
+ dictType: '',
|
|
|
+ sysDictDataList: [
|
|
|
+ {
|
|
|
+ id: undefined,
|
|
|
+ dictId: undefined,
|
|
|
+ dictCode: '',
|
|
|
+ itemCode: '',
|
|
|
+ itemValue: '',
|
|
|
+ itemSort: 1, // 默认排序值
|
|
|
+ // iconFile: null,
|
|
|
+ isDefault: 0,
|
|
|
+ status: DictionaryStatus.disabled,
|
|
|
+ imageUrl: '',
|
|
|
},
|
|
|
- { deep: true, immediate: true },
|
|
|
+ ],
|
|
|
+ description: '',
|
|
|
+ status: DictionaryStatus.disabled,
|
|
|
+ ...props.initialData, // 使用 initialData 初始化表单
|
|
|
+});
|
|
|
+
|
|
|
+watch(() => props.dictCode, (newData) => {
|
|
|
+ if (newData) {
|
|
|
+ queryDictTypeDetail(newData).then((res) => {
|
|
|
+ Object.assign(formData, {
|
|
|
+ ...res,
|
|
|
+ // 单独处理字典项数组保持响应式更新
|
|
|
+ sysDictDataList: res.sysDictDataList || []
|
|
|
+ });
|
|
|
+ })
|
|
|
+ }
|
|
|
+}, { deep: true, immediate: true })
|
|
|
+
|
|
|
+const formRules = reactive<FormRules<FormData>>({
|
|
|
+ dictName: [{ required: true, message: '请选择字典名称', trigger: 'change' }],
|
|
|
+ dictCode: [{ required: true, message: '请选择字典编码', trigger: 'change' }],
|
|
|
+ dictType: [{ required: true, message: '请选择字典分类', trigger: 'change' }],
|
|
|
+ description: [{ max: 1000, message: '描述不超过1000字', trigger: 'blur' }],
|
|
|
+ status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
|
|
+});
|
|
|
+
|
|
|
+const addDictItem = () => {
|
|
|
+ formData.sysDictDataList.push({
|
|
|
+ id: undefined,
|
|
|
+ dictId: formData.dictId,
|
|
|
+ dictCode: formData.dictCode,
|
|
|
+ itemCode: '',
|
|
|
+ itemValue: '',
|
|
|
+ itemSort: 1, // 默认排序值
|
|
|
+ isDefault: 0,
|
|
|
+ status: DictionaryStatus.disabled,
|
|
|
+ imageUrl: '',
|
|
|
+ },
|
|
|
);
|
|
|
+};
|
|
|
|
|
|
- const formRules = reactive<FormRules<FormData>>({
|
|
|
- dictName: [{ required: true, message: '请选择字典名称', trigger: 'change' }],
|
|
|
- dictCode: [{ required: true, message: '请选择字典编码', trigger: 'change' }],
|
|
|
- dictCategoryType: [{ required: true, message: '请选择字典分类', trigger: 'change' }],
|
|
|
- description: [{ max: 1000, message: '描述不超过1000字', trigger: 'blur' }],
|
|
|
- status: [{ required: true, message: '请选择状态', trigger: 'change' }],
|
|
|
- });
|
|
|
+const removeDictItem = (index: number) => {
|
|
|
+ formData.sysDictDataList.splice(index, 1);
|
|
|
+};
|
|
|
|
|
|
- const addDictItem = () => {
|
|
|
- formData.dictItems.push({
|
|
|
- value: '',
|
|
|
- code: '',
|
|
|
- sortOrder: 5,
|
|
|
- iconFile: null,
|
|
|
- });
|
|
|
- };
|
|
|
+// 图片上传相关
|
|
|
+const dialogImageUrl = ref('');
|
|
|
+const dialogVisible = ref(false);
|
|
|
+
|
|
|
+const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|
|
+ dialogImageUrl.value = uploadFile.url!;
|
|
|
+ dialogVisible.value = true;
|
|
|
+};
|
|
|
+
|
|
|
+const handleRemove = (itemIndex: number) => {
|
|
|
+ if (formData.sysDictDataList[itemIndex]) {
|
|
|
+ // formData.sysDictDataList[itemIndex].iconFile = null;
|
|
|
+ formData.sysDictDataList[itemIndex].imageUrl = ''; // 如果有单独的 URL 字段
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- const removeDictItem = (index: number) => {
|
|
|
- formData.dictItems.splice(index, 1);
|
|
|
- };
|
|
|
+const handleChange = (uploadFile: UploadUserFile, uploadFiles: UploadUserFile[], itemIndex: number) => {
|
|
|
+ // Element Plus 的 onChange 会在文件状态改变时触发多次,通常在 ready 状态时文件已可选
|
|
|
+ // 这里简单地将文件对象存起来,实际上传应在 handleSubmit 中处理
|
|
|
+ if (formData.sysDictDataList[itemIndex]) {
|
|
|
+ // formData.sysDictDataList[itemIndex].iconFile = uploadFile;
|
|
|
+ // console.log('uploadFile:', uploadFile);
|
|
|
+ // uploadPresetImageApi(uploadFile.raw, 'CAMERA_IMAGE').then((res) => {
|
|
|
+ // // formData.sysDictDataList[itemIndex].imageUrl = res.data;
|
|
|
+ // })
|
|
|
+ }
|
|
|
+};
|
|
|
|
|
|
- // 图片上传相关
|
|
|
- const dialogImageUrl = ref('');
|
|
|
- const dialogVisible = ref(false);
|
|
|
+const handleUpload = (res: any) => {
|
|
|
+ console.log('res:', res)
|
|
|
+};
|
|
|
|
|
|
- const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
|
|
|
- dialogImageUrl.value = uploadFile.url!;
|
|
|
- dialogVisible.value = true;
|
|
|
- };
|
|
|
+const handleSubmit = async () => {
|
|
|
+ if (!formRef.value) return;
|
|
|
|
|
|
- const handleRemove = (itemIndex: number) => {
|
|
|
- if (formData.dictItems[itemIndex]) {
|
|
|
- formData.dictItems[itemIndex].iconFile = null;
|
|
|
- formData.dictItems[itemIndex].iconUrl = ''; // 如果有单独的 URL 字段
|
|
|
- }
|
|
|
- };
|
|
|
+ await formRef.value.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ // 在这里处理实际的文件上传逻辑,例如使用 FormData
|
|
|
+ // const submissionData = new FormData();
|
|
|
+ // Object.keys(formData).forEach(key => {
|
|
|
+ // if (key === 'sysDictDataList') {
|
|
|
+ // formData.sysDictDataList.forEach((item, index) => {
|
|
|
+ // submissionData.append(`sysDictDataList[${index}][value]`, item.value);
|
|
|
+ // submissionData.append(`sysDictDataList[${index}][code]`, item.code);
|
|
|
+ // submissionData.append(`sysDictDataList[${index}][sortOrder]`, String(item.sortOrder));
|
|
|
+ // if (item.iconFile && item.iconFile.raw) {
|
|
|
+ // submissionData.append(`sysDictDataList[${index}][icon]`, item.iconFile.raw);
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ // } else {
|
|
|
+ // submissionData.append(key, formData[key as keyof Omit<FormData, 'sysDictDataList'>]);
|
|
|
+ // }
|
|
|
+ // });
|
|
|
+ // emit('submit', submissionData);
|
|
|
+ formData.sysDictDataList.forEach(item => {
|
|
|
+ item.dictCode = formData.dictCode;
|
|
|
+ });
|
|
|
+
|
|
|
+ emit('submit', JSON.parse(JSON.stringify(formData))); // 暂时发送原始数据,上传需单独处理
|
|
|
+ } else {
|
|
|
|
|
|
- const handleChange = (uploadFile: UploadUserFile, uploadFiles: UploadUserFile[], itemIndex: number) => {
|
|
|
- // Element Plus 的 onChange 会在文件状态改变时触发多次,通常在 ready 状态时文件已可选
|
|
|
- // 这里简单地将文件对象存起来,实际上传应在 handleSubmit 中处理
|
|
|
- if (formData.dictItems[itemIndex]) {
|
|
|
- formData.dictItems[itemIndex].iconFile = uploadFile;
|
|
|
+ return false;
|
|
|
}
|
|
|
- };
|
|
|
-
|
|
|
- const handleSubmit = async () => {
|
|
|
- if (!formRef.value) return;
|
|
|
- await formRef.value.validate((valid) => {
|
|
|
- if (valid) {
|
|
|
- // 在这里处理实际的文件上传逻辑,例如使用 FormData
|
|
|
- // const submissionData = new FormData();
|
|
|
- // Object.keys(formData).forEach(key => {
|
|
|
- // if (key === 'dictItems') {
|
|
|
- // formData.dictItems.forEach((item, index) => {
|
|
|
- // submissionData.append(`dictItems[${index}][value]`, item.value);
|
|
|
- // submissionData.append(`dictItems[${index}][code]`, item.code);
|
|
|
- // submissionData.append(`dictItems[${index}][sortOrder]`, String(item.sortOrder));
|
|
|
- // if (item.iconFile && item.iconFile.raw) {
|
|
|
- // submissionData.append(`dictItems[${index}][icon]`, item.iconFile.raw);
|
|
|
- // }
|
|
|
- // });
|
|
|
- // } else {
|
|
|
- // submissionData.append(key, formData[key as keyof Omit<FormData, 'dictItems'>]);
|
|
|
- // }
|
|
|
- // });
|
|
|
- // emit('submit', submissionData);
|
|
|
- emit('submit', JSON.parse(JSON.stringify(formData))); // 暂时发送原始数据,上传需单独处理
|
|
|
- } else {
|
|
|
- console.log('error submit!');
|
|
|
- return false;
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
-
|
|
|
- const handleCancel = () => {
|
|
|
- emit('close');
|
|
|
- };
|
|
|
-
|
|
|
- // 暴露方法给父组件,例如重置表单
|
|
|
- defineExpose({
|
|
|
- resetForm: () => {
|
|
|
- formRef.value?.resetFields();
|
|
|
- formData.dictItems = [
|
|
|
- {
|
|
|
- value: '',
|
|
|
- code: '',
|
|
|
- sortOrder: 5,
|
|
|
- iconFile: null,
|
|
|
- },
|
|
|
- ];
|
|
|
- },
|
|
|
- getFormData: () => formData, // 允许父组件获取当前表单数据
|
|
|
});
|
|
|
+};
|
|
|
+
|
|
|
+// 移动方法
|
|
|
+const moveDictItem = (index: number, direction: 'up' | 'down') => {
|
|
|
+ const items = formData.sysDictDataList;
|
|
|
+ if (direction === 'up' && index > 0) {
|
|
|
+ // 交换位置
|
|
|
+ [items[index - 1], items[index]] = [items[index], items[index - 1]];
|
|
|
+ } else if (direction === 'down' && index < items.length - 1) {
|
|
|
+ // 交换位置
|
|
|
+ [items[index + 1], items[index]] = [items[index], items[index + 1]];
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据最新位置重新设置排序值
|
|
|
+ items.forEach((item, idx) => {
|
|
|
+ item.itemSort = idx + 1;
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleCancel = () => {
|
|
|
+ emit('close');
|
|
|
+};
|
|
|
+
|
|
|
+// 暴露方法给父组件,例如重置表单
|
|
|
+defineExpose({
|
|
|
+ resetForm: () => {
|
|
|
+ formRef.value?.resetFields();
|
|
|
+ formData.sysDictDataList = [
|
|
|
+ {
|
|
|
+ id: undefined,
|
|
|
+ dictId: undefined,
|
|
|
+ dictCode: '',
|
|
|
+ itemCode: '',
|
|
|
+ itemValue: '',
|
|
|
+ itemSort: 1, // 默认排序值
|
|
|
+ isDefault: 0,
|
|
|
+ status: DictionaryStatus.disabled,
|
|
|
+ imageUrl: '',
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
+ },
|
|
|
+ getFormData: () => formData, // 允许父组件获取当前表单数据
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
- .add-dict-form {
|
|
|
- .el-select,
|
|
|
- .el-input-number {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
+.add-dict-form {
|
|
|
+
|
|
|
+ .el-select,
|
|
|
+ .el-input-number {
|
|
|
+ width: 100%;
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+.dict-item-group {
|
|
|
+ padding: 15px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .dict-item-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
|
|
|
- .dict-item-group {
|
|
|
- padding: 15px;
|
|
|
- border: 1px solid #dcdfe6;
|
|
|
- border-radius: 4px;
|
|
|
- margin-bottom: 20px;
|
|
|
- position: relative;
|
|
|
-
|
|
|
- .dict-item-header {
|
|
|
- display: flex;
|
|
|
- justify-content: flex-end;
|
|
|
- align-items: center;
|
|
|
- margin-bottom: 10px;
|
|
|
-
|
|
|
- h4 {
|
|
|
- margin: 0;
|
|
|
- font-size: 16px;
|
|
|
- }
|
|
|
+ h4 {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 16px;
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+.form-footer {
|
|
|
+ text-align: right;
|
|
|
+ margin-top: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+// 覆盖 el-upload 的样式,使其适应小图标场景
|
|
|
+:deep(.el-upload--picture-card) {
|
|
|
+ width: 100px;
|
|
|
+ height: 100px;
|
|
|
+ line-height: 110px;
|
|
|
+}
|
|
|
|
|
|
- .form-footer {
|
|
|
+:deep(.el-upload-list--picture-card .el-upload-list__item) {
|
|
|
+ width: 100px;
|
|
|
+ height: 100px;
|
|
|
+}
|
|
|
+
|
|
|
+.subDictWrapper {
|
|
|
+ display: flex;
|
|
|
+
|
|
|
+ .dictItemsLabel {
|
|
|
+ width: 30%;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
text-align: right;
|
|
|
- margin-top: 20px;
|
|
|
+ margin-right: 26px;
|
|
|
}
|
|
|
|
|
|
- // 覆盖 el-upload 的样式,使其适应小图标场景
|
|
|
- :deep(.el-upload--picture-card) {
|
|
|
- width: 100px;
|
|
|
- height: 100px;
|
|
|
- line-height: 110px;
|
|
|
- }
|
|
|
- :deep(.el-upload-list--picture-card .el-upload-list__item) {
|
|
|
- width: 100px;
|
|
|
- height: 100px;
|
|
|
+ .subDictList {
|
|
|
+ flex: 1;
|
|
|
}
|
|
|
- .subDictWrapper {
|
|
|
- display: flex;
|
|
|
- .dictItemsLabel {
|
|
|
- width: 30%;
|
|
|
- font-size: 14px;
|
|
|
- color: #606266;
|
|
|
- text-align: right;
|
|
|
- margin-right: 26px;
|
|
|
- }
|
|
|
- .subDictList {
|
|
|
- flex: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.dict-item-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 10px;
|
|
|
+
|
|
|
+ .move-buttons {
|
|
|
+ margin-right: auto;
|
|
|
+ .el-button {
|
|
|
+ padding: 5px;
|
|
|
+ margin-right: 8px;
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+.dialog-content {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ img {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+}
|
|
|
</style>
|