Sfoglia il codice sorgente

修改订单评价

hurx 1 mese fa
parent
commit
3ebd9ed6d8

+ 13 - 3
src/api/pc/enterprise/order.ts

@@ -126,7 +126,7 @@ export function batchConfirmation(orderIds: number[]) {
  */
 export function getEvalutionList(params?: any) {
   return request({
-    url: '/order/pcOrderEvaluation/list',
+    url: '/order/pcOrderEvaluationHeader/list',
     method: 'get',
     params: params
   });
@@ -137,7 +137,7 @@ export function getEvalutionList(params?: any) {
  */
 export function addOrderEvaluation(data: any) {
   return request({
-    url: '/order/pcOrderEvaluation',
+    url: '/order/pcOrderEvaluationHeader',
     method: 'post',
     data: data
   });
@@ -145,11 +145,21 @@ export function addOrderEvaluation(data: any) {
 
 export function getOrderEvaluation(id: number) {
   return request({
-    url: `/order/pcOrderEvaluation/${id}`,
+    url: `/order/pcOrderEvaluationHeader/${id}`,
     method: 'get'
   });
 }
 
+export function getOrderEvaluationHeader(orderId: string | number) {
+  return request({
+    url: `/order/pcOrderEvaluationHeader/info/byOrder`,
+    method: 'get',
+    params: {
+      orderId
+    }
+  });
+}
+
 // ==================== 订单流程管理 ====================
 
 /**

+ 6 - 0
src/router/index.ts

@@ -200,6 +200,12 @@ export const constantRoutes: RouteRecordRaw[] = [
         component: () => import('@/views/order/orderEvaluation/index.vue'),
         meta: { title: '订单评价', workbench: true }
       },
+      {
+        path: '/order/orderEvaluation/evaluation',
+        name: 'EvaluationAdd',
+        component: () => import('@/views/order/orderEvaluation/evaluation.vue'),
+        meta: { title: '新增评价', workbench: true }
+      },
       {
         path: '/plan',
         component: () => import('@/views/plan/index.vue'),

+ 2 - 1
src/utils/siteConfig.ts

@@ -56,7 +56,8 @@ export const SITE_ROUTES: Record<any, string[]> = {
     '/enterprise/securitySetting',
     '/enterprise/securitySetting/resetPassword',
     '/enterprise/securitySetting/changePhone',
-    '/enterprise/changePerson'
+    '/enterprise/changePerson',
+    '/order/orderEvaluation/evaluation'
   ], //订单列表
 
   i: ['/i'], //个人信息

+ 25 - 10
src/views/enterprise/changePerson/index.vue

@@ -104,6 +104,7 @@
 import { ref, reactive } from 'vue';
 import { Check, CircleCheckFilled } from '@element-plus/icons-vue';
 import { ElMessage } from 'element-plus';
+import { smsCode } from '@/api/breg/index';
 
 const currentStep = ref(1);
 
@@ -112,29 +113,43 @@ const step1Form = reactive({
   code: '',
   verified: false
 });
-
+const timer = ref<any>(null);
 const step2Form = reactive({
   person: ''
 });
 
 const countdown = ref(0);
 
-// 发送验证码模拟方法
+// 发送验证码
 const handleSendCode = () => {
-  if (!step1Form.phone) {
-    ElMessage.warning('请输入手机号码');
+  if (countdown.value > 0) return;
+  if (step1Form.phone) {
+    smsCode({ phonenumber: step1Form.phone }).then((res: any) => {
+      if (res.code == 200) {
+        ElMessage({
+          message: '验证码已发送',
+          type: 'success'
+        });
+        startCountdown();
+      }
+    });
+  } else {
+    ElMessage({
+      message: '请输入正确的手机号码',
+      type: 'warning'
+    });
     return;
   }
+};
+
+// 启动倒计时
+const startCountdown = () => {
   countdown.value = 60;
-  const timer = setInterval(() => {
+
+  timer.value = setInterval(() => {
     countdown.value--;
-    if (countdown.value <= 0) {
-      clearInterval(timer);
-    }
   }, 1000);
-  ElMessage.success('验证码已发送');
 };
-
 const handleNextStep = () => {
   if (!step1Form.phone || !step1Form.code) {
     ElMessage.warning('请填写完整的手机号和验证码');

+ 37 - 11
src/views/enterprise/securitySetting/resetPassword.vue

@@ -45,14 +45,12 @@
       <div class="step-content" v-if="currentStep === 1">
         <el-form ref="step1FormRef" :model="step1Form" :rules="step1Rules" label-width="100px" class="verify-form">
           <el-form-item label="手机号码:" prop="phone">
-            <el-input v-model="step1Form.phone" disabled class="form-input" />
+            <el-input v-model="step1Form.phone" disabled class="form-input"> </el-input>
             <span class="form-tip">若该手机号已无法使用请联系客服</span>
           </el-form-item>
           <el-form-item label="验证码:" prop="code">
             <el-input v-model="step1Form.code" placeholder="短信验证码" class="form-input code-input" />
-            <el-button link type="primary" class="send-code-btn" :disabled="countdown > 0" @click="handleSendCode">
-              {{ countdown > 0 ? `${countdown}s后重发` : '发送验证码' }}
-            </el-button>
+            <el-button @click="handleSendCode" :class="['code', countdown > 0 ? 'disabled' : '']"> {{ codeText }}</el-button>
           </el-form-item>
           <el-form-item label="" class="verify-checkbox">
             <el-checkbox v-model="step1Form.verified">点击验证</el-checkbox>
@@ -98,7 +96,7 @@ import { Check, CircleCheckFilled } from '@element-plus/icons-vue';
 import { ElMessage } from 'element-plus';
 import { useRoute } from 'vue-router';
 import { changePwd } from '@/api/pc/enterprise/index';
-
+import { smsCode } from '@/api/breg/index';
 const currentStep = ref(1);
 const route = useRoute();
 
@@ -109,8 +107,9 @@ const step1Form = reactive({
   code: '',
   verified: false
 });
-
-const countdown = ref(0);
+const codeText = ref<string>('发送验证码');
+const countdown = ref<number>(0);
+const timer = ref<any>(null);
 
 const step1Rules = {
   code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
@@ -144,14 +143,41 @@ const step2Rules = {
 
 // 发送验证码
 const handleSendCode = () => {
+  if (countdown.value > 0) return;
+  if (step1Form.phone) {
+    smsCode({ phonenumber: step1Form.phone }).then((res: any) => {
+      if (res.code == 200) {
+        ElMessage({
+          message: '验证码已发送',
+          type: 'success'
+        });
+        startCountdown();
+      }
+    });
+  } else {
+    ElMessage({
+      message: '请输入正确的手机号码',
+      type: 'warning'
+    });
+    return;
+  }
+};
+
+// 启动倒计时
+const startCountdown = () => {
   countdown.value = 60;
-  const timer = setInterval(() => {
+  codeText.value = `${countdown.value}s 后重新发送`;
+
+  timer.value = setInterval(() => {
     countdown.value--;
-    if (countdown.value <= 0) {
-      clearInterval(timer);
+    if (countdown.value > 0) {
+      codeText.value = `${countdown.value}s 后重新发送`;
+    } else {
+      clearInterval(timer.value);
+      timer.value = null;
+      codeText.value = '发送验证码';
     }
   }, 1000);
-  ElMessage.success('验证码已发送');
 };
 
 // 下一步

+ 448 - 0
src/views/order/orderEvaluation/evaluation.vue

@@ -0,0 +1,448 @@
+<template>
+  <div class="evaluation-page">
+    <div class="evaluation-header">
+      <div class="header-left">
+        <span class="header-title">评价订单</span>
+        <span class="header-info">订单号:{{ orderInfo.orderNo }}</span>
+        <span class="header-info">{{ orderInfo.orderTime }}</span>
+      </div>
+      <div class="header-right">
+        <el-button type="primary" @click="handleSubmitEvaluate">提交评价</el-button>
+        <el-button type="info" @click="handleBack">返回</el-button>
+      </div>
+    </div>
+    <div class="evaluate-content">
+      <!-- 物流服务评价 -->
+      <div class="logistics-evaluation">
+        <div class="section-title">物流服务评价</div>
+        <div class="logistics-ratings">
+          <div class="rating-item">
+            <span class="rating-label">快递包装</span>
+            <el-rate v-model="evaluateForm.expressPacking" :colors="rateColors" />
+          </div>
+          <div class="rating-item">
+            <span class="rating-label">送货速度</span>
+            <el-rate v-model="evaluateForm.deliverySpeed" :colors="rateColors" />
+          </div>
+          <div class="rating-item">
+            <span class="rating-label">配送员评价</span>
+            <el-rate v-model="evaluateForm.deliveryManRating" :colors="rateColors" />
+          </div>
+        </div>
+      </div>
+      <!-- 商品评价列表 -->
+      <div v-for="(item, index) in evaluateForm.productEvaluations" :key="index" class="product-evaluation-item">
+        <div class="product-left">
+          <div class="product-image">
+            <el-image :src="item.image" fit="contain">
+              <template #error>
+                <div class="image-placeholder">
+                  <el-icon :size="30" color="#ccc"><Picture /></el-icon>
+                </div>
+              </template>
+            </el-image>
+          </div>
+          <div class="product-name">{{ item.name }}</div>
+          <div class="product-code">{{ item.productNo }}</div>
+        </div>
+        <div class="product-right">
+          <div class="evaluation-hint">
+            <el-icon color="#e6a23c"><WarningFilled /></el-icon>
+            <span>请至少填写一件商品的评价</span>
+          </div>
+          <div class="rating-row">
+            <span class="field-label">商品评价</span>
+            <el-rate v-model="item.rating" :colors="rateColors" />
+          </div>
+          <div class="content-row">
+            <span class="field-label">评价晒单</span>
+            <el-input v-model="item.content" type="textarea" :rows="4" placeholder="请输入评价内容" maxlength="200" />
+          </div>
+          <div class="upload-row">
+            <el-upload
+              class="upload-box"
+              :action="action"
+              :show-file-list="false"
+              :on-success="(res) => handleProductUploadSuccess(res, index)"
+              :before-upload="beforeAvatarUpload"
+            >
+              <div v-if="item.imageUrl" class="upload-preview">
+                <el-image :src="item.imageUrl" fit="cover" />
+              </div>
+              <div v-else class="upload-placeholder">
+                <el-icon :size="24"><Plus /></el-icon>
+              </div>
+            </el-upload>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, onMounted } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+import { Picture, Plus, WarningFilled } from '@element-plus/icons-vue';
+import { ElMessage } from 'element-plus';
+import type { UploadProps } from 'element-plus';
+import { getOrderProducts, addOrderEvaluation, getOrderEvaluation, getOrderEvaluationHeader } from '@/api/pc/enterprise/order';
+
+const action = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
+const router = useRouter();
+const route = useRoute();
+
+const rateColors = ['#f7ba2a', '#f7ba2a', '#f7ba2a'];
+
+const orderInfo = reactive({
+  orderId: '',
+  orderNo: '',
+  orderTime: ''
+});
+
+const evaluateForm = reactive({
+  expressPacking: 5,
+  deliverySpeed: 5,
+  deliveryManRating: 5,
+  evaluationType: 1 as number,
+  productEvaluations: [] as any[]
+});
+
+// 加载订单商品
+const loadOrderProducts = async (orderId: string) => {
+  try {
+    const res = await getOrderProducts([Number(orderId)]);
+    if (res.code === 200 && res.rows) {
+      return res.rows.map((product: any) => ({
+        orderItemId: product.id,
+        productId: product.productId,
+        name: product.productName || '',
+        productName: product.productName || '',
+        productNo: product.productNo || '',
+        image: product.productImage || '',
+        productImg: product.productImage || '',
+        rating: 5,
+        content: '',
+        imageUrl: ''
+      }));
+    }
+    return [];
+  } catch (error) {
+    console.error('加载订单商品失败:', error);
+    return [];
+  }
+};
+
+// 加载已有评价数据(追评/查看)
+const loadExistingEvaluation = async (orderId: string) => {
+  try {
+    const res = await getOrderEvaluationHeader(orderId);
+    if (res.code === 200 && res.data) {
+      // 回显物流评分
+      evaluateForm.expressPacking = res.data.logisticsPackScore || 5;
+      evaluateForm.deliverySpeed = res.data.deliverSpeedScore || 5;
+      evaluateForm.deliveryManRating = res.data.courierServiceScore || 5;
+
+      // 回显商品评价内容
+      const itemList = res.data.orderEvaluationItemList || [];
+      if (itemList.length > 0 && evaluateForm.productEvaluations.length > 0) {
+        // 按 orderItemId 或 productId 匹配回显
+        itemList.forEach((evalItem: any) => {
+          const productIndex = evaluateForm.productEvaluations.findIndex(
+            (p: any) => p.orderItemId === evalItem.orderItemId || p.productId === evalItem.productId
+          );
+          if (productIndex !== -1) {
+            evaluateForm.productEvaluations[productIndex].rating = evalItem.productScore || 5;
+            evaluateForm.productEvaluations[productIndex].content = evalItem.content || '';
+            evaluateForm.productEvaluations[productIndex].imageUrl = evalItem.images || '';
+          }
+        });
+      }
+    }
+  } catch (error) {
+    console.error('加载评价数据失败:', error);
+  }
+};
+
+//上传成功(按商品索引)
+const handleProductUploadSuccess = (res: any, index: number) => {
+  if (res.code == 200) {
+    evaluateForm.productEvaluations[index].imageUrl = res.data.url;
+  } else {
+    ElMessage({ message: res.msg, type: 'warning' });
+  }
+};
+
+const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
+  if (rawFile.size / 1024 / 1024 > 2) {
+    ElMessage.error('不能大于2MB!');
+    return false;
+  }
+  return true;
+};
+
+const handleSubmitEvaluate = async () => {
+  const hasEvaluation = evaluateForm.productEvaluations.some((item: any) => item.content);
+  if (!hasEvaluation) {
+    ElMessage.warning('请至少填写一件商品的评价');
+    return;
+  }
+
+  try {
+    const submitData = {
+      orderId: orderInfo.orderId,
+      orderNo: orderInfo.orderNo,
+      logisticsPackScore: evaluateForm.expressPacking,
+      deliverSpeedScore: evaluateForm.deliverySpeed,
+      courierServiceScore: evaluateForm.deliveryManRating,
+      evaluationType: evaluateForm.evaluationType,
+      orderEvaluationItemList: evaluateForm.productEvaluations
+        .filter((item: any) => item.content)
+        .map((item: any) => ({
+          orderItemId: item.orderItemId,
+          productId: item.productId,
+          productName: item.productName || item.name,
+          productImg: item.productImg || item.image,
+          productScore: item.rating,
+          content: item.content,
+          images: item.imageUrl ? String(item.imageUrl) : ''
+        }))
+    };
+
+    const res = await addOrderEvaluation(submitData);
+    if (res.code === 200) {
+      ElMessage.success('评价提交成功');
+      router.back();
+    } else {
+      ElMessage.error(res.msg || '评价提交失败');
+    }
+  } catch (error) {
+    console.error('评价提交失败:', error);
+    ElMessage.error('评价提交失败');
+  }
+};
+
+const handleBack = () => {
+  router.back();
+};
+
+onMounted(async () => {
+  const orderId = String(route.query.orderId || '');
+  const type = Number(route.query.type) || 1;
+  const orderNo = (route.query.orderNo as string) || '';
+  const orderTime = (route.query.orderTime as string) || '';
+
+  orderInfo.orderId = orderId;
+  orderInfo.orderNo = orderNo;
+  orderInfo.orderTime = orderTime;
+  evaluateForm.evaluationType = type;
+
+  if (orderId) {
+    // 优先从 history state 获取已加载的商品数据
+    const stateProducts = history.state?.products;
+    let products: any[] = [];
+    if (stateProducts) {
+      try {
+        const parsed = JSON.parse(stateProducts);
+        products = parsed.map((p: any) => ({
+          orderItemId: p.id,
+          productId: p.productId,
+          name: p.productName || p.name,
+          productName: p.productName || p.name,
+          productNo: p.spec2,
+          image: p.productImg || p.image,
+          productImg: p.productImg || p.image,
+          rating: 5,
+          content: '',
+          imageUrl: ''
+        }));
+      } catch (e) {
+        products = await loadOrderProducts(orderId);
+      }
+    } else {
+      products = await loadOrderProducts(orderId);
+    }
+    evaluateForm.productEvaluations = products;
+
+    // 追评或查看评价时,加载已有评价
+    if (type === 2 || type === 3) {
+      await loadExistingEvaluation(orderId);
+    }
+  }
+});
+</script>
+
+<style scoped lang="scss">
+.evaluation-page {
+  padding: 20px;
+  background: #fff;
+  min-height: 100%;
+  width: 100%;
+}
+
+.evaluation-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  .header-left {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+    .header-title {
+      font-size: 16px;
+      font-weight: bold;
+      color: #333;
+    }
+    .header-info {
+      font-size: 14px;
+      color: #666;
+    }
+  }
+  .header-right {
+    display: flex;
+    gap: 8px;
+  }
+}
+
+.evaluate-content {
+  .logistics-evaluation {
+    border: 1px solid #eee;
+    border-radius: 4px;
+    padding: 20px;
+    margin-bottom: 20px;
+    .section-title {
+      font-size: 14px;
+      font-weight: bold;
+      color: #e6a23c;
+      margin-bottom: 15px;
+    }
+    .logistics-ratings {
+      display: flex;
+      gap: 40px;
+      .rating-item {
+        display: flex;
+        align-items: center;
+        gap: 10px;
+        .rating-label {
+          font-size: 13px;
+          color: #666;
+          white-space: nowrap;
+        }
+      }
+    }
+  }
+
+  .product-evaluation-item {
+    display: flex;
+    border: 1px solid #eee;
+    border-radius: 4px;
+    padding: 20px;
+    margin-bottom: 15px;
+    gap: 30px;
+
+    .product-left {
+      width: 180px;
+      flex-shrink: 0;
+      .product-image {
+        width: 100px;
+        height: 100px;
+        background: #f5f5f5;
+        border-radius: 4px;
+        overflow: hidden;
+        margin-bottom: 10px;
+        .el-image {
+          width: 100%;
+          height: 100%;
+        }
+        .image-placeholder {
+          width: 100%;
+          height: 100%;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+        }
+      }
+      .product-name {
+        font-size: 13px;
+        color: #333;
+        margin-bottom: 6px;
+        line-height: 1.4;
+      }
+      .product-code {
+        font-size: 12px;
+        color: #e6a23c;
+      }
+    }
+
+    .product-right {
+      flex: 1;
+      .evaluation-hint {
+        display: flex;
+        align-items: center;
+        gap: 5px;
+        font-size: 13px;
+        color: #e6a23c;
+        margin-bottom: 15px;
+      }
+      .rating-row {
+        display: flex;
+        align-items: center;
+        gap: 10px;
+        margin-bottom: 15px;
+      }
+      .content-row {
+        display: flex;
+        gap: 10px;
+        margin-bottom: 15px;
+      }
+      .field-label {
+        font-size: 13px;
+        color: #666;
+        white-space: nowrap;
+        line-height: 32px;
+      }
+      .upload-row {
+        padding-left: 65px;
+      }
+    }
+  }
+}
+
+.upload-box {
+  :deep(.el-upload) {
+    width: 100px;
+    height: 100px;
+    border: 1px dashed #d9d9d9;
+    border-radius: 6px;
+    cursor: pointer;
+    overflow: hidden;
+
+    &:hover {
+      border-color: #e60012;
+    }
+  }
+
+  .upload-placeholder {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    justify-content: center;
+    color: #999;
+    font-size: 12px;
+    gap: 5px;
+  }
+
+  .upload-preview {
+    width: 100%;
+    height: 100%;
+
+    .el-image {
+      width: 100%;
+      height: 100%;
+    }
+  }
+}
+</style>

+ 24 - 238
src/views/order/orderEvaluation/index.vue

@@ -108,52 +108,6 @@
       </div>
       <el-empty v-if="orderList.length === 0" description="暂无订单" />
     </div>
-
-    <el-dialog v-model="evaluateDialogVisible" :title="evaluateDialogTitle" width="600px">
-      <div class="evaluate-product">
-        <div class="product-image">
-          <el-image :src="currentProduct?.image" fit="contain">
-            <template #error
-              ><div class="image-placeholder">
-                <el-icon :size="30" color="#ccc"><Picture /></el-icon></div
-            ></template>
-          </el-image>
-        </div>
-        <div class="product-info">
-          <div class="product-name">{{ currentProduct?.name }}</div>
-          <div class="product-spec">{{ currentProduct?.spec1 }} {{ currentProduct?.spec2 }}</div>
-        </div>
-      </div>
-      <el-form ref="evaluateFormRef" :model="evaluateForm" :rules="evaluateRules" label-width="80px">
-        <el-form-item label="商品评分" prop="deliverGoods">
-          <el-rate v-model="evaluateForm.deliverGoods" :colors="['#e60012', '#e60012', '#e60012']" />
-        </el-form-item>
-        <el-form-item label="评价内容" prop="content">
-          <el-input v-model="evaluateForm.content" type="textarea" :rows="4" placeholder="请输入评价内容" maxlength="200" show-word-limit />
-        </el-form-item>
-        <el-form-item label="上传图片">
-          <el-upload
-            class="upload-box"
-            :action="action"
-            :show-file-list="false"
-            :on-success="handleEvaluateUrlSuccess"
-            :before-upload="beforeAvatarUpload"
-          >
-            <div v-if="evaluateForm.evaluateUrl" class="upload-preview">
-              <el-image :src="evaluateForm.evaluateUrl" fit="cover" />
-            </div>
-            <div v-else class="upload-placeholder">
-              <el-icon :size="24"><Plus /></el-icon>
-              <span>上传</span>
-            </div>
-          </el-upload>
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <el-button @click="evaluateDialogVisible = false">取消</el-button>
-        <el-button type="danger" @click="handleSubmitEvaluate">提交评价</el-button>
-      </template>
-    </el-dialog>
   </div>
 </template>
 
@@ -163,21 +117,14 @@ import { useRouter } from 'vue-router';
 import { Search, Edit, ChatDotRound, Document, ArrowRight, Picture, Plus } from '@element-plus/icons-vue';
 import { ElMessage } from 'element-plus';
 import { PageTitle, StatusTabs } from '@/components';
-import { getOrderList, getOrderProducts, getEvalutionList, addOrderEvaluation, getOrderEvaluation } from '@/api/pc/enterprise/order';
+import { getOrderList, getOrderProducts, getEvalutionList } from '@/api/pc/enterprise/order';
 import type { OrderMain, OrderStatusStats } from '@/api/pc/enterprise/orderTypes';
 import { getDeptTree } from '@/api/pc/organization';
 import { DeptInfo } from '@/api/pc/organization/types';
-const action = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { order_status, pay_method } = toRefs<any>(proxy?.useDict('order_status', 'pay_method'));
-import type { UploadProps } from 'element-plus';
 const router = useRouter();
 const activeMainTab = ref('0');
-const evaluateDialogVisible = ref(false);
-const evaluateDialogTitle = ref('商品评价');
-const evaluateFormRef = ref();
-const currentOrder = ref<any>(null);
-const currentProduct = ref<any>(null);
 
 const deptList = ref([]);
 
@@ -188,11 +135,6 @@ const mainTabs = [
 ];
 
 const queryParams = reactive({ keyword: '', dateRange: null, department: '', status: '', payType: '', evaluationStatus: '' });
-const evaluateForm = reactive({ deliverGoods: 5, content: '', evaluationType: null, evaluateUrl: '' });
-const evaluateRules = {
-  deliverGoods: [{ required: true, message: '请选择评分', trigger: 'change' }],
-  content: [{ required: true, message: '请输入评价内容', trigger: 'blur' }]
-};
 
 const pendingOrders = ref([]);
 const followUpOrders = ref([]);
@@ -232,12 +174,15 @@ const loadOrderProducts = async (orderId: number) => {
     if (res.code === 200 && res.rows) {
       return res.rows.map((product: any) => ({
         id: product.id,
+        productId: product.productId,
         name: product.productName || '',
+        productName: product.productName || '',
         spec1: product.productUnit || '',
         spec2: product.productNo || '',
         price: product.orderPrice || 0,
         quantity: product.orderQuantity || 0,
-        image: product.productImage || ''
+        image: product.productImage || '',
+        productImg: product.productImage || ''
       }));
     }
     return [];
@@ -305,27 +250,6 @@ const getorders = async () => {
   }
 };
 
-//上传成功
-const handleEvaluateUrlSuccess = (res: any) => {
-  if (res.code == 200) {
-    evaluateForm.evaluateUrl = res.data.url;
-  } else {
-    ElMessage({
-      message: res.msg,
-      type: 'warning'
-    });
-  }
-  console.log(res);
-};
-
-const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
-  if (rawFile.size / 1024 / 1024 > 2) {
-    ElMessage.error('不能大于2MB!');
-    return false;
-  }
-  return true;
-};
-
 // 监听标签页切换,重新获取数据
 watch(activeMainTab, () => {
   getorders();
@@ -354,90 +278,28 @@ const loadDeptTree = async () => {
 const handleViewDetail = (order: any) => {
   router.push(`/order/orderManage/detail/${order.orderId}`);
 };
-const handleEvaluate = (order: any) => {
-  currentOrder.value = order;
-  currentProduct.value = order.products[0];
-  evaluateDialogTitle.value = '商品评价';
-  evaluateForm.deliverGoods = undefined;
-  evaluateForm.content = '';
-  evaluateForm.evaluationType = 1;
-  evaluateDialogVisible.value = true;
+const navigateToEvaluation = (order: any, type: number) => {
+  router.push({
+    path: '/order/orderEvaluation/evaluation',
+    query: {
+      orderId: order.orderId,
+      orderNo: order.orderNo,
+      orderTime: order.orderTime,
+      type: type
+    },
+    state: {
+      products: JSON.stringify(order.products)
+    }
+  } as any);
 };
-const handleFollowUpEvaluate = async (order: any) => {
-  const res = await getOrderEvaluation(order.orderId);
-  if (res.code === 200 && res.data) {
-    currentOrder.value = order;
-    currentProduct.value = order.products[0];
-    evaluateDialogTitle.value = '追加评价';
-    evaluateForm.deliverGoods = res.data.deliverGoods;
-    evaluateForm.content = res.data.content;
-    evaluateForm.evaluationType = 2;
-    evaluateDialogVisible.value = true;
-  } else {
-    ElMessage.error('获取评价失败');
-  }
+const handleEvaluate = (order: any) => {
+  navigateToEvaluation(order, 1);
 };
-const handleViewEvaluation = async (order: any) => {
-  const res = await getOrderEvaluation(order.orderId);
-  if (res.code === 200 && res.data) {
-    currentOrder.value = order;
-    currentProduct.value = order.products[0];
-    evaluateDialogTitle.value = '查看评价';
-    evaluateForm.deliverGoods = res.data.deliverGoods;
-    evaluateForm.content = res.data.content;
-    evaluateDialogVisible.value = true;
-  } else {
-    ElMessage.error('获取评价失败');
-  }
+const handleFollowUpEvaluate = (order: any) => {
+  navigateToEvaluation(order, 2);
 };
-const handleSubmitEvaluate = async () => {
-  const valid = await evaluateFormRef.value?.validate();
-  if (!valid) return;
-
-  try {
-    const submitData = {
-      orderId: currentOrder.value?.orderId,
-      productId: currentProduct.value?.id,
-      evaluationType: evaluateForm.evaluationType, // 1-评价 2-追评
-      deliverGoods: evaluateForm.deliverGoods,
-      content: evaluateForm.content,
-      // 图片上传暂时留空,后续可以添加
-      images: []
-    };
-
-    const res = await addOrderEvaluation(submitData);
-    if (res.code === 200) {
-      ElMessage.success('评价提交成功');
-      evaluateDialogVisible.value = false;
-
-      // 重新获取订单列表
-      await getorders();
-
-      // 如果需要手动更新本地数据(可选)
-      if (activeMainTab.value === '0') {
-        const index = pendingOrders.value.findIndex((o) => o.orderId === currentOrder.value.orderId);
-        if (index > -1) {
-          const order = pendingOrders.value.splice(index, 1)[0];
-          if (evaluateForm.evaluationType === '1') {
-            followUpOrders.value.push(order);
-          } else {
-            evaluatedOrders.value.push(order);
-          }
-        }
-      } else if (activeMainTab.value === '1') {
-        const index = followUpOrders.value.findIndex((o) => o.orderId === currentOrder.value.orderId);
-        if (index > -1) {
-          const order = followUpOrders.value.splice(index, 1)[0];
-          evaluatedOrders.value.push(order);
-        }
-      }
-    } else {
-      ElMessage.error(res.msg || '评价提交失败');
-    }
-  } catch (error) {
-    console.error('评价提交失败:', error);
-    ElMessage.error('评价提交失败');
-  }
+const handleViewEvaluation = (order: any) => {
+  navigateToEvaluation(order, 3);
 };
 
 // 页面加载时获取订单列表
@@ -616,80 +478,4 @@ onMounted(() => {
     }
   }
 }
-.upload-box {
-  :deep(.el-upload) {
-    width: 100px;
-    height: 100px;
-    border: 1px dashed #d9d9d9;
-    border-radius: 6px;
-    cursor: pointer;
-    overflow: hidden;
-
-    &:hover {
-      border-color: #e60012;
-    }
-  }
-
-  .upload-placeholder {
-    width: 100%;
-    height: 100%;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-    justify-content: center;
-    color: #999;
-    font-size: 12px;
-    gap: 5px;
-  }
-
-  .upload-preview {
-    width: 100%;
-    height: 100%;
-
-    .el-image {
-      width: 100%;
-      height: 100%;
-    }
-  }
-}
-
-.evaluate-product {
-  display: flex;
-  align-items: center;
-  gap: 15px;
-  padding: 15px;
-  background: #f9f9f9;
-  border-radius: 4px;
-  margin-bottom: 20px;
-  .product-image {
-    width: 60px;
-    height: 60px;
-    background: #fff;
-    border-radius: 4px;
-    overflow: hidden;
-    flex-shrink: 0;
-    .el-image {
-      width: 100%;
-      height: 100%;
-    }
-    .image-placeholder {
-      width: 100%;
-      height: 100%;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-    }
-  }
-  .product-info {
-    .product-name {
-      font-size: 14px;
-      color: #333;
-      margin-bottom: 5px;
-    }
-    .product-spec {
-      font-size: 12px;
-      color: #999;
-    }
-  }
-}
 </style>

+ 6 - 6
src/views/order/orderManage/applyAfter.vue

@@ -58,7 +58,7 @@
               <div class="col col-available">未售后数量</div>
               <div class="col col-qty">退货数量</div>
               <div class="col col-amount">退货金额</div>
-              <div class="col col-op">操作</div>
+              <!-- <div class="col col-op">操作</div> -->
             </div>
 
             <div v-if="selectedProducts.length === 0" class="table-empty">
@@ -87,18 +87,18 @@
               <div class="col col-qty">
                 <el-input-number
                   v-model="item.returnQuantity"
-                  :min="0"
+                  :min="item.soldQty"
                   :max="item.availableQty"
                   controls-position="right"
-                  size="small"
                   :controls="false"
+                  disabled
                   @change="handleQtyChange"
                 />
               </div>
               <div class="col col-amount">¥{{ formatMoney(item.returnQuantity * item.unitPrice) }}</div>
-              <div class="col col-op">
+              <!-- <div class="col col-op">
                 <el-button type="danger" link @click="handleRemoveProduct(item.productId)">删除</el-button>
-              </div>
+              </div> -->
             </div>
           </div>
         </div>
@@ -210,7 +210,7 @@ import { getOrderReturnInfo, addOrderReturn } from '@/api/pc/enterprise/orderRet
 import type { OrderReturn } from '@/api/pc/enterprise/orderReturnTypes';
 const action = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
 import type { UploadProps } from 'element-plus';
-const topBtnFlag = ref(true);
+const topBtnFlag = ref(false);
 const router = useRouter();
 const route = useRoute();
 const loading = ref(false);