763 lines
26 KiB
Vue
763 lines
26 KiB
Vue
<template>
|
||
<div>
|
||
<!-- 调试信息 -->
|
||
<div style="margin-bottom: 20px; padding: 15px; background: #f5f7fa; border-radius: 8px;">
|
||
<el-button size="small" @click="showDebugInfo">查看调试信息</el-button>
|
||
<el-button size="small" @click="showRawData">查看原始数据</el-button>
|
||
<el-button size="small" type="primary" @click="testTreeStructure">测试树形结构</el-button>
|
||
<el-button size="small" type="success" @click="getCategories">重新加载数据</el-button>
|
||
<span style="margin-left: 20px; color: #666;">
|
||
数据总数: {{ tableData.length }} |
|
||
树形层级: {{ getMaxLevel() }}级
|
||
</span>
|
||
</div>
|
||
|
||
<el-table :data="tableData" style="width: 100%;margin-bottom: 20px;" row-key="id" border v-loading="loading"
|
||
element-loading-text="加载中..." element-loading-spinner="el-icon-loading"
|
||
:tree-props="{ children: 'children' }" :default-expand-all="false" :expand-on-click-node="false">
|
||
<el-table-column prop="name" label="名称" min-width="120">
|
||
</el-table-column>
|
||
<el-table-column prop="id" label="id" min-width="200">
|
||
</el-table-column>
|
||
<el-table-column prop="level" label="层级" min-width="120">
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="280" fixed="right">
|
||
<template slot-scope="scope">
|
||
<el-button type="text" size="small" @click="addNode(scope.row, 'sibling')">新增同级</el-button>
|
||
<el-button type="text" size="small" @click="addNode(scope.row, 'child')">新增子级</el-button>
|
||
<el-button type="text" size="small" @click="editNode(scope.row)">编辑</el-button>
|
||
<el-button type="text" size="small" @click="deleteNode(scope.row)"
|
||
style="color: #F56C6C;">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
|
||
<el-drawer title="菜单管理" :visible.sync="drawer" :direction="direction">
|
||
|
||
<div style="margin: 20px;"></div>
|
||
<el-form style="margin: 10px;" :label-position="labelPosition" label-width="100px" :model="formLabelAlign" :rules="formRules" ref="menuForm">
|
||
<el-form-item label="菜单名称" prop="name">
|
||
<el-input v-model="formLabelAlign.name" placeholder="请输入菜单名称"></el-input>
|
||
</el-form-item>
|
||
<el-form-item v-if="!formLabelAlign.parentid" label="菜单图标" prop="icon">
|
||
<div class="icon-upload-container">
|
||
<!-- 图片预览区域 -->
|
||
<div v-if="formLabelAlign.icon" class="icon-preview">
|
||
<div class="preview-wrapper">
|
||
<!-- SVG图片显示 -->
|
||
<img v-if="isSvgImage(formLabelAlign.icon)"
|
||
:src="formLabelAlign.icon"
|
||
class="preview-image svg-image"
|
||
alt="菜单图标">
|
||
<!-- 普通图片显示 -->
|
||
<img v-else
|
||
:src="formLabelAlign.icon"
|
||
class="preview-image"
|
||
alt="菜单图标">
|
||
<div class="preview-actions">
|
||
<el-button type="text" size="mini" @click="removeIcon" icon="el-icon-delete" style="color: #F56C6C;">删除</el-button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 上传组件 -->
|
||
<el-upload
|
||
v-if="!formLabelAlign.icon"
|
||
class="icon-uploader"
|
||
action="#"
|
||
:http-request="handleIconUpload"
|
||
:show-file-list="false"
|
||
:before-upload="beforeIconUpload"
|
||
accept=".svg,.png,.jpg"
|
||
drag>
|
||
<i class="el-icon-plus uploader-icon"></i>
|
||
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||
<!-- <div class="el-upload__tip" slot="tip">
|
||
<i class="el-icon-info"></i>
|
||
支持 SVG、PNG、JPG格式,文件大小不超过 5MB
|
||
</div> -->
|
||
</el-upload>
|
||
</div>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="菜单排序" style="margin-top: 10px!important;" prop="poriority">
|
||
<el-input-number :controls="false" v-model="formLabelAlign.poriority" :step="1" :min="0" :max="100" placeholder="请输入排序值"></el-input-number>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="菜单来源" prop="source">
|
||
<el-input v-model="formLabelAlign.source" placeholder="请输入菜单来源"></el-input>
|
||
</el-form-item>
|
||
|
||
<!-- 操作按钮 -->
|
||
<el-form-item>
|
||
<el-button type="primary" @click="submitForm">{{ isEdit ? '保存' : '新增' }}</el-button>
|
||
<el-button @click="resetForm">重置</el-button>
|
||
<el-button @click="drawer = false">取消</el-button>
|
||
</el-form-item>
|
||
|
||
|
||
</el-form>
|
||
</el-drawer>
|
||
|
||
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import { reqNcMatchMenu,reqAddProductMenu,reqHomepageCategoryTreeUpdate,reqHomepageCategoryTreeDelete } from '@/api/ncmatch';
|
||
export default {
|
||
name: 'menuMangement',
|
||
data() {
|
||
return {
|
||
loading: false,
|
||
categories: [],
|
||
tableData: [], // 移除硬编码的测试数据
|
||
drawer: false,
|
||
direction: 'rtl',
|
||
labelPosition: 'right',
|
||
|
||
isEdit: false,
|
||
formLabelAlign: {
|
||
name: '',
|
||
icon: '',
|
||
iconFile: null, // 存储二进制文件对象
|
||
url_link: '',
|
||
parentid: '',
|
||
poriority: '',
|
||
source: '',
|
||
},
|
||
formRules: {
|
||
name: [
|
||
{ required: true, message: '请输入菜单名称', trigger: 'blur' }
|
||
],
|
||
poriority: [
|
||
{ required: true, message: '请输入菜单排序', trigger: 'blur' }
|
||
]
|
||
}
|
||
}
|
||
},
|
||
created() {
|
||
this.getCategories();
|
||
},
|
||
methods: {
|
||
// 处理图标上传
|
||
handleIconUpload(options) {
|
||
const file = options.file;
|
||
console.log('上传文件:', file);
|
||
|
||
// 创建本地预览URL
|
||
const reader = new FileReader();
|
||
reader.onload = (e) => {
|
||
this.formLabelAlign.icon = e.target.result;
|
||
this.$message.success('图片上传成功!');
|
||
};
|
||
reader.readAsDataURL(file);
|
||
|
||
// 保存文件对象到表单数据中,用于后续提交
|
||
this.formLabelAlign.iconFile = file;
|
||
},
|
||
|
||
// 上传前验证
|
||
beforeIconUpload(file) {
|
||
// 检查文件类型
|
||
const isValidType = this.isValidImageType(file.type);
|
||
if (!isValidType) {
|
||
this.$message.error('只支持 SVG、PNG、JPG格式的图片!');
|
||
return false;
|
||
}
|
||
|
||
// 检查文件大小 (5MB)
|
||
const isLt5M = file.size / 1024 / 1024 < 5;
|
||
if (!isLt5M) {
|
||
this.$message.error('图片大小不能超过 5MB!');
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
},
|
||
|
||
// 验证图片类型
|
||
isValidImageType(type) {
|
||
const validTypes = [
|
||
'image/svg+xml',
|
||
'image/png',
|
||
'image/jpeg',
|
||
'image/jpg',
|
||
'image/gif',
|
||
'image/webp'
|
||
];
|
||
return validTypes.includes(type);
|
||
},
|
||
|
||
// 判断是否为SVG图片
|
||
isSvgImage(src) {
|
||
return src && (src.includes('.svg') || src.startsWith('data:image/svg+xml'));
|
||
},
|
||
|
||
// 删除图标
|
||
removeIcon() {
|
||
this.$confirm('确定要删除这个图标吗?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
this.formLabelAlign.icon = '';
|
||
this.formLabelAlign.iconFile = null;
|
||
this.$message.success('图标已删除');
|
||
}).catch(() => {});
|
||
},
|
||
|
||
// 提交表单(区分新增与保存)
|
||
submitForm() {
|
||
// reqHomepageCategoryTreeUpdate({id:row.id,name:row.name,poriority:row.poriority,source:row.source,url_link:window.location.href}).then(res=>{
|
||
// if(res.status){
|
||
// this.$message.success('编辑成功!');
|
||
// this.getCategories();
|
||
// }else{
|
||
// this.$message.error(res.msg);
|
||
// }
|
||
// })
|
||
this.$refs.menuForm.validate((valid) => {
|
||
if (valid) {
|
||
// 创建FormData对象
|
||
const formData = new FormData();
|
||
|
||
// 添加基本表单数据
|
||
formData.append('name', this.formLabelAlign.name);
|
||
formData.append('poriority', this.formLabelAlign.poriority);
|
||
formData.append('source', this.formLabelAlign.source);
|
||
formData.append('url_link', window.location.href);
|
||
|
||
// 只有当parentid为null时才传递图片
|
||
if (!this.formLabelAlign.parentid || this.formLabelAlign.parentid === '' || this.formLabelAlign.parentid === '0') {
|
||
if (this.formLabelAlign.iconFile) {
|
||
formData.append('icon', this.formLabelAlign.iconFile);
|
||
console.log('包含图片上传');
|
||
} else if (this.formLabelAlign.icon) {
|
||
// 如果有现有图片URL,也传递
|
||
formData.append('iconUrl', this.formLabelAlign.icon);
|
||
console.log('包含现有图片URL');
|
||
}
|
||
} else {
|
||
console.log('跳过图片上传,parentid不为null');
|
||
}
|
||
|
||
// 添加parentid
|
||
if (this.formLabelAlign.parentid) {
|
||
formData.append('parentid', this.formLabelAlign.parentid);
|
||
}
|
||
|
||
// 打印FormData内容(调试用)
|
||
for (let [key, value] of formData.entries()) {
|
||
console.log(`${key}:`, value);
|
||
}
|
||
|
||
// 这里调用API保存数据(根据 isEdit 区分)
|
||
if (this.isEdit) {
|
||
this.updateMenuData({
|
||
id: this.formLabelAlign.id,
|
||
name: this.formLabelAlign.name,
|
||
poriority: this.formLabelAlign.poriority,
|
||
source: this.formLabelAlign.source,
|
||
parentid: this.formLabelAlign.parentid,
|
||
url_link: window.location.href,
|
||
// 如果是顶级并且未改图标,不传 icon 字段
|
||
// 图标更新仅在新增或更换图片时通过另一路径处理
|
||
})
|
||
} else {
|
||
this.saveMenuData(formData);
|
||
}
|
||
} else {
|
||
this.$message.error('请检查表单信息!');
|
||
return false;
|
||
}
|
||
});
|
||
},
|
||
|
||
// 新增菜单数据
|
||
saveMenuData(formData) {
|
||
// 这里添加实际的API调用
|
||
// 例如:
|
||
reqAddProductMenu(formData).then(res => {
|
||
if (res.status) {
|
||
this.$message.success('保存成功!');
|
||
this.drawer = false;
|
||
this.getCategories(); // 刷新数据
|
||
}else{
|
||
this.$message.error(res.msg);
|
||
}
|
||
}).catch(error => {
|
||
this.$message.error('保存失败:' + error.message);
|
||
});
|
||
|
||
// // 临时模拟成功
|
||
// this.$message.success('保存成功!');
|
||
// this.drawer = false;
|
||
// console.log('FormData数据已准备就绪,可以发送到服务器');
|
||
},
|
||
|
||
// 保存(编辑)菜单数据(非文件字段)
|
||
updateMenuData(payload) {
|
||
reqHomepageCategoryTreeUpdate(payload).then(res => {
|
||
if (res.status) {
|
||
this.$message.success('保存成功!');
|
||
this.drawer = false;
|
||
this.getCategories();
|
||
} else {
|
||
this.$message.error(res.msg);
|
||
}
|
||
}).catch(error => {
|
||
this.$message.error('保存失败:' + error.message);
|
||
})
|
||
},
|
||
|
||
// 重置表单
|
||
resetForm() {
|
||
this.$refs.menuForm.resetFields();
|
||
this.formLabelAlign.icon = '';
|
||
this.formLabelAlign.iconFile = null;
|
||
},
|
||
addNode(row, type) {
|
||
this.drawer = true;
|
||
this.resetForm();
|
||
this.isEdit = false;
|
||
if (type === 'child') {
|
||
this.formLabelAlign.parentid = row.id;
|
||
} else if (type === 'sibling') {
|
||
this.formLabelAlign.parentid = row.parentid;
|
||
}
|
||
console.log('新增节点:', row, '类型:', type);
|
||
},
|
||
getCategories() {
|
||
this.loading = true;
|
||
reqNcMatchMenu({ url_link: window.location.href }).then(res => {
|
||
this.loading = false;
|
||
if (res.status) {
|
||
this.categories = this.buildSimpleTree(res.data);
|
||
this.tableData = this.categories; // 使用精简的树形结构
|
||
console.log("构建的精简树结构:", this.categories);
|
||
}
|
||
}).catch(error => {
|
||
this.loading = false;
|
||
console.error('获取菜单数据失败:', error);
|
||
});
|
||
},
|
||
editNode(row) {
|
||
this.drawer = true;
|
||
this.formLabelAlign = { ...row };
|
||
// 编辑时清除iconFile,避免重复上传
|
||
this.formLabelAlign.iconFile = null;
|
||
this.isEdit = true;
|
||
|
||
|
||
},
|
||
deleteNode(row) {
|
||
|
||
reqHomepageCategoryTreeDelete({id:row.id}).then(res=>{
|
||
if(res.status){
|
||
this.$message.success('删除成功!');
|
||
this.getCategories();
|
||
|
||
}else{
|
||
this.$message.error(res.msg);
|
||
}
|
||
})
|
||
|
||
},
|
||
buildTree(data, parentId = null) {
|
||
if (!Array.isArray(data)) {
|
||
console.log('数据不是数组:', data);
|
||
return [];
|
||
}
|
||
|
||
console.log('构建树结构,当前parentId:', parentId, '数据长度:', data.length);
|
||
|
||
// 找出当前层级的节点
|
||
const currentNodes = data.filter(item => {
|
||
// 处理顶级节点(parentid 为 null 或空字符串)
|
||
if (parentId === null) {
|
||
return !item.parentid || item.parentid === '' || item.parentid === '0';
|
||
}
|
||
return item.parentid === parentId;
|
||
});
|
||
|
||
console.log('当前层级节点数量:', currentNodes.length, '节点:', currentNodes);
|
||
|
||
if (currentNodes.length === 0) return [];
|
||
|
||
// 处理每个节点
|
||
return currentNodes.map(node => {
|
||
const resultNode = {
|
||
id: node.id,
|
||
name: node.name || '未命名',
|
||
parentid: node.parentid
|
||
};
|
||
|
||
// 递归处理子节点
|
||
const children = this.buildSimpleTree(data, node.id);
|
||
|
||
// 只有当有子节点时才添加 children 字段
|
||
if (children && children.length > 0) {
|
||
resultNode.children = children;
|
||
}
|
||
|
||
return resultNode;
|
||
});
|
||
},
|
||
|
||
// 精简的树形结构构建方法
|
||
buildSimpleTree(data, parentId = null) {
|
||
if (!Array.isArray(data)) {
|
||
return [];
|
||
}
|
||
|
||
// 找出当前层级的节点
|
||
const currentNodes = data.filter(item => {
|
||
if (parentId === null) {
|
||
return !item.parentid || item.parentid === '' || item.parentid === '0';
|
||
}
|
||
return item.parentid === parentId;
|
||
});
|
||
|
||
if (currentNodes.length === 0) return [];
|
||
|
||
// 处理每个节点,只保留必要字段
|
||
return currentNodes.map(node => {
|
||
const resultNode = {
|
||
id: node.id,
|
||
name: node.name || '未命名',
|
||
parentid: node.parentid
|
||
};
|
||
|
||
// 递归处理子节点
|
||
const children = this.buildSimpleTree(data, node.id);
|
||
|
||
// 只有当有子节点时才添加 children 字段
|
||
if (children && children.length > 0) {
|
||
resultNode.children = children;
|
||
}
|
||
|
||
return resultNode;
|
||
});
|
||
},
|
||
|
||
// 计算节点层级
|
||
calculateLevel(data, nodeId) {
|
||
let level = 1;
|
||
let currentId = nodeId;
|
||
|
||
while (true) {
|
||
const parent = data.find(item => item.id === currentId);
|
||
if (!parent || !parent.parentid || parent.parentid === '' || parent.parentid === '0') {
|
||
break;
|
||
}
|
||
level++;
|
||
currentId = parent.parentid;
|
||
}
|
||
|
||
return level;
|
||
},
|
||
showDebugInfo() {
|
||
console.log("当前 tableData 的结构:", this.tableData);
|
||
console.log("当前 tableData 的层级分布:", this.getLevelDistribution());
|
||
console.log("当前 tableData 的最大层级:", this.getMaxLevel());
|
||
|
||
// 检查树形结构
|
||
this.checkTreeStructure(this.tableData);
|
||
},
|
||
|
||
// 检查树形结构
|
||
checkTreeStructure(nodes, level = 0) {
|
||
if (!Array.isArray(nodes)) return;
|
||
|
||
nodes.forEach(node => {
|
||
const indent = ' '.repeat(level);
|
||
console.log(`${indent}📁 ${node.name} (ID: ${node.id})`);
|
||
console.log(`${indent} - hasChildren: ${node.hasChildren}`);
|
||
console.log(`${indent} - children.length: ${node.children ? node.children.length : 'undefined'}`);
|
||
console.log(`${indent} - level: ${node.level}`);
|
||
|
||
if (node.children && node.children.length > 0) {
|
||
this.checkTreeStructure(node.children, level + 1);
|
||
}
|
||
});
|
||
},
|
||
showRawData() {
|
||
console.log("原始数据:", this.categories);
|
||
},
|
||
|
||
// 测试树形结构
|
||
testTreeStructure() {
|
||
const testData = [
|
||
{
|
||
id: 1,
|
||
name: '一级菜单1',
|
||
parentid: null
|
||
},
|
||
{
|
||
id: 2,
|
||
name: '一级菜单2',
|
||
parentid: null
|
||
},
|
||
{
|
||
id: 3,
|
||
name: '一级菜单3',
|
||
parentid: null,
|
||
children: [
|
||
{
|
||
id: 31,
|
||
name: '二级菜单3-1',
|
||
parentid: 3
|
||
},
|
||
{
|
||
id: 32,
|
||
name: '二级菜单3-2',
|
||
parentid: 3,
|
||
children: [
|
||
{
|
||
id: 321,
|
||
name: '三级菜单3-2-1',
|
||
parentid: 32
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
];
|
||
|
||
console.log("精简测试数据:", testData);
|
||
this.tableData = testData;
|
||
},
|
||
getLevelDistribution() {
|
||
const levels = {};
|
||
this.tableData.forEach(node => {
|
||
const level = node.level;
|
||
if (levels[level]) {
|
||
levels[level]++;
|
||
} else {
|
||
levels[level] = 1;
|
||
}
|
||
});
|
||
return levels;
|
||
},
|
||
getMaxLevel() {
|
||
let maxLevel = 0;
|
||
this.tableData.forEach(node => {
|
||
if (node.level > maxLevel) {
|
||
maxLevel = node.level;
|
||
}
|
||
});
|
||
return maxLevel;
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
<style scoped>
|
||
.el-table {
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.el-table th {
|
||
background-color: #f5f7fa;
|
||
color: #606266;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.el-table td {
|
||
padding: 12px 0;
|
||
}
|
||
|
||
.el-button--text {
|
||
padding: 4px 8px;
|
||
margin: 0 2px;
|
||
}
|
||
|
||
.el-button--text:hover {
|
||
background-color: #f5f7fa;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.el-tag {
|
||
border-radius: 4px;
|
||
}
|
||
|
||
/* 树形表格的缩进样式 */
|
||
.el-table__expand-icon {
|
||
margin-right: 8px;
|
||
}
|
||
|
||
/* 加载状态样式 */
|
||
.el-loading-mask {
|
||
background-color: rgba(255, 255, 255, 0.8);
|
||
}
|
||
|
||
|
||
.license-uploader {
|
||
border: 2px dashed #d1d9e0;
|
||
border-radius: 12px;
|
||
cursor: pointer;
|
||
position: relative;
|
||
overflow: hidden;
|
||
width:150px;
|
||
height: 150px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
|
||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||
|
||
&:hover {
|
||
border-color: #667eea;
|
||
background: linear-gradient(135deg, #f0f4ff 0%, #e8f0ff 100%);
|
||
box-shadow: 0 8px 25px rgba(102, 126, 234, 0.2);
|
||
}
|
||
|
||
.license-uploader-icon {
|
||
font-size: 28px;
|
||
color: #667eea;
|
||
width: 100%;
|
||
height: 160px;
|
||
line-height: 160px;
|
||
text-align: center;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.license-image {
|
||
width: 100%;
|
||
height: 160px;
|
||
display: block;
|
||
object-fit: cover;
|
||
border-radius: 8px;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||
}
|
||
}
|
||
|
||
/* 图标上传容器样式 */
|
||
.icon-upload-container {
|
||
width: 100%;
|
||
}
|
||
|
||
/* 图标预览样式 */
|
||
.icon-preview {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.preview-wrapper {
|
||
position: relative;
|
||
display: inline-block;
|
||
border: 2px dashed #d9d9d9;
|
||
border-radius: 8px;
|
||
padding: 10px;
|
||
background: #fafafa;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.preview-wrapper:hover {
|
||
border-color: #409eff;
|
||
background: #f0f9ff;
|
||
}
|
||
|
||
.preview-image {
|
||
max-width: 120px;
|
||
max-height: 120px;
|
||
object-fit: contain;
|
||
border-radius: 4px;
|
||
display: block;
|
||
}
|
||
|
||
.svg-image {
|
||
background: linear-gradient(45deg, #f0f0f0 25%, transparent 25%),
|
||
linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),
|
||
linear-gradient(45deg, transparent 75%, #f0f0f0 75%),
|
||
linear-gradient(-45deg, transparent 75%, #f0f0f0 75%);
|
||
background-size: 20px 20px;
|
||
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
||
}
|
||
|
||
.preview-actions {
|
||
margin-top: 10px;
|
||
text-align: center;
|
||
}
|
||
|
||
.preview-actions .el-button {
|
||
margin: 0 5px;
|
||
}
|
||
|
||
/* 上传组件样式 */
|
||
.icon-uploader {
|
||
width: 150px;
|
||
height: 150px;
|
||
}
|
||
|
||
.icon-uploader .el-upload {
|
||
width: 100%;
|
||
}
|
||
|
||
::v-deep .icon-uploader .el-upload-dragger {
|
||
width: 150px!important;
|
||
height: 150px!important;
|
||
border: 2px dashed #d9d9d9;
|
||
border-radius: 8px;
|
||
background: #fafafa;
|
||
transition: all 0.3s;
|
||
display: flex ;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content:center;
|
||
}
|
||
|
||
.icon-uploader .el-upload-dragger:hover {
|
||
border-color: #409eff;
|
||
background: #f0f9ff;
|
||
}
|
||
|
||
.uploader-icon {
|
||
font-size: 28px;
|
||
color: #8c939d;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.el-upload__text {
|
||
color: #606266;
|
||
font-size: 14px;
|
||
margin-bottom: 5px;
|
||
}
|
||
|
||
.el-upload__text em {
|
||
color: #409eff;
|
||
font-style: normal;
|
||
}
|
||
|
||
.el-upload__tip {
|
||
font-size: 12px;
|
||
color: #909399;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
|
||
|
||
/* 表单样式优化 */
|
||
.el-form-item {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.el-form-item__label {
|
||
font-weight: 500;
|
||
color: #606266;
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 768px) {
|
||
.preview-image {
|
||
max-width: 80px;
|
||
max-height: 80px;
|
||
}
|
||
|
||
.icon-uploader .el-upload-dragger {
|
||
height: 100px;
|
||
}
|
||
}
|
||
|
||
</style> |