| New file |
| | |
| | | <template> |
| | | <Modal |
| | | v-model="visible" |
| | | title="修改模板信息" |
| | | width="600" |
| | | @on-ok="handleOk" |
| | | @on-cancel="handleCancel" |
| | | > |
| | | <div v-if="loading" style="text-align: center; padding: 20px;"> |
| | | <Spin size="large" /> |
| | | <p>加载中...</p> |
| | | </div> |
| | | |
| | | <Form ref="form" :model="form" :label-width="100" v-else-if="templateData"> |
| | | <FormItem label="模板ID"> |
| | | <Input v-model="templateData.id" disabled /> |
| | | </FormItem> |
| | | |
| | | <FormItem label="模板名称"> |
| | | <Input v-model="form.templateName" disabled /> |
| | | </FormItem> |
| | | |
| | | <!-- 模板图片选择 --> |
| | | <FormItem |
| | | v-if="templateData.templateImgs && templateData.templateImgs.length > 0" |
| | | label="模板图片" |
| | | > |
| | | <div class="image-grid"> |
| | | <div |
| | | v-for="(img, index) in templateData.templateImgs" |
| | | :key="img.id" |
| | | class="image-item" |
| | | :class="{ selected: selectedImageId === img.id }" |
| | | @click="selectImage(img.id)" |
| | | > |
| | | <img :src="getImageUrl(img.imgUrl)" class="image-preview" /> |
| | | <div v-if="selectedImageId === img.id" class="selected-overlay"> |
| | | <Icon type="md-checkmark" size="30" color="#fff" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </FormItem> |
| | | |
| | | <!-- 动态表单项 --> |
| | | <div v-if="templateData.templateConstomizeTitles"> |
| | | <FormItem |
| | | v-for="(item, index) in templateData.templateConstomizeTitles" |
| | | :key="item.id" |
| | | :label="item.templateTitle" |
| | | > |
| | | <!-- 文本输入 --> |
| | | <Input |
| | | v-if="item.contentType === 'TEXT'" |
| | | v-model="formValues[item.id]" |
| | | :placeholder="'请输入' + item.templateTitle" |
| | | /> |
| | | |
| | | <!-- 图片上传 --> |
| | | <div v-if="item.contentType === 'IMAGE'" class="image-upload-container"> |
| | | <!-- 图片预览 --> |
| | | <div v-if="formValues[item.id]" class="image-preview-container"> |
| | | <img :src="getImageUrl(formValues[item.id])" class="uploaded-image" /> |
| | | <Icon |
| | | type="md-close" |
| | | class="delete-icon" |
| | | @click="removeImage(item.id)" |
| | | /> |
| | | </div> |
| | | |
| | | <!-- 上传按钮 --> |
| | | <div v-else class="upload-btn" @click="uploadImage(item.id)"> |
| | | <Icon type="md-add" size="30" color="#999" /> |
| | | <span>上传图片</span> |
| | | </div> |
| | | |
| | | <!-- 文件选择输入框(隐藏) --> |
| | | <input |
| | | :ref="'fileInput' + item.id" |
| | | type="file" |
| | | accept="image/*" |
| | | style="display: none" |
| | | @change="handleFileSelect($event, item.id)" |
| | | /> |
| | | </div> |
| | | </FormItem> |
| | | </div> |
| | | |
| | | <!-- 调试信息 --> |
| | | <!-- <details style="margin-top: 20px; border: 1px solid #eee; padding: 10px;">--> |
| | | <!-- <summary>调试信息</summary>--> |
| | | <!-- <pre>{{ JSON.stringify(templateData, null, 2) }}</pre>--> |
| | | <!-- <p>选中的图片ID: {{ selectedImageId }}</p>--> |
| | | <!-- <p>表单值: {{ JSON.stringify(formValues, null, 2) }}</p>--> |
| | | <!-- </details>--> |
| | | </Form> |
| | | |
| | | <div v-else> |
| | | <p>未加载到模板数据</p> |
| | | </div> |
| | | |
| | | <div slot="footer"> |
| | | <Button @click="handleCancel">取消</Button> |
| | | <Button type="primary" @click="handleOk" :loading="loading">确定</Button> |
| | | </div> |
| | | </Modal> |
| | | </template> |
| | | |
| | | <script> |
| | | import * as API_Order from "@/api/order"; |
| | | import { getFilePreviewUrl, uploadFileByLmk } from "@/api/common.js"; |
| | | |
| | | export default { |
| | | name: "EditTemplateModal", |
| | | props: { |
| | | value: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | templateId: { |
| | | type: [String, Number], |
| | | default: "" |
| | | }, |
| | | // 添加订单编号属性 |
| | | orderSn: { |
| | | type: String, |
| | | default: "" |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | visible: this.value, |
| | | loading: false, |
| | | templateData: null, |
| | | form: { |
| | | templateName: "" |
| | | }, |
| | | formValues: {}, |
| | | selectedImageId: null, |
| | | currentUploadFieldId: null // 当前正在上传的字段ID |
| | | }; |
| | | }, |
| | | watch: { |
| | | value(val) { |
| | | this.visible = val; |
| | | if (val) { |
| | | console.log("EditTemplateModal打开,接收到的参数:", { |
| | | templateId: this.templateId, |
| | | orderSn: this.orderSn |
| | | }); |
| | | this.loadTemplateData(); |
| | | } |
| | | }, |
| | | visible(val) { |
| | | this.$emit("input", val); |
| | | } |
| | | }, |
| | | methods: { |
| | | // 加载模板数据 |
| | | async loadTemplateData() { |
| | | // 确保订单编号是必传的 |
| | | if (!this.orderSn) { |
| | | this.$Message.error("订单编号不能为空"); |
| | | console.error("订单编号为空,当前参数:", { |
| | | templateId: this.templateId, |
| | | orderSn: this.orderSn |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | if (!this.templateId) { |
| | | this.$Message.error("模板ID不能为空"); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | this.loading = true; |
| | | console.log("正在加载模板数据,模板ID:", this.templateId, "订单编号:", this.orderSn); |
| | | const res = await API_Order.getTemplate(this.templateId); |
| | | console.log("获取到的模板数据:", res); |
| | | if (res.code==200) { |
| | | this.templateData = res.data; |
| | | // 使用 name 字段作为模板名称 |
| | | this.form.templateName = res.data.name || ""; |
| | | |
| | | // 初始化表单值 |
| | | this.formValues = {}; |
| | | // 初始化选中的图片ID |
| | | this.selectedImageId = null; |
| | | |
| | | if (res.data.templateConstomizeTitles) { |
| | | res.data.templateConstomizeTitles.forEach(item => { |
| | | // 回显已有的值 |
| | | if (item.value) { |
| | | this.$set(this.formValues, item.id, item.value); |
| | | } else { |
| | | // 初始化表单值(如果没有默认值) |
| | | this.$set(this.formValues, item.id, ""); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // 如果有模板图片,设置默认选中的图片 |
| | | if (res.data.templateImgs && res.data.templateImgs.length > 0) { |
| | | // 如果已有选中的图片ID,则使用该ID,否则默认选中第一张 |
| | | if (res.data.chooseImageId) { |
| | | this.selectedImageId = res.data.chooseImageId; |
| | | } else { |
| | | this.selectedImageId = res.data.templateImgs[0].id; |
| | | } |
| | | } |
| | | |
| | | console.log("处理后的数据:", { |
| | | templateData: this.templateData, |
| | | formValues: this.formValues, |
| | | selectedImageId: this.selectedImageId |
| | | }); |
| | | } else { |
| | | this.$Message.error(res.message || "获取模板数据失败"); |
| | | } |
| | | } catch (error) { |
| | | this.$Message.error("加载模板数据失败: " + error.message); |
| | | console.error("加载模板数据失败:", error); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | |
| | | // 获取图片URL |
| | | getImageUrl(fileKey) { |
| | | // 确保fileKey是字符串类型 |
| | | if (!fileKey || typeof fileKey !== 'string') { |
| | | console.warn('fileKey is not a valid string:', fileKey); |
| | | return ''; // 返回空字符串或默认图片 |
| | | } |
| | | |
| | | // 安全检查startsWith方法是否存在 |
| | | if (fileKey.startsWith && typeof fileKey.startsWith === 'function' && |
| | | (fileKey.startsWith("http://") || fileKey.startsWith("https://"))) { |
| | | return fileKey; |
| | | } |
| | | |
| | | // 否则返回fileKey,让组件自己处理 |
| | | return fileKey; |
| | | }, |
| | | |
| | | // 选择图片 |
| | | selectImage(imageId) { |
| | | this.selectedImageId = imageId; |
| | | }, |
| | | |
| | | // 上传图片 |
| | | uploadImage(fieldId) { |
| | | this.currentUploadFieldId = fieldId; |
| | | // 触发文件选择 |
| | | this.$refs['fileInput' + fieldId][0].click(); |
| | | }, |
| | | |
| | | // 处理文件选择 |
| | | async handleFileSelect(event, fieldId) { |
| | | const file = event.target.files[0]; |
| | | if (!file) return; |
| | | |
| | | // 验证文件类型 |
| | | if (file.type && !file.type.startsWith('image/')) { |
| | | this.$Message.error("请选择图片文件"); |
| | | return; |
| | | } |
| | | |
| | | // 验证文件大小(限制为5MB) |
| | | if (file.size > 5 * 1024 * 1024) { |
| | | this.$Message.error("图片大小不能超过5MB"); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | this.loading = true; |
| | | // 创建FormData对象 |
| | | const formData = new FormData(); |
| | | formData.append('file', file); |
| | | |
| | | // 上传文件 |
| | | const res = await uploadFileByLmk(formData); |
| | | console.log('上传文件返回结果:', res); // 添加调试日志 |
| | | if (res.code === 200) { |
| | | // 上传成功,设置表单值 |
| | | // 确保res.data是字符串类型 |
| | | let fileKey = ''; |
| | | if (typeof res.data === 'string') { |
| | | fileKey = res.data; |
| | | } else if (res.data && typeof res.data === 'object') { |
| | | // 如果返回的是对象,尝试获取fileKey或url字段 |
| | | fileKey = res.data.fileKey || res.data.url || ''; |
| | | } else { |
| | | fileKey = String(res.data); |
| | | } |
| | | |
| | | // 确保fileKey是字符串类型 |
| | | if (typeof fileKey !== 'string') { |
| | | fileKey = String(fileKey); |
| | | } |
| | | |
| | | this.$set(this.formValues, fieldId, fileKey); |
| | | this.$Message.success("图片上传成功"); |
| | | } else { |
| | | this.$Message.error(res.msg || "图片上传失败"); |
| | | } |
| | | } catch (error) { |
| | | this.$Message.error("图片上传失败: " + (error.message || error)); |
| | | console.error(error); |
| | | } finally { |
| | | this.loading = false; |
| | | // 清空文件输入框 |
| | | event.target.value = ''; |
| | | } |
| | | }, |
| | | |
| | | // 移除图片 |
| | | removeImage(fieldId) { |
| | | this.$set(this.formValues, fieldId, ""); |
| | | }, |
| | | |
| | | // 构造提交参数 |
| | | buildSubmitParams() { |
| | | const params = { |
| | | templateId: this.templateId, |
| | | // 添加订单编号到提交参数 |
| | | sn: this.orderSn, |
| | | templateName: this.form.templateName, |
| | | chooseImageId: this.selectedImageId, |
| | | templateForm: [] |
| | | }; |
| | | |
| | | // 添加表单字段 |
| | | if (this.templateData && this.templateData.templateConstomizeTitles) { |
| | | this.templateData.templateConstomizeTitles.forEach(item => { |
| | | params.templateForm.push({ |
| | | id: item.id, |
| | | templateTitle: item.templateTitle, |
| | | contentType: item.contentType, |
| | | value: this.formValues[item.id] || "" |
| | | }); |
| | | }); |
| | | } |
| | | |
| | | console.log("提交参数:", params); |
| | | return params; |
| | | }, |
| | | |
| | | // 确定按钮 |
| | | async handleOk() { |
| | | if (!this.templateData) { |
| | | this.$Message.error("没有可提交的模板数据"); |
| | | return; |
| | | } |
| | | |
| | | this.loading = true; |
| | | try { |
| | | const params = this.buildSubmitParams(); |
| | | const res = await API_Order.editTemplate(params); |
| | | if (res.code==200) { |
| | | this.$Message.success("模板信息修改成功"); |
| | | this.visible = false; |
| | | this.$emit("success"); |
| | | } else { |
| | | this.$Message.error(res.message || "修改失败"); |
| | | } |
| | | } catch (error) { |
| | | this.$Message.error("修改失败: " + error.message); |
| | | console.error(error); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | }, |
| | | |
| | | // 取消按钮 |
| | | handleCancel() { |
| | | this.visible = false; |
| | | this.$emit("cancel"); |
| | | } |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .image-grid { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .image-item { |
| | | position: relative; |
| | | width: 100px; |
| | | height: 100px; |
| | | border: 1px solid #ddd; |
| | | border-radius: 4px; |
| | | cursor: pointer; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .image-item:hover { |
| | | border-color: #57a3f3; |
| | | } |
| | | |
| | | .image-item.selected { |
| | | border-color: #57a3f3; |
| | | box-shadow: 0 0 0 2px rgba(45, 140, 240, 0.2); |
| | | } |
| | | |
| | | .image-preview { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | } |
| | | |
| | | .selected-overlay { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-color: rgba(0, 0, 0, 0.5); |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .image-upload-container { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .image-preview-container { |
| | | position: relative; |
| | | width: 100px; |
| | | height: 100px; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .uploaded-image { |
| | | width: 100%; |
| | | height: 100%; |
| | | object-fit: cover; |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .delete-icon { |
| | | position: absolute; |
| | | top: -8px; |
| | | right: -8px; |
| | | width: 20px; |
| | | height: 20px; |
| | | background-color: #ed4014; |
| | | border-radius: 50%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | color: #fff; |
| | | } |
| | | |
| | | .upload-btn { |
| | | width: 100px; |
| | | height: 100px; |
| | | border: 1px dashed #dcdee2; |
| | | border-radius: 4px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | color: #999; |
| | | } |
| | | |
| | | .upload-btn:hover { |
| | | border-color: #57a3f3; |
| | | color: #57a3f3; |
| | | } |
| | | </style> |