peng
2025-10-16 877c9a8df95ff61fbe556b8d1f4cf417252ee256
用户行为分析
2个文件已修改
1个文件已添加
532 ■■■■■ 已修改文件
seller/src/api/order.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller/src/views/order/order/editTemplateModal.vue 479 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller/src/views/order/order/orderDetail.vue 40 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller/src/api/order.js
@@ -168,3 +168,16 @@
export const getTracesList = (sn) => {
  return getRequest(`/order/order/getTracesList/${sn}`);
}
//获取模板
export const getTemplate = (templateId) => {
  return getRequest(`/order/order/getTemplate/${templateId}`);
}
//修改模板
export const editTemplate = (params) => {
  return postRequest(`/order/order/edit/template`,params,{
    "Content-type": "application/json"
  })
}
seller/src/views/order/order/editTemplateModal.vue
New file
@@ -0,0 +1,479 @@
<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>
seller/src/views/order/order/orderDetail.vue
@@ -157,6 +157,7 @@
                  <div class="div-item-left">商品模板:</div>
                  <div class="div-item-right">
                    {{ item.templateName || '无模板标题' }} <!-- 处理空值默认显示 -->
                    <Button size="small" @click="editTemplateInfo(item.templateId, sn)" style="margin-left: 10px;">编辑</Button>
                  </div>
                </div>
                <!-- 4. 选择图片:渲染 chooseImg 字段(处理 null/空值) -->
@@ -181,8 +182,6 @@
              </div>
            </div>
            <!-- 3. 文本内容:判断 content 是「图片URL」还是「纯文本」 -->
            <div class="div-item">
              <div class="div-item-left">{{isUrl(item.content)? '图片:':'文本内容'}}</div>
@@ -198,8 +197,6 @@
                <span v-else>{{ item.content || '无文本内容' }}</span> <!-- 纯文本/空值处理 -->
              </div>
            </div>
            <!-- 可选:循环项分隔线,优化视觉 -->
            <hr v-if="index !== orderInfo.userCheckTemplates.length - 1" style="margin: 15px 0; border: none; border-top: 1px solid #eee;">
@@ -642,6 +639,15 @@
    </Modal>
    <multipleMap ref="map" @callback="getAddress"></multipleMap>
    <!-- 添加模板编辑弹窗 -->
    <EditTemplateModal
      v-model="editTemplateModalVisible"
      :template-id="currentTemplateId"
      :order-sn="sn"
      @success="handleTemplateEditSuccess"
      @cancel="editTemplateModalVisible = false"
    />
  </div>
</template>
@@ -651,12 +657,13 @@
import * as RegExp from "@/libs/RegExp.js";
import multipleMap from "@/views/my-components/map/multiple-map";
import EditTemplateModal from "./editTemplateModal.vue";
export default {
  name: "orderDetail",
  components: {
    multipleMap,
    EditTemplateModal
  },
  data () {
    return {
@@ -1013,7 +1020,10 @@
        },
      ],
      orderPackage: [],
      packageTraceList: []
      packageTraceList: [],
      // 添加模板编辑弹窗相关数据
      editTemplateModalVisible: false,
      currentTemplateId: ""
    };
  },
  methods: {
@@ -1423,6 +1433,24 @@
      })
    },
    // 编辑模板信息
    editTemplateInfo(templateId, orderSn) {
      console.log("调用editTemplateInfo,参数:", {
        templateId: templateId,
        orderSn: orderSn
      });
      this.currentTemplateId = templateId;
      this.editTemplateModalVisible = true;
    },
    // 模板编辑成功回调
    handleTemplateEditSuccess() {
      this.editTemplateModalVisible = false;
      // 可以在这里刷新数据或提示用户
      this.$Message.success("模板信息已更新");
      // 刷新订单详情页面数据
      this.getDataDetail();
    }
  },
  mounted () {
    this.sn = this.$route.query.sn;