|
@@ -27,28 +27,19 @@
|
|
|
<!-- 移动按钮 -->
|
|
<!-- 移动按钮 -->
|
|
|
<div class="dict-item-header">
|
|
<div class="dict-item-header">
|
|
|
<div class="move-buttons">
|
|
<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
|
|
|
|
|
|
|
+ <MoveButton v-if="index > 0" type="up" @move="moveDictItem(index, $event)" />
|
|
|
|
|
+ <MoveButton
|
|
|
v-if="index < formData.sysDictDataList.length - 1"
|
|
v-if="index < formData.sysDictDataList.length - 1"
|
|
|
- type="primary"
|
|
|
|
|
- link
|
|
|
|
|
- @click="moveDictItem(index, 'down')"
|
|
|
|
|
- >
|
|
|
|
|
- <el-icon>
|
|
|
|
|
- <Bottom />
|
|
|
|
|
- </el-icon>
|
|
|
|
|
- </el-button>
|
|
|
|
|
|
|
+ type="down"
|
|
|
|
|
+ @move="moveDictItem(index, $event)"
|
|
|
|
|
+ />
|
|
|
<el-button
|
|
<el-button
|
|
|
v-if="formData.sysDictDataList.length > 1"
|
|
v-if="formData.sysDictDataList.length > 1"
|
|
|
- type="danger"
|
|
|
|
|
link
|
|
link
|
|
|
|
|
+ class="delete-botton"
|
|
|
@click="removeDictItem(index)"
|
|
@click="removeDictItem(index)"
|
|
|
>
|
|
>
|
|
|
- <el-icon> <Delete /> </el-icon>删除
|
|
|
|
|
|
|
+ <el-icon><Delete /></el-icon>
|
|
|
</el-button>
|
|
</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
@@ -68,18 +59,45 @@
|
|
|
<el-input v-model="item.itemCode" placeholder="请输入" />
|
|
<el-input v-model="item.itemCode" placeholder="请输入" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
<el-form-item label="图标">
|
|
<el-form-item label="图标">
|
|
|
- <el-upload
|
|
|
|
|
|
|
+ <!-- // 在模板部分修改上传组件的ref绑定 -->
|
|
|
|
|
+ <!-- <el-upload
|
|
|
|
|
+ :ref="(el) => setUploadRef(index, el)"
|
|
|
v-model:file-list="item.fileList"
|
|
v-model:file-list="item.fileList"
|
|
|
:auto-upload="false"
|
|
:auto-upload="false"
|
|
|
list-type="picture-card"
|
|
list-type="picture-card"
|
|
|
:limit="1"
|
|
:limit="1"
|
|
|
- :on-preview="(file) => handlePictureCardPreview(file, index)"
|
|
|
|
|
|
|
+ :on-preview="(file) => handlePictureCardPreview(file)"
|
|
|
:on-remove="() => handleRemove(index)"
|
|
:on-remove="() => handleRemove(index)"
|
|
|
:on-change="(file) => handleChange(file, index)"
|
|
:on-change="(file) => handleChange(file, index)"
|
|
|
|
|
+ :on-exceed="(files) => handleExceed(files, index)"
|
|
|
>
|
|
>
|
|
|
<el-icon>
|
|
<el-icon>
|
|
|
<Plus />
|
|
<Plus />
|
|
|
</el-icon>
|
|
</el-icon>
|
|
|
|
|
+ </el-upload> -->
|
|
|
|
|
+ <el-upload
|
|
|
|
|
+ :ref="(el) => setUploadRef(index, el)"
|
|
|
|
|
+ v-model:file-list="item.fileList"
|
|
|
|
|
+ :auto-upload="false"
|
|
|
|
|
+ list-type="picture-card"
|
|
|
|
|
+ :limit="1"
|
|
|
|
|
+ :on-change="(file) => handleChange(file, index)"
|
|
|
|
|
+ :on-exceed="(files) => handleExceed(files, index)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-icon><Plus /></el-icon>
|
|
|
|
|
+ <template #file="{ file }">
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
|
|
|
|
|
+ <span class="el-upload-list__item-actions">
|
|
|
|
|
+ <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
|
|
|
|
|
+ <el-icon><zoom-in /></el-icon>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ <span class="el-upload-list__item-delete" @click="handleRemove(index)">
|
|
|
|
|
+ <el-icon><Delete /></el-icon>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
</el-upload>
|
|
</el-upload>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</div>
|
|
</div>
|
|
@@ -89,10 +107,10 @@
|
|
|
|
|
|
|
|
<el-form-item>
|
|
<el-form-item>
|
|
|
<el-button type="primary" link @click="addDictItem">
|
|
<el-button type="primary" link @click="addDictItem">
|
|
|
- <el-icon>
|
|
|
|
|
|
|
+ <el-icon :size="16">
|
|
|
<CirclePlus />
|
|
<CirclePlus />
|
|
|
</el-icon>
|
|
</el-icon>
|
|
|
- 新增字典分类
|
|
|
|
|
|
|
+ <span class="add-text">新增</span>
|
|
|
</el-button>
|
|
</el-button>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
@@ -115,14 +133,14 @@
|
|
|
</el-radio-group>
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
- <el-form-item class="form-footer">
|
|
|
|
|
|
|
+ <div class="form-footer">
|
|
|
<el-button @click="handleCancel">取消</el-button>
|
|
<el-button @click="handleCancel">取消</el-button>
|
|
|
<el-button type="primary" @click="handleSubmit">提交</el-button>
|
|
<el-button type="primary" @click="handleSubmit">提交</el-button>
|
|
|
- </el-form-item>
|
|
|
|
|
|
|
+ </div>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
</el-drawer>
|
|
</el-drawer>
|
|
|
|
|
|
|
|
- <el-dialog v-model="dialogVisible">
|
|
|
|
|
|
|
+ <el-dialog v-model="dialogVisible" width="30%">
|
|
|
<div class="dialog-content">
|
|
<div class="dialog-content">
|
|
|
<img :src="dialogImageUrl" alt="Preview Image" />
|
|
<img :src="dialogImageUrl" alt="Preview Image" />
|
|
|
</div>
|
|
</div>
|
|
@@ -147,12 +165,17 @@
|
|
|
FormRules,
|
|
FormRules,
|
|
|
UploadProps,
|
|
UploadProps,
|
|
|
UploadUserFile,
|
|
UploadUserFile,
|
|
|
|
|
+ UploadInstance,
|
|
|
|
|
+ UploadRawFile,
|
|
|
|
|
+ genFileId,
|
|
|
|
|
+ ElMessage,
|
|
|
} from 'element-plus';
|
|
} from 'element-plus';
|
|
|
- import { Plus, Delete, CirclePlus, Top, Bottom } from '@element-plus/icons-vue';
|
|
|
|
|
|
|
+ import { Plus, Delete, CirclePlus, ZoomIn } from '@element-plus/icons-vue';
|
|
|
import { dictionaryTypeOptions, DictionaryStatus, dictionaryStatusOptions } from '../constants';
|
|
import { dictionaryTypeOptions, DictionaryStatus, dictionaryStatusOptions } from '../constants';
|
|
|
import { queryDictTypeDetail } from '@/api/dict';
|
|
import { queryDictTypeDetail } from '@/api/dict';
|
|
|
import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
|
|
import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
|
|
|
import { cloneDeep } from 'lodash-es';
|
|
import { cloneDeep } from 'lodash-es';
|
|
|
|
|
+ import MoveButton from './MoveButton.vue';
|
|
|
|
|
|
|
|
interface SysDictDataItem {
|
|
interface SysDictDataItem {
|
|
|
id?: string | number; // 可选,用于编辑时
|
|
id?: string | number; // 可选,用于编辑时
|
|
@@ -282,6 +305,7 @@
|
|
|
const handleRemove = (itemIndex: number) => {
|
|
const handleRemove = (itemIndex: number) => {
|
|
|
if (formData.sysDictDataList[itemIndex]) {
|
|
if (formData.sysDictDataList[itemIndex]) {
|
|
|
formData.sysDictDataList[itemIndex].imageUrl = ''; // 如果有单独的 URL 字段
|
|
formData.sysDictDataList[itemIndex].imageUrl = ''; // 如果有单独的 URL 字段
|
|
|
|
|
+ formData.sysDictDataList[itemIndex].fileList = [];
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -301,6 +325,26 @@
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ // 添加上传组件引用数组
|
|
|
|
|
+ const uploadRefs = ref<UploadInstance[]>([]);
|
|
|
|
|
+ const setUploadRef = (index: number, el: any) => {
|
|
|
|
|
+ uploadRefs.value[index] = el;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 修改handleExceed方法
|
|
|
|
|
+ const handleExceed: UploadProps['onExceed'] = (files: File[], index: number) => {
|
|
|
|
|
+ const uploadInstance = uploadRefs.value[index];
|
|
|
|
|
+ if (!uploadInstance) return;
|
|
|
|
|
+
|
|
|
|
|
+ // 清空当前实例的文件
|
|
|
|
|
+ uploadInstance.clearFiles();
|
|
|
|
|
+
|
|
|
|
|
+ // 添加新文件
|
|
|
|
|
+ const file = files[0] as UploadRawFile;
|
|
|
|
|
+ file.uid = genFileId();
|
|
|
|
|
+ uploadInstance.handleStart(file);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
const handleSubmit = async () => {
|
|
const handleSubmit = async () => {
|
|
|
if (!formRef.value) return;
|
|
if (!formRef.value) return;
|
|
|
|
|
|
|
@@ -320,6 +364,15 @@
|
|
|
});
|
|
});
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+ const hoverState = reactive({
|
|
|
|
|
+ up: false,
|
|
|
|
|
+ down: false,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const handleHover = (event: Event, type: 'up' | 'down', isEnter = true) => {
|
|
|
|
|
+ hoverState[type] = isEnter;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
// 移动方法
|
|
// 移动方法
|
|
|
const moveDictItem = (index: number, direction: 'up' | 'down') => {
|
|
const moveDictItem = (index: number, direction: 'up' | 'down') => {
|
|
|
const items = formData.sysDictDataList;
|
|
const items = formData.sysDictDataList;
|
|
@@ -365,6 +418,7 @@
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
|
.add-dict-form {
|
|
.add-dict-form {
|
|
|
|
|
+ // padding-bottom: 40px;
|
|
|
.el-select,
|
|
.el-select,
|
|
|
.el-input-number {
|
|
.el-input-number {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
@@ -373,9 +427,9 @@
|
|
|
|
|
|
|
|
.dict-item-group {
|
|
.dict-item-group {
|
|
|
padding: 15px;
|
|
padding: 15px;
|
|
|
- border: 1px solid #dcdfe6;
|
|
|
|
|
border-radius: 4px;
|
|
border-radius: 4px;
|
|
|
margin-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
|
|
|
+ background-color: #f0f2f5;
|
|
|
position: relative;
|
|
position: relative;
|
|
|
|
|
|
|
|
.dict-item-header {
|
|
.dict-item-header {
|
|
@@ -392,8 +446,22 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.form-footer {
|
|
.form-footer {
|
|
|
|
|
+ position: sticky;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ background: white;
|
|
|
|
|
+ padding: 20px 0;
|
|
|
|
|
+ z-index: 100;
|
|
|
|
|
+ box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.06);
|
|
|
text-align: right;
|
|
text-align: right;
|
|
|
- margin-top: 20px;
|
|
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .add-dict-form {
|
|
|
|
|
+ height: calc(100vh - 120px); // 根据实际抽屉高度调整
|
|
|
|
|
+ overflow-y: auto;
|
|
|
|
|
+ .el-select,
|
|
|
|
|
+ .el-input-number {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 覆盖 el-upload 的样式,使其适应小图标场景
|
|
// 覆盖 el-upload 的样式,使其适应小图标场景
|
|
@@ -425,27 +493,32 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.dict-item-header {
|
|
.dict-item-header {
|
|
|
- display: flex;
|
|
|
|
|
- justify-content: flex-end;
|
|
|
|
|
- align-items: center;
|
|
|
|
|
margin-bottom: 10px;
|
|
margin-bottom: 10px;
|
|
|
|
|
|
|
|
.move-buttons {
|
|
.move-buttons {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ justify-content: end;
|
|
|
|
|
+ width: 100%;
|
|
|
margin-right: auto;
|
|
margin-right: auto;
|
|
|
.el-button {
|
|
.el-button {
|
|
|
padding: 5px;
|
|
padding: 5px;
|
|
|
- margin-right: 8px;
|
|
|
|
|
|
|
+ // margin-right: 8px;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.dialog-content {
|
|
.dialog-content {
|
|
|
- width: 100%;
|
|
|
|
|
- height: 100%;
|
|
|
|
|
|
|
+ // width: 600px;
|
|
|
|
|
+ // height: 600px;
|
|
|
|
|
|
|
|
img {
|
|
img {
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
height: 100%;
|
|
height: 100%;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .add-text {
|
|
|
|
|
+ margin-left: 10px;
|
|
|
|
|
+ }
|
|
|
</style>
|
|
</style>
|