| | |
| | | <div class="page-header"> |
| | | <h2>企业门户</h2> |
| | | <div class="header-actions"> |
| | | <el-button @click="handlePreview" :icon="View" type="info" plain>预览</el-button> |
| | | <el-button @click="toggleEdit" :icon="isEdit ? 'Close' : 'Edit'" :type="isEdit ? 'default' : 'primary'"> |
| | | <el-button @click="handlePreview" |
| | | :icon="View" |
| | | type="info" |
| | | plain>预览</el-button> |
| | | <el-button @click="toggleEdit" |
| | | :icon="isEdit ? 'Close' : 'Edit'" |
| | | :type="isEdit ? 'default' : 'primary'"> |
| | | {{ isEdit ? '取消编辑' : '编辑' }} |
| | | </el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 企业信息卡片 --> |
| | | <div class="enterprise-info-card" v-loading="loading"> |
| | | <div class="enterprise-info-card" |
| | | v-loading="loading"> |
| | | <!-- 基本信息区域 --> |
| | | <div class="info-section"> |
| | | <div class="section-header"> |
| | | <h3>基本信息</h3> |
| | | </div> |
| | | <el-descriptions :column="2" border class="info-descriptions"> |
| | | <el-descriptions :column="2" |
| | | border |
| | | class="info-descriptions"> |
| | | <el-descriptions-item label="公司名称"> |
| | | <el-input v-if="isEdit" v-model="form.companyName" placeholder="请输入公司名称" clearable /> |
| | | <span v-else class="content-text">{{ form.companyName || '-' }}</span> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.companyName" |
| | | placeholder="请输入公司名称" |
| | | clearable /> |
| | | <span v-else |
| | | class="content-text">{{ form.companyName || '-' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="联系人"> |
| | | <el-input v-if="isEdit" v-model="form.contactPerson" placeholder="请输入联系人" clearable /> |
| | | <span v-else class="content-text">{{ form.contactPerson || '-' }}</span> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.contactPerson" |
| | | placeholder="请输入联系人" |
| | | clearable /> |
| | | <span v-else |
| | | class="content-text">{{ form.contactPerson || '-' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="联系电话"> |
| | | <el-input v-if="isEdit" v-model="form.contactPhone" placeholder="请输入联系电话" clearable /> |
| | | <span v-else class="content-text">{{ form.contactPhone || '-' }}</span> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.contactPhone" |
| | | placeholder="请输入联系电话" |
| | | clearable /> |
| | | <span v-else |
| | | class="content-text">{{ form.contactPhone || '-' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="公司地址"> |
| | | <el-input v-if="isEdit" v-model="form.companyAddress" placeholder="请输入公司地址" clearable /> |
| | | <span v-else class="content-text">{{ form.companyAddress || '-' }}</span> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.companyAddress" |
| | | placeholder="请输入公司地址" |
| | | clearable /> |
| | | <span v-else |
| | | class="content-text">{{ form.companyAddress || '-' }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="公司网站"> |
| | | <el-input v-if="isEdit" v-model="form.website" placeholder="请输入公司网站" clearable /> |
| | | <a v-else-if="form.website" :href="form.website" target="_blank" class="link-text">{{ form.website }}</a> |
| | | <span v-else class="content-text">-</span> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.website" |
| | | placeholder="请输入公司网站" |
| | | clearable /> |
| | | <a v-else-if="form.website" |
| | | :href="form.website" |
| | | target="_blank" |
| | | class="link-text">{{ form.website }}</a> |
| | | <span v-else |
| | | class="content-text">-</span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | |
| | | <!-- Logo和二维码区域 --> |
| | | <div class="info-section"> |
| | | <div class="section-header"> |
| | |
| | | <div class="upload-item"> |
| | | <span class="upload-label">公司Logo</span> |
| | | <div class="upload-wrapper"> |
| | | <el-upload |
| | | v-if="isEdit" |
| | | class="logo-uploader" |
| | | :show-file-list="false" |
| | | :before-upload="(file) => beforeLogoUpload(file, 'companyLogo')" |
| | | action="#"> |
| | | <img v-if="form.companyLogo" :src="'/file/preview?url=' + form.companyLogo" class="uploaded-image" /> |
| | | <div v-else class="upload-placeholder"> |
| | | <el-icon class="upload-icon"><Plus /></el-icon> |
| | | <el-upload v-if="isEdit" |
| | | class="logo-uploader" |
| | | :show-file-list="false" |
| | | :before-upload="(file) => beforeLogoUpload(file, 'companyLogo')" |
| | | action="#"> |
| | | <img v-if="form.companyLogo" |
| | | :src="base + form.companyLogo" |
| | | class="uploaded-image" |
| | | alt="Image Preview" /> |
| | | <div v-else |
| | | class="upload-placeholder"> |
| | | <el-icon class="upload-icon"> |
| | | <Plus /> |
| | | </el-icon> |
| | | <span class="upload-text">上传Logo</span> |
| | | </div> |
| | | </el-upload> |
| | | <img |
| | | v-else-if="form.companyLogo" |
| | | :src="'/file/preview?url=' + form.companyLogo" |
| | | class="display-image" |
| | | /> |
| | | <div v-else class="empty-placeholder"> |
| | | <el-icon :size="40"><Picture /></el-icon> |
| | | <img v-else-if="form.companyLogo" |
| | | :src="base + form.companyLogo" |
| | | class="display-image" |
| | | alt="Image Preview" /> |
| | | <div v-else |
| | | class="empty-placeholder"> |
| | | <el-icon :size="40"> |
| | | <Picture /> |
| | | </el-icon> |
| | | <span>暂无Logo</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 二维码 --> |
| | | <div class="upload-item"> |
| | | <span class="upload-label">二维码</span> |
| | | <div class="upload-wrapper"> |
| | | <el-upload |
| | | v-if="isEdit" |
| | | class="qr-uploader" |
| | | :show-file-list="false" |
| | | :before-upload="(file) => beforeLogoUpload(file, 'qrCode')" |
| | | action="#"> |
| | | <img v-if="form.qrCode" :src="'/file/preview?url=' + form.qrCode" class="uploaded-image" /> |
| | | <div v-else class="upload-placeholder"> |
| | | <el-icon class="upload-icon"><Plus /></el-icon> |
| | | <el-upload v-if="isEdit" |
| | | class="qr-uploader" |
| | | :show-file-list="false" |
| | | :before-upload="(file) => beforeLogoUpload(file, 'qrCode')" |
| | | action="#"> |
| | | <img v-if="form.qrCode" |
| | | :src="base + form.qrCode" |
| | | class="uploaded-image" |
| | | alt="Image Preview" /> |
| | | <div v-else |
| | | class="upload-placeholder"> |
| | | <el-icon class="upload-icon"> |
| | | <Plus /> |
| | | </el-icon> |
| | | <span class="upload-text">上传二维码</span> |
| | | </div> |
| | | </el-upload> |
| | | <img |
| | | v-else-if="form.qrCode" |
| | | :src="'/file/preview?url=' + form.qrCode" |
| | | class="display-image" |
| | | /> |
| | | <div v-else class="empty-placeholder"> |
| | | <el-icon :size="40"><Picture /></el-icon> |
| | | <img v-else-if="form.qrCode" |
| | | :src="base + form.qrCode" |
| | | class="display-image" |
| | | alt="Image Preview" /> |
| | | <div v-else |
| | | class="empty-placeholder"> |
| | | <el-icon :size="40"> |
| | | <Picture /> |
| | | </el-icon> |
| | | <span>暂无二维码</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 公司简介 --> |
| | | <div class="info-section"> |
| | | <div class="section-header"> |
| | | <h3>公司简介</h3> |
| | | </div> |
| | | <div class="content-editor"> |
| | | <el-input |
| | | v-if="isEdit" |
| | | v-model="form.companyIntro" |
| | | type="textarea" |
| | | :rows="6" |
| | | maxlength="2000" |
| | | show-word-limit |
| | | placeholder="请输入公司简介..." |
| | | /> |
| | | <div v-else class="content-display" v-html="form.companyIntro || '<span class=\'empty-text\'>暂无公司简介</span>'"></div> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.companyIntro" |
| | | type="textarea" |
| | | :rows="6" |
| | | maxlength="2000" |
| | | show-word-limit |
| | | placeholder="请输入公司简介..." /> |
| | | <div v-else |
| | | class="content-display" |
| | | v-html="form.companyIntro || '<span class=\'empty-text\'>暂无公司简介</span>'"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 产品介绍 --> |
| | | <div class="info-section"> |
| | | <div class="section-header"> |
| | | <h3>产品介绍</h3> |
| | | </div> |
| | | <div class="content-editor"> |
| | | <el-input |
| | | v-if="isEdit" |
| | | v-model="form.productIntro" |
| | | type="textarea" |
| | | :rows="6" |
| | | maxlength="2000" |
| | | show-word-limit |
| | | placeholder="请输入产品介绍..." |
| | | /> |
| | | <div v-else class="content-display" v-html="form.productIntro || '<span class=\'empty-text\'>暂无产品介绍</span>'"></div> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.productIntro" |
| | | type="textarea" |
| | | :rows="6" |
| | | maxlength="2000" |
| | | show-word-limit |
| | | placeholder="请输入产品介绍..." /> |
| | | <div v-else |
| | | class="content-display" |
| | | v-html="form.productIntro || '<span class=\'empty-text\'>暂无产品介绍</span>'"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 设备介绍 --> |
| | | <div class="info-section"> |
| | | <div class="section-header"> |
| | | <h3>设备介绍</h3> |
| | | </div> |
| | | <div class="content-editor"> |
| | | <el-input |
| | | v-if="isEdit" |
| | | v-model="form.equipmentIntro" |
| | | type="textarea" |
| | | :rows="6" |
| | | maxlength="2000" |
| | | show-word-limit |
| | | placeholder="请输入设备介绍..." |
| | | /> |
| | | <div v-else class="content-display" v-html="form.equipmentIntro || '<span class=\'empty-text\'>暂无设备介绍</span>'"></div> |
| | | <el-input v-if="isEdit" |
| | | v-model="form.equipmentIntro" |
| | | type="textarea" |
| | | :rows="6" |
| | | maxlength="2000" |
| | | show-word-limit |
| | | placeholder="请输入设备介绍..." /> |
| | | <div v-else |
| | | class="content-display" |
| | | v-html="form.equipmentIntro || '<span class=\'empty-text\'>暂无设备介绍</span>'"></div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <div v-if="isEdit" class="form-actions"> |
| | | <el-button type="primary" @click="handleSave" :loading="saving" size="large">保存</el-button> |
| | | <el-button @click="handleCancel" size="large">取消</el-button> |
| | | <div v-if="isEdit" |
| | | class="form-actions"> |
| | | <el-button type="primary" |
| | | @click="handleSave" |
| | | :loading="saving" |
| | | size="large">保存</el-button> |
| | | <el-button @click="handleCancel" |
| | | size="large">取消</el-button> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 预览弹窗 --> |
| | | <el-dialog |
| | | v-model="previewVisible" |
| | | title="企业信息预览" |
| | | width="70%" |
| | | :destroy-on-close="true"> |
| | | <el-dialog v-model="previewVisible" |
| | | title="企业信息预览" |
| | | width="70%" |
| | | :destroy-on-close="true"> |
| | | <div class="preview-content"> |
| | | <div class="preview-header"> |
| | | <img v-if="form.companyLogo" :src="'/file/preview?url=' + form.companyLogo" class="preview-logo" /> |
| | | <img v-if="form.companyLogo" |
| | | :src="form.companyLogo" |
| | | class="preview-logo" |
| | | alt="Image Preview" /> |
| | | <div class="preview-title"> |
| | | <h1>{{ form.companyName || '公司名称' }}</h1> |
| | | <p v-if="form.website">{{ form.website }}</p> |
| | |
| | | <h4>设备介绍</h4> |
| | | <div v-html="form.equipmentIntro || '暂无介绍'"></div> |
| | | </div> |
| | | <div v-if="form.qrCode" class="preview-section preview-qr"> |
| | | <div v-if="form.qrCode" |
| | | class="preview-section preview-qr"> |
| | | <h4>扫码关注</h4> |
| | | <img :src="'/file/preview?url=' + form.qrCode" class="qr-image" /> |
| | | <img :src="form.qrCode" |
| | | class="qr-image" |
| | | alt="Image Preview" /> |
| | | </div> |
| | | </div> |
| | | </el-dialog> |
| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref, reactive, onMounted } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { Plus, Picture, View } from '@element-plus/icons-vue' |
| | | import { getEnterpriseInfo, saveEnterpriseInfo, uploadLogo, uploadQrCode } from '@/api/basicData/enterpriseInfo.js' |
| | | import { ref, reactive, onMounted } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import { Plus, Picture, View } from "@element-plus/icons-vue"; |
| | | import { |
| | | getEnterpriseInfo, |
| | | saveEnterpriseInfo, |
| | | uploadLogo, |
| | | uploadQrCode, |
| | | } from "@/api/basicData/enterpriseInfo.js"; |
| | | |
| | | const { proxy } = getCurrentInstance() |
| | | const { proxy } = getCurrentInstance(); |
| | | |
| | | const loading = ref(false) |
| | | const saving = ref(false) |
| | | const isEdit = ref(false) |
| | | const previewVisible = ref(false) |
| | | const uploadType = ref('') |
| | | const loading = ref(false); |
| | | const saving = ref(false); |
| | | const isEdit = ref(false); |
| | | const previewVisible = ref(false); |
| | | const uploadType = ref(""); |
| | | |
| | | const form = reactive({ |
| | | id: null, |
| | | companyName: '', |
| | | companyLogo: '', |
| | | companyIntro: '', |
| | | productIntro: '', |
| | | equipmentIntro: '', |
| | | contactPerson: '', |
| | | contactPhone: '', |
| | | companyAddress: '', |
| | | website: '', |
| | | qrCode: '' |
| | | }) |
| | | companyName: "", |
| | | companyLogo: "", |
| | | companyIntro: "", |
| | | productIntro: "", |
| | | equipmentIntro: "", |
| | | contactPerson: "", |
| | | contactPhone: "", |
| | | companyAddress: "", |
| | | website: "", |
| | | qrCode: "", |
| | | }); |
| | | |
| | | // 深拷贝原始数据,用于取消时恢复 |
| | | let originalForm = {} |
| | | |
| | | let originalForm = {}; |
| | | const base = window.location.protocol + "//" + window.location.host; |
| | | // 获取企业信息 |
| | | const fetchInfo = () => { |
| | | loading.value = true |
| | | getEnterpriseInfo().then(res => { |
| | | if (res.code === 200 && res.data) { |
| | | Object.assign(form, res.data) |
| | | originalForm = JSON.parse(JSON.stringify(res.data)) |
| | | } |
| | | }).finally(() => { |
| | | loading.value = false |
| | | }) |
| | | } |
| | | loading.value = true; |
| | | getEnterpriseInfo() |
| | | .then(res => { |
| | | if (res.code === 200 && res.data) { |
| | | // 将图片路径拼接为完整地址 |
| | | |
| | | if (res.data.companyLogo) { |
| | | res.data.companyLogo = res.data.companyLogo; |
| | | } |
| | | if (res.data.qrCode) { |
| | | res.data.qrCode = res.data.qrCode; |
| | | } |
| | | Object.assign(form, res.data); |
| | | originalForm = JSON.parse(JSON.stringify(res.data)); |
| | | } |
| | | }) |
| | | .finally(() => { |
| | | loading.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 切换编辑模式 |
| | | const toggleEdit = () => { |
| | | if (isEdit.value) { |
| | | // 取消编辑,恢复原始数据 |
| | | Object.assign(form, originalForm) |
| | | isEdit.value = false |
| | | Object.assign(form, originalForm); |
| | | isEdit.value = false; |
| | | } else { |
| | | // 进入编辑模式 |
| | | originalForm = JSON.parse(JSON.stringify(form)) |
| | | isEdit.value = true |
| | | originalForm = JSON.parse(JSON.stringify(form)); |
| | | isEdit.value = true; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 预览 |
| | | const handlePreview = () => { |
| | | previewVisible.value = true |
| | | } |
| | | previewVisible.value = true; |
| | | }; |
| | | |
| | | // 文件上传前校验 |
| | | const beforeLogoUpload = (file, type) => { |
| | | const isImage = file.type.startsWith('image/') |
| | | const isLt2M = file.size / 1024 / 1024 < 2 |
| | | const isImage = file.type.startsWith("image/"); |
| | | const isLt2M = file.size / 1024 / 1024 < 2; |
| | | |
| | | if (!isImage) { |
| | | ElMessage.error('只能上传图片文件!') |
| | | return false |
| | | ElMessage.error("只能上传图片文件!"); |
| | | return false; |
| | | } |
| | | if (!isLt2M) { |
| | | ElMessage.error('图片大小不能超过 2MB!') |
| | | return false |
| | | ElMessage.error("图片大小不能超过 2MB!"); |
| | | return false; |
| | | } |
| | | |
| | | uploadType.value = type |
| | | uploadFileReq(file) |
| | | return false |
| | | } |
| | | uploadType.value = type; |
| | | uploadFileReq(file); |
| | | return false; |
| | | }; |
| | | |
| | | // 上传文件请求 |
| | | const uploadFileReq = (file) => { |
| | | const uploadFn = uploadType.value === 'companyLogo' ? uploadLogo : uploadQrCode |
| | | uploadFn(file).then(res => { |
| | | if (res.code === 200) { |
| | | const path = res.data.tempPath |
| | | if (uploadType.value === 'companyLogo') { |
| | | form.companyLogo = path |
| | | const uploadFileReq = file => { |
| | | const uploadFn = |
| | | uploadType.value === "companyLogo" ? uploadLogo : uploadQrCode; |
| | | uploadFn(file) |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | const path = res.data.tempPath; |
| | | if (uploadType.value === "companyLogo") { |
| | | form.companyLogo = path; |
| | | } else { |
| | | form.qrCode = path; |
| | | } |
| | | ElMessage.success("上传成功"); |
| | | } else { |
| | | form.qrCode = path |
| | | ElMessage.error(res.msg || "上传失败"); |
| | | } |
| | | ElMessage.success('上传成功') |
| | | } else { |
| | | ElMessage.error(res.msg || '上传失败') |
| | | } |
| | | }).catch(() => { |
| | | ElMessage.error('上传失败') |
| | | }) |
| | | } |
| | | }) |
| | | .catch(() => { |
| | | ElMessage.error("上传失败"); |
| | | }); |
| | | }; |
| | | |
| | | // 保存 |
| | | const handleSave = () => { |
| | | saving.value = true |
| | | saveEnterpriseInfo(form).then(res => { |
| | | if (res.code === 200) { |
| | | ElMessage.success('保存成功') |
| | | isEdit.value = false |
| | | fetchInfo() |
| | | } else { |
| | | ElMessage.error(res.msg || '保存失败') |
| | | } |
| | | }).finally(() => { |
| | | saving.value = false |
| | | }) |
| | | } |
| | | saving.value = true; |
| | | console.log(form, "form"); |
| | | |
| | | saveEnterpriseInfo(form) |
| | | .then(res => { |
| | | if (res.code === 200) { |
| | | ElMessage.success("保存成功"); |
| | | isEdit.value = false; |
| | | fetchInfo(); |
| | | } else { |
| | | ElMessage.error(res.msg || "保存失败"); |
| | | } |
| | | }) |
| | | .finally(() => { |
| | | saving.value = false; |
| | | }); |
| | | }; |
| | | |
| | | // 取消 |
| | | const handleCancel = () => { |
| | | Object.assign(form, originalForm) |
| | | isEdit.value = false |
| | | } |
| | | Object.assign(form, originalForm); |
| | | isEdit.value = false; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | fetchInfo() |
| | | }) |
| | | fetchInfo(); |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .page-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 16px 24px; |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | margin-bottom: 16px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); |
| | | |
| | | h2 { |
| | | margin: 0; |
| | | font-size: 20px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | } |
| | | |
| | | .header-actions { |
| | | .page-header { |
| | | display: flex; |
| | | gap: 10px; |
| | | } |
| | | } |
| | | |
| | | .enterprise-info-card { |
| | | background: #fff; |
| | | padding: 24px; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); |
| | | } |
| | | |
| | | .info-section { |
| | | margin-bottom: 32px; |
| | | |
| | | &:last-of-type { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .section-header { |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 16px 24px; |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | margin-bottom: 16px; |
| | | box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06); |
| | | |
| | | h3 { |
| | | h2 { |
| | | margin: 0; |
| | | font-size: 16px; |
| | | font-size: 20px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | padding-bottom: 10px; |
| | | border-bottom: 2px solid #409eff; |
| | | display: inline-block; |
| | | position: relative; |
| | | } |
| | | |
| | | &::after { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: -2px; |
| | | width: 60px; |
| | | height: 2px; |
| | | background-color: #409eff; |
| | | .header-actions { |
| | | display: flex; |
| | | gap: 10px; |
| | | } |
| | | } |
| | | |
| | | .enterprise-info-card { |
| | | background: #fff; |
| | | padding: 24px; |
| | | border-radius: 8px; |
| | | box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06); |
| | | } |
| | | |
| | | .info-section { |
| | | margin-bottom: 32px; |
| | | |
| | | &:last-of-type { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .section-header { |
| | | margin-bottom: 16px; |
| | | |
| | | h3 { |
| | | margin: 0; |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | padding-bottom: 10px; |
| | | border-bottom: 2px solid #409eff; |
| | | display: inline-block; |
| | | position: relative; |
| | | |
| | | &::after { |
| | | content: ""; |
| | | position: absolute; |
| | | left: 0; |
| | | bottom: -2px; |
| | | width: 60px; |
| | | height: 2px; |
| | | background-color: #409eff; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | .info-descriptions { |
| | | :deep(.el-descriptions__label) { |
| | | width: 120px; |
| | | background-color: #f5f7fa; |
| | | font-weight: 500; |
| | | .info-descriptions { |
| | | :deep(.el-descriptions__label) { |
| | | width: 120px; |
| | | background-color: #f5f7fa; |
| | | font-weight: 500; |
| | | color: #606266; |
| | | } |
| | | |
| | | :deep(.el-descriptions__content) { |
| | | color: #303133; |
| | | } |
| | | } |
| | | |
| | | .content-text { |
| | | color: #606266; |
| | | } |
| | | |
| | | :deep(.el-descriptions__content) { |
| | | color: #303133; |
| | | } |
| | | } |
| | | .link-text { |
| | | color: #409eff; |
| | | text-decoration: none; |
| | | |
| | | .content-text { |
| | | color: #606266; |
| | | } |
| | | |
| | | .link-text { |
| | | color: #409eff; |
| | | text-decoration: none; |
| | | |
| | | &:hover { |
| | | text-decoration: underline; |
| | | } |
| | | } |
| | | |
| | | .logo-qr-container { |
| | | display: flex; |
| | | gap: 40px; |
| | | } |
| | | |
| | | .upload-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | |
| | | .upload-label { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | margin-bottom: 12px; |
| | | font-weight: 500; |
| | | &:hover { |
| | | text-decoration: underline; |
| | | } |
| | | } |
| | | |
| | | .upload-wrapper { |
| | | .logo-qr-container { |
| | | display: flex; |
| | | gap: 40px; |
| | | } |
| | | |
| | | .upload-item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | |
| | | .upload-label { |
| | | font-size: 14px; |
| | | color: #606266; |
| | | margin-bottom: 12px; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .upload-wrapper { |
| | | width: 140px; |
| | | height: 140px; |
| | | } |
| | | } |
| | | |
| | | /* el-upload 根节点是外层 div,真正触发区在内层 .el-upload,需让内层铺满外层虚线框 */ |
| | | .logo-uploader, |
| | | .qr-uploader { |
| | | display: flex; |
| | | flex-direction: column; |
| | | box-sizing: border-box; |
| | | width: 140px; |
| | | height: 140px; |
| | | } |
| | | } |
| | | border: 1px dashed #d9d9d9; |
| | | border-radius: 8px; |
| | | cursor: pointer; |
| | | transition: all 0.3s; |
| | | overflow: hidden; |
| | | |
| | | /* el-upload 根节点是外层 div,真正触发区在内层 .el-upload,需让内层铺满外层虚线框 */ |
| | | .logo-uploader, |
| | | .qr-uploader { |
| | | display: flex; |
| | | flex-direction: column; |
| | | box-sizing: border-box; |
| | | width: 140px; |
| | | height: 140px; |
| | | border: 1px dashed #d9d9d9; |
| | | border-radius: 8px; |
| | | cursor: pointer; |
| | | transition: all 0.3s; |
| | | overflow: hidden; |
| | | :deep(.el-upload) { |
| | | flex: 1; |
| | | min-height: 0; |
| | | width: 100%; |
| | | display: flex !important; |
| | | flex-direction: column; |
| | | align-items: stretch; |
| | | box-sizing: border-box; |
| | | border: none; |
| | | outline: none; |
| | | } |
| | | |
| | | :deep(.el-upload) { |
| | | flex: 1; |
| | | min-height: 0; |
| | | width: 100%; |
| | | display: flex !important; |
| | | flex-direction: column; |
| | | align-items: stretch; |
| | | box-sizing: border-box; |
| | | border: none; |
| | | outline: none; |
| | | :deep(.uploaded-image), |
| | | :deep(.upload-placeholder) { |
| | | flex: 1 1 auto; |
| | | min-height: 0; |
| | | min-width: 0; |
| | | width: 100%; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | } |
| | | |
| | | :deep(.uploaded-image) { |
| | | object-fit: contain; |
| | | } |
| | | |
| | | :deep(.upload-placeholder) { |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | background: #fafafa; |
| | | color: #8c939d; |
| | | |
| | | .upload-icon { |
| | | font-size: 32px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .upload-text { |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | :deep(.uploaded-image), |
| | | :deep(.upload-placeholder) { |
| | | flex: 1 1 auto; |
| | | min-height: 0; |
| | | min-width: 0; |
| | | width: 100%; |
| | | } |
| | | |
| | | &:hover { |
| | | border-color: #409eff; |
| | | } |
| | | |
| | | :deep(.uploaded-image) { |
| | | .display-image { |
| | | width: 140px; |
| | | height: 140px; |
| | | object-fit: contain; |
| | | border-radius: 8px; |
| | | border: 1px solid #e4e7ed; |
| | | } |
| | | |
| | | :deep(.upload-placeholder) { |
| | | .empty-placeholder { |
| | | width: 140px; |
| | | height: 140px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | background: #fafafa; |
| | | color: #8c939d; |
| | | border-radius: 8px; |
| | | border: 1px dashed #e4e7ed; |
| | | color: #c0c4cc; |
| | | |
| | | .upload-icon { |
| | | font-size: 32px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .upload-text { |
| | | span { |
| | | margin-top: 8px; |
| | | font-size: 12px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .display-image { |
| | | width: 140px; |
| | | height: 140px; |
| | | object-fit: contain; |
| | | border-radius: 8px; |
| | | border: 1px solid #e4e7ed; |
| | | } |
| | | |
| | | .empty-placeholder { |
| | | width: 140px; |
| | | height: 140px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: center; |
| | | align-items: center; |
| | | background: #fafafa; |
| | | border-radius: 8px; |
| | | border: 1px dashed #e4e7ed; |
| | | color: #c0c4cc; |
| | | |
| | | span { |
| | | margin-top: 8px; |
| | | font-size: 12px; |
| | | .content-editor { |
| | | :deep(.el-textarea__inner) { |
| | | border-radius: 6px; |
| | | font-size: 14px; |
| | | line-height: 1.8; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .content-editor { |
| | | :deep(.el-textarea__inner) { |
| | | .content-display { |
| | | padding: 16px 20px; |
| | | background: #fafafa; |
| | | border-radius: 6px; |
| | | font-size: 14px; |
| | | border: 1px solid #ebeef5; |
| | | line-height: 1.8; |
| | | color: #606266; |
| | | min-height: 120px; |
| | | white-space: pre-wrap; |
| | | |
| | | :deep(.empty-text) { |
| | | color: #c0c4cc; |
| | | font-style: italic; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .content-display { |
| | | padding: 16px 20px; |
| | | background: #fafafa; |
| | | border-radius: 6px; |
| | | border: 1px solid #ebeef5; |
| | | line-height: 1.8; |
| | | color: #606266; |
| | | min-height: 120px; |
| | | white-space: pre-wrap; |
| | | |
| | | :deep(.empty-text) { |
| | | color: #c0c4cc; |
| | | font-style: italic; |
| | | } |
| | | } |
| | | |
| | | .form-actions { |
| | | display: flex; |
| | | justify-content: center; |
| | | gap: 16px; |
| | | padding-top: 24px; |
| | | margin-top: 16px; |
| | | border-top: 1px solid #ebeef5; |
| | | } |
| | | |
| | | /* 预览弹窗样式 */ |
| | | .preview-content { |
| | | .preview-header { |
| | | .form-actions { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 20px; |
| | | padding: 20px; |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | border-radius: 8px; |
| | | color: #fff; |
| | | margin-bottom: 20px; |
| | | justify-content: center; |
| | | gap: 16px; |
| | | padding-top: 24px; |
| | | margin-top: 16px; |
| | | border-top: 1px solid #ebeef5; |
| | | } |
| | | |
| | | .preview-logo { |
| | | width: 80px; |
| | | height: 80px; |
| | | object-fit: contain; |
| | | background: #fff; |
| | | /* 预览弹窗样式 */ |
| | | .preview-content { |
| | | .preview-header { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 20px; |
| | | padding: 20px; |
| | | background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); |
| | | border-radius: 8px; |
| | | padding: 8px; |
| | | color: #fff; |
| | | margin-bottom: 20px; |
| | | |
| | | .preview-logo { |
| | | width: 80px; |
| | | height: 80px; |
| | | object-fit: contain; |
| | | background: #fff; |
| | | border-radius: 8px; |
| | | padding: 8px; |
| | | } |
| | | |
| | | .preview-title { |
| | | h1 { |
| | | margin: 0 0 8px 0; |
| | | font-size: 28px; |
| | | font-weight: 600; |
| | | } |
| | | |
| | | p { |
| | | margin: 0; |
| | | opacity: 0.9; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .preview-title { |
| | | h1 { |
| | | margin: 0 0 8px 0; |
| | | font-size: 28px; |
| | | .preview-section { |
| | | margin-bottom: 24px; |
| | | |
| | | h4 { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin: 0 0 12px 0; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | p { |
| | | margin: 0; |
| | | opacity: 0.9; |
| | | font-size: 14px; |
| | | margin: 8px 0; |
| | | color: #606266; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | :deep(div) { |
| | | line-height: 1.8; |
| | | color: #606266; |
| | | white-space: pre-wrap; |
| | | } |
| | | } |
| | | |
| | | .preview-qr { |
| | | text-align: center; |
| | | |
| | | .qr-image { |
| | | width: 150px; |
| | | height: 150px; |
| | | margin-top: 12px; |
| | | border-radius: 8px; |
| | | border: 1px solid #ebeef5; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .preview-section { |
| | | margin-bottom: 24px; |
| | | |
| | | h4 { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | margin: 0 0 12px 0; |
| | | padding-bottom: 8px; |
| | | border-bottom: 1px solid #ebeef5; |
| | | } |
| | | |
| | | p { |
| | | margin: 8px 0; |
| | | color: #606266; |
| | | line-height: 1.6; |
| | | } |
| | | |
| | | :deep(div) { |
| | | line-height: 1.8; |
| | | color: #606266; |
| | | white-space: pre-wrap; |
| | | } |
| | | :deep(.el-divider) { |
| | | margin: 16px 0; |
| | | } |
| | | |
| | | .preview-qr { |
| | | text-align: center; |
| | | |
| | | .qr-image { |
| | | width: 150px; |
| | | height: 150px; |
| | | margin-top: 12px; |
| | | border-radius: 8px; |
| | | border: 1px solid #ebeef5; |
| | | } |
| | | } |
| | | } |
| | | |
| | | :deep(.el-divider) { |
| | | margin: 16px 0; |
| | | } |
| | | </style> |