Alex vor 1 Jahr
Ursprung
Commit
c698fabc40

+ 77 - 47
src/views/recycleLogistics/abnormalSetting/index.vue

@@ -1,56 +1,86 @@
 <template>
-  <ele-page flex-table>
-    <ele-card flex-table header="异常签收设置">
-      <el-form
-        ref="formRef"
-        style="max-width: 520px"
-        :model="form"
-        label-width="160px"
-      >
-        <el-form-item label="每人每日异常签收限量" prop="abnormalNum1">
-          <el-input v-model="form.abnormalNum1">
-            <template #append>次</template>
-          </el-input>
-        </el-form-item>
-        <el-form-item label="每日异常签收限量" prop="abnormalNum2">
-          <el-input v-model="form.abnormalNum2">
-            <template #append>次</template>
-          </el-input>
-        </el-form-item>
-        <el-form-item label="预留手机号" prop="mobile">
-          <el-input v-model="form.mobile" />
-        </el-form-item>
-        <el-form-item>
-          <el-button
-            style="min-width: 100px"
-            type="primary"
-            @click="submitForm(formRef)"
-            v-permission="'recycleLogistics:abnormalSetting:update'"
-          >
-            确认修改
-          </el-button>
-        </el-form-item>
-      </el-form>
-    </ele-card>
-  </ele-page>
+    <ele-page flex-table>
+        <ele-card flex-table header="异常签收设置">
+            <el-form ref="formRef" style="max-width: 520px" :model="form" :rules="rules" label-width="160px">
+                <el-form-item label="每人每日异常签收限量" prop="maxSignPerNum">
+                    <el-input v-model="form.maxSignPerNum">
+                        <template #append>次</template>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="每日异常签收限量" prop="maxSignDayNum">
+                    <el-input v-model="form.maxSignDayNum">
+                        <template #append>次</template>
+                    </el-input>
+                </el-form-item>
+                <el-form-item label="预留手机号" prop="mobile">
+                    <el-input v-model="form.mobile" :maxlength="11" />
+                </el-form-item>
+                <el-form-item>
+                    <el-button style="min-width: 100px" type="primary" @click="submitForm(formRef)"
+                        v-permission="'recycleLogistics:abnormalSetting:update'">
+                        确认修改
+                    </el-button>
+                </el-form-item>
+            </el-form>
+        </ele-card>
+    </ele-page>
 </template>
 
 <script setup>
-  const formRef = ref(null);
-  const form = reactive({
-    abnormalNum1: '',
-    abnormalNum2: '',
+import { ElMessage } from 'element-plus';
+import { getCurrentInstance } from 'vue'
+const { proxy } = getCurrentInstance();
+
+const formRef = ref(null);
+const form = reactive({
+    maxSignPerNum: '',
+    maxSignDayNum: '',
     mobile: ''
-  });
+});
+
+// 表单验证规则
+const rules = {
+    mobile: [
+        { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号格式', trigger: 'blur' }
+    ]
+};
 
-  const submitForm = async (formEl) => {
+// 获取设置数据
+const getSettings = async () => {
+    const res = await proxy.$http.get('/order/ordersign/routeExceptionSignQuery');
+    if (res.data?.code === 200) {
+        const { maxSignPerNum, maxSignDayNum, mobile } = res.data.data;
+        Object.assign(form, {
+            maxSignPerNum,
+            maxSignDayNum,
+            mobile
+        });
+    }
+};
+
+// 提交表单
+const submitForm = async (formEl) => {
     if (!formEl) return;
-    await formEl.validate((valid, fields) => {
-      if (valid) {
-        console.log('submit!');
-      } else {
-        console.log('error submit!', fields);
-      }
+    await formEl.validate(async (valid, fields) => {
+        if (valid) {
+            const res = await proxy.$http.post('/order/ordersign/routeExceptionSign', {
+                maxSignPerNum: form.maxSignPerNum,
+                maxSignDayNum: form.maxSignDayNum,
+                mobile: form.mobile
+            });
+            if (res.data?.code === 200) {
+                ElMessage.success('设置保存成功');
+            } else {
+                ElMessage.error(res.data.msg)
+            }
+        } else {
+            console.log('error submit!', fields);
+        }
     });
-  };
+};
+
+// 页面加载时获取设置
+onMounted(() => {
+    getSettings();
+});
 </script>

+ 71 - 49
src/views/recycleLogistics/abnormalSign/index.vue

@@ -9,14 +9,16 @@
 
         <template #action="{ row }">
             <div>
-                <el-button type="primary" link v-permission="'recycleLogistics:abnormalSign:agree'"
-                    @click="handleAgree(row)">
-                    [同意]
-                </el-button>
-                <el-button type="danger" link v-permission="'recycleLogistics:abnormalSign:reject'"
-                    @click="handleReject(row)">
-                    [驳回]
-                </el-button>
+                <template v-if="useStatus === '1'">
+                    <el-button type="primary" link v-permission="'recycleLogistics:abnormalSign:agree'"
+                        @click="handleAgree(row)">
+                        [同意]
+                    </el-button>
+                    <el-button type="danger" link v-permission="'recycleLogistics:abnormalSign:reject'"
+                        @click="handleReject(row)">
+                        [驳回]
+                    </el-button>
+                </template>
                 <el-button type="success" link v-permission="'recycleLogistics:abnormalSign:detail'"
                     @click="toOrderDetail(row)">
                     [订单详情]
@@ -25,32 +27,35 @@
                     @click="openOrderLog(row)">
                     [订单日志]
                 </el-button>
-                <el-button type="danger" link v-permission="'recycleLogistics:abnormalSign:cancel'"
-                    @click="handleCancelOrder(row)">
-                    [取消订单]
-                </el-button>
-                <el-button type="primary" link v-permission="'recycleLogistics:abnormalSign:fallback'"
-                    @click="fallbackOrder(row)">
-                    [回退状态]
-                </el-button>
-                <el-button type="success" link v-permission="'recycleLogistics:abnormalSign:receive'"
-                    @click="handleLogisticsSigning(row)">
-                    [物流签收]
-                </el-button>
-                <el-button type="warning" link v-permission="'recycleLogistics:abnormalSign:userTag'"
-                    @click="openEditUserTag(row)">
-                    [用户标签]
-                </el-button>
-                <el-button type="danger" link v-permission="'recycleLogistics:abnormalSign:interception'"
-                    @click="applyForInterception(row)">
-                    [申请拦截退回]
-                </el-button>
+                <template v-if="useStatus === '1'">
+                    <el-button type="danger" link v-permission="'recycleLogistics:abnormalSign:cancel'"
+                        @click="handleCancelOrder(row)">
+                        [取消订单]
+                    </el-button>
+                    <el-button type="primary" link v-permission="'recycleLogistics:abnormalSign:fallback'"
+                        @click="fallbackOrder(row)">
+                        [回退状态]
+                    </el-button>
+                    <el-button type="success" link v-permission="'recycleLogistics:abnormalSign:receive'"
+                        @click="handleLogisticsSigning(row)">
+                        [快递签收]
+                    </el-button>
+                    <el-button type="warning" link v-permission="'recycleLogistics:abnormalSign:userTag'"
+                        @click="openEditUserTag(row)">
+                        [用户标签]
+                    </el-button>
+                    <el-button type="danger" link v-permission="'recycleLogistics:abnormalSign:interception'"
+                        @click="applyForInterception(row)">
+                        [申请拦截退回]
+                    </el-button>
+                </template>
             </div>
         </template>
 
         <component :is="orderLog" ref="orderLogRef" />
         <component :is="orderDetail" ref="orderDetailRef" @refresh="pageRef.value?.reload()" />
         <userBindTag ref="userTagRef" />
+        <reject-modal ref="rejectModalRef" @success="pageRef.value?.reload()" />
     </order-page>
 </template>
 
@@ -63,6 +68,7 @@ import { useRouter } from 'vue-router';
 import { useOrderOperation } from '@/utils/use-order-operation';
 //用户标签
 import userBindTag from '@/views/recycleOrder/components/user-bind-tag.vue';
+import RejectModal from '@/views/recycleLogistics/components/reject-modal.vue';
 
 defineOptions({ name: 'abnormalSign' });
 
@@ -72,20 +78,27 @@ const { proxy } = getCurrentInstance();
 const pageRef = ref(null);
 //用户标签
 const userTagRef = ref(null);
+//驳回弹窗
+const rejectModalRef = ref(null);
 
 const useStatus = ref('1');
-function handleStatusChange() {
-    pageRef.value.reload({ useStatus: useStatus.value });
-}
 
 const pageConfig = reactive({
-    pageUrl: '/order/orderInfo/exceptionOrderList',
-    exportUrl: '/order/orderInfo/exceptionOrderExport',
+    get pageUrl() {
+        return useStatus.value === '1' ? '/order/orderInfo/exceptionOrderList' : '/order/orderInfo/exceptionHistoryList';
+    },
+    get exportUrl() {
+        return useStatus.value === '1' ? '/order/orderInfo/exceptionOrderExport' : '/order/orderInfo/exceptionHistoryExport';
+    },
     fileName: '路由异常签收',
     cacheKey: 'abnormalSignTable',
     params: { status: '1' }
 });
 
+function handleStatusChange() {
+    pageRef.value?.reload();
+}
+
 //用户绑定标签
 function openEditUserTag(row) {
     userTagRef.value?.handleOpen(row);
@@ -98,7 +111,10 @@ function handleAgree(row) {
         cancelButtonText: '关闭',
         type: 'warning'
     }).then(() => {
-        proxy.$http.post(`/order/orderInfo/agreeAbnormalSign/${row.orderId}`).then((res) => {
+        proxy.$http.post('/order/orderInfo/exceptcheck', {
+            id: row.exceptOrderCheckInfo.id,
+            checkStatus: 2
+        }).then((res) => {
             if (res.data.code === 200) {
                 EleMessage.success('操作成功');
                 pageRef.value?.reload();
@@ -111,26 +127,12 @@ function handleAgree(row) {
 
 // 驳回异常签收
 function handleReject(row) {
-    ElMessageBox.confirm('确认驳回异常签收?', '提示', {
-        confirmButtonText: '确定',
-        cancelButtonText: '关闭',
-        type: 'warning'
-    }).then(() => {
-        proxy.$http.post(`/order/orderInfo/rejectAbnormalSign/${row.orderId}`).then((res) => {
-            if (res.data.code === 200) {
-                EleMessage.success('操作成功');
-                pageRef.value?.reload();
-            } else {
-                EleMessage.error(res.data.msg);
-            }
-        });
-    });
+    rejectModalRef.value?.handleOpen(row.orderId);
 }
 
 const { 
     handleCancelOrder, 
     applyForInterception, 
-    handleLogisticsSigning, 
     fallbackOrder,
     toOrderDetail,
     openOrderLog,
@@ -139,4 +141,24 @@ const {
     orderLog,
     orderDetail
 } = useOrderOperation(pageRef);
+
+// Add logistics signing function
+function handleLogisticsSigning(row) {
+    ElMessageBox.confirm('确认签收?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '关闭',
+        type: 'warning'
+    }).then(() => {
+        proxy.$http.post('/order/orderInfo/adminDeliverySigned', {
+            orderId: row.orderId
+        }).then((res) => {
+            if (res.data.code === 200) {
+                EleMessage.success('操作成功');
+                pageRef.value?.reload();
+            } else {
+                EleMessage.error(res.data.msg);
+            }
+        });
+    });
+}
 </script>

+ 42 - 40
src/views/recycleLogistics/components/order-page.vue

@@ -29,30 +29,33 @@
                 <template #sender="{ row }">
                     <div class="common-text">
                         <el-text>推送人:</el-text>
-                        <el-text>周武泰</el-text>
+                        <el-text>{{row.exceptOrderCheckInfo?.createName}}</el-text>
                     </div>
                     <div class="common-text">
                         <el-text>推送时间:</el-text>
-                        <el-text>2024-11-21 10:24:56 </el-text>
+                        <el-text>{{row.exceptOrderCheckInfo?.createTime||'-'}}</el-text>
                     </div>
                 </template>
                 <template #dealer="{ row }">
                     <div class="common-text">
                         <el-text>处理人:</el-text>
-                        <el-text>周武泰</el-text>
+                        <el-text>{{row.exceptOrderCheckInfo?.checkName||'-'}}</el-text>
                     </div>
                     <div class="common-text">
                         <el-text>处理时间:</el-text>
-                        <el-text>2024-11-21 10:24:56 </el-text>
+                        <el-text>{{row.exceptOrderCheckInfo?.checkTime||'-'}}</el-text>
                     </div>
                 </template>
+                <template #checkStatus="{ row }">
+                    <dict-data code="abnormal_check_status" type="tag" :model-value="row.exceptOrderCheckInfo?.checkStatus" />
+                </template>
                 <template #remarks="{ row }">
-                    <el-popover trigger="hover" width="240px">
+                    <el-popover trigger="hover" width="240px" @show="handleShowPopover(row)" @hide="showOrderId = ''">
                         <template #reference>
                             <el-button :icon="Flag" link style="font-size: 20px" @click="handleRemarks(row)">
                             </el-button>
                         </template>
-                        <orderTimeline :records="activities" title="备注历史记录"></orderTimeline>
+                        <orderTimeline :orderId="showOrderId" title="备注历史记录"></orderTimeline>
                     </el-popover>
                 </template>
 
@@ -68,10 +71,9 @@
 </template>
 
 <script setup>
-import { ref, getCurrentInstance } from 'vue';
+import { ref, getCurrentInstance, computed } from 'vue';
 import { ElMessageBox } from 'element-plus/es';
 import { EleMessage } from 'ele-admin-plus/es';
-import { DownloadOutlined } from '@/components/icons';
 import { Flag, ChatDotSquare } from '@element-plus/icons-vue';
 import OrderSearch from './order-search.vue';
 import OrderNumber from '@/views/recycleOrder/components/order-number.vue';
@@ -102,7 +104,7 @@ const [statusDicts] = useDictData(['sys_normal_disable']);
 const tableRef = ref(null);
 
 /** 表格列配置 */
-const columns = ref([
+const baseColumns = [
     {
         type: 'selection',
         columnKey: 'selection',
@@ -122,15 +124,7 @@ const columns = ref([
             statusDicts.value.find((d) => d.dictValue == row.status)?.dictLabel
     },
     { label: '时间', prop: 'time', slot: 'time', minWidth: 220 },
-    { label: '推送人', prop: 'sender', slot: 'sender', minWidth: 170 },
-    { label: '处理人', prop: 'dealer', slot: 'dealer', minWidth: 170 },
-    {
-        label: '处理结果',
-        prop: 'status',
-        slot: 'status',
-        formatter: (row) =>
-            statusDicts.value.find((d) => d.dictValue == row.status)?.dictLabel
-    },
+    { label: '推送人', prop: 'createName', slot: 'sender', minWidth: 170 },
     { label: '处理备注', prop: 'remarks', slot: 'remarks' },
     {
         columnKey: 'action',
@@ -140,7 +134,29 @@ const columns = ref([
         slot: 'action',
         fixed: 'right',
     }
-]);
+];
+
+const historyColumns = [
+    { label: '处理人', prop: 'checkName', slot: 'dealer', minWidth: 170 },
+    {
+        label: '处理结果',
+        prop: 'checkStatus',
+        slot: 'checkStatus',
+        minWidth: 120
+    }
+];
+
+const columns = computed(() => {
+    // Insert history columns before the action column if not in pending status
+    if (props.pageConfig.pageUrl.includes('exceptionHistoryList')) {
+        return [
+            ...baseColumns.slice(0, -2),
+            ...historyColumns,
+            ...baseColumns.slice(-2)
+        ];
+    }
+    return baseColumns;
+});
 
 /** 表格选中数据 */
 const selections = ref([]);
@@ -151,8 +167,14 @@ const current = ref(null);
 /** 是否显示编辑弹窗 */
 const showEdit = ref(false);
 
+//备注弹窗显示
+const showOrderId = ref();
+function handleShowPopover(row) {
+    showOrderId.value = row.orderId;
+}
+
 async function queryPage(params) {
-    const res = await proxy.$http.get(props.pageUrl, { params });
+    const res = await proxy.$http.get(props.pageConfig.pageUrl, { params });
     if (res.data.code === 200) {
         return res.data;
     }
@@ -240,26 +262,6 @@ const remarksRef = ref(null);
 function handleRemarks(row) {
     remarksRef.value?.handleOpen(row);
 }
-const activities = [
-    {
-        content: 'Event start',
-        timestamp: '2018-04-15',
-        color: '#0bbd87',
-        icon: ChatDotSquare
-    },
-    {
-        content: 'Approved',
-        timestamp: '2018-04-13',
-        color: '#0bbd87',
-        icon: ChatDotSquare
-    },
-    {
-        content: 'Success',
-        timestamp: '2018-04-11',
-        color: '#0bbd87',
-        icon: ChatDotSquare
-    }
-];
 
 defineExpose({ reload, exportData, operatBatch });
 </script>

+ 60 - 62
src/views/recycleLogistics/components/order-search.vue

@@ -1,83 +1,81 @@
 <!-- 搜索表单 -->
 <template>
-  <ele-card :body-style="{ paddingBottom: '8px' }">
-    <ProSearch
-      :items="formItems"
-      ref="searchRef"
-      @search="search"
-      :initKeys="initKeys"
-    ></ProSearch>
-  </ele-card>
+    <ele-card :body-style="{ paddingBottom: '8px' }">
+        <ProSearch :items="formItems" ref="searchRef" @search="search" :initKeys="initKeys"></ProSearch>
+    </ele-card>
 </template>
 
 <script setup>
-  import { reactive, ref, defineEmits } from 'vue';
-  import ProSearch from '@/components/CommonPage/ProSearch2.vue';
+import { reactive, ref, defineEmits } from 'vue';
+import ProSearch from '@/components/CommonPage/ProSearch2.vue';
 
-  let { proxy } = getCurrentInstance();
-  const emit = defineEmits(['search']);
+let { proxy } = getCurrentInstance();
+const emit = defineEmits(['search']);
 
-  const formItems = reactive([
-    { type: 'input', label: '推送人', prop: 'bookName' },
+const formItems = reactive([
+    { type: 'input', label: '推送人', prop: 'pushName' },
     {
-      type: 'date',
-      label: '推送时间(开始时间)',
-      prop: 'beginTime',
-      props: {
-        format: 'YYYY-MM-DD',
-        valueFormat: 'YYYY-MM-DD'
-      }
+        type: 'date',
+        label: '推送时间(开始时间)',
+        prop: 'pushTimeStart',
+        props: {
+            format: 'YYYY-MM-DD HH:mm:ss',
+            valueFormat: 'YYYY-MM-DD HH:mm:ss'
+        }
     },
     {
-      type: 'date',
-      label: '推送时间(结束时间)',
-      prop: 'endTime',
-      props: {
-        format: 'YYYY-MM-DD',
-        valueFormat: 'YYYY-MM-DD'
-      }
+        type: 'date',
+        label: '推送时间(结束时间)',
+        prop: 'pushTimeEnd',
+        props: {
+            format: 'YYYY-MM-DD HH:mm:ss',
+            valueFormat: 'YYYY-MM-DD HH:mm:ss'
+        }
     },
-    { type: 'input', label: '处理人', prop: 'isbn' },
+    { type: 'input', label: '处理人', prop: 'checkName' },
     {
-      type: 'date',
-      label: '建单时间(开始时间)',
-      prop: 'beginTime',
-      props: {
-        format: 'YYYY-MM-DD',
-        valueFormat: 'YYYY-MM-DD'
-      }
+        type: 'date',
+        label: '处理时间(开始时间)',
+        prop: 'checkTimeStart',
+        props: {
+            format: 'YYYY-MM-DD HH:mm:ss',
+            valueFormat: 'YYYY-MM-DD HH:mm:ss'
+        }
     },
     {
-      type: 'date',
-      label: '建单时间(结束时间)',
-      prop: 'endTime',
-      props: {
-        format: 'YYYY-MM-DD',
-        valueFormat: 'YYYY-MM-DD'
-      }
+        type: 'date',
+        label: '处理时间(结束时间)',
+        prop: 'checkTimeEnd',
+        props: {
+            format: 'YYYY-MM-DD HH:mm:ss',
+            valueFormat: 'YYYY-MM-DD HH:mm:ss'
+        }
     },
-    { type: 'input', label: '订单编号', prop: 'author' },
-    { type: 'input', label: '物流编号', prop: 'publish' },
+    { type: 'input', label: '订单编号', prop: 'orderId' },
+    { type: 'input', label: '物流单号', prop: 'waybillCode' },
     {
-      type: 'dictSelect',
-      label: '处理结果',
-      prop: 'perCheck',
-      props: { code: 'is_common_yes' }
+        type: 'dictSelect',
+        label: '处理结果',
+        prop: 'checkStatus',
+        props: { code: 'abnormal_check_status' }
     },
-  ]);
+]);
 
-  const initKeys = reactive({
-    schoolName: '',
-    provinceId: '',
-    cityId: '',
-    schoolLevel: '',
-    departmentName: '',
-    shcoolTag: ''
-  });
+const initKeys = reactive({
+    pushName: '',
+    pushTimeStart: '',
+    pushTimeEnd: '',
+    checkName: '',
+    checkTimeStart: '',
+    checkTimeEnd: '',
+    orderId: '',
+    waybillCode: '',
+    checkStatus: ''
+});
 
-  const searchRef = ref(null);
-  /** 搜索 */
-  const search = (data) => {
+const searchRef = ref(null);
+/** 搜索 */
+const search = (data) => {
     emit('search', { ...data });
-  };
+};
 </script>

+ 52 - 0
src/views/recycleLogistics/components/reject-modal.vue

@@ -0,0 +1,52 @@
+<!-- 驳回弹窗 -->
+<template>
+    <simple-form-modal title="驳回提示" :items="formItems" ref="editRef" :baseUrl="baseUrl" :formatData="formatData"
+        @success="(data) => emit('success', data)"></simple-form-modal>
+</template>
+
+<script setup>
+import { reactive, ref, defineEmits, computed } from 'vue';
+import SimpleFormModal from '@/components/CommonPage/SimpleFormModal.vue';
+
+const emit = defineEmits(['success']);
+
+const formItems = computed(() => {
+    return [
+        {
+            type: 'dictSelect',
+            label: '驳回原因',
+            prop: 'refusalReson',
+            props: { code: 'audit_reject_reason', class: 'custom-select' },
+        }
+    ];
+});
+
+//默认值
+const baseUrl = reactive({
+    add: '/order/orderInfo/exceptcheck',
+    update: '/order/orderInfo/exceptcheck'
+});
+
+const formData = ref({
+    id: '',
+    checkStatus: 2
+});
+
+const formatData = (data) => {
+    return {
+        id: formData.value.id,
+        checkStatus: formData.value.checkStatus,
+        refusalReson: data.refusalReson,
+        refusalResonCode: data.refusalReson
+    }
+}
+
+const editRef = ref(null);
+
+function handleOpen(id) {
+    formData.value.id = id;
+    editRef.value?.handleOpen(formData.value);
+}
+
+defineExpose({ handleOpen });
+</script> 

+ 21 - 0
src/views/recycleOrder/awaitSubmit/index.vue

@@ -0,0 +1,21 @@
+<template>
+    <order-page ref="pageRef" :pageConfig="pageConfig" permissionKey="awaitSubmit">
+    </order-page>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import { ElMessage } from 'element-plus';
+import OrderPage from '@/views/recycleOrder/components/order-page-all.vue';
+defineOptions({ name: 'recycleOrderAwaitSubmit' });
+
+/** 页面组件实例 */
+const pageRef = ref(null);
+
+const pageConfig = reactive({
+    pageUrl: '/order/orderInfo/unSubmit/pageList',
+    exportUrl: '/order/orderInfo/unSubmit/export',
+    fileName: '待提交订单',
+    cacheKey: 'awaitSubmitTable'
+});
+</script>

+ 2 - 2
src/views/recycleOrder/components/order-amount.vue

@@ -6,8 +6,8 @@
         </div>
         <div class="common-text">
             <el-text>审核书款:</el-text>
-            <el-text v-if="!row.finalMoney">待核算</el-text>
-            <el-text v-else>¥{{ row.finalMoney }}</el-text>
+            <el-text v-if="typeof row.finalMoney == 'number'">¥{{ row.finalMoney }}</el-text>
+            <el-text v-else>待核算</el-text>
         </div>
         <div class="common-text">
             <el-text>订单类型:</el-text>

+ 12 - 3
src/views/recycleOrder/components/order-customer.vue

@@ -7,9 +7,9 @@
         <div class="common-text" v-if="isReturn">
             <el-text>昵称:</el-text>
             <el-text>{{ row.userNick }}
-                <el-tag type="success" size="small">{{
-                    row.orderFrom == 1 ? '微信' : '支付宝'
-                    }}</el-tag>
+                <el-tag type="success" size="small" v-if="platformType">
+                    {{ platformType }}
+                </el-tag>
             </el-text>
         </div>
         <div class="common-text">
@@ -35,6 +35,8 @@
 
 <script setup>
 import { formatName, formatPhone } from '@/utils/common';
+import { computed } from 'vue';
+
 const props = defineProps({
     row: {
         type: Object,
@@ -45,4 +47,11 @@ const props = defineProps({
         default: false
     }
 });
+
+const platformType = computed(() => {
+    const value = props.row.orderFrom || props.row.plat;
+    if (value === 1) return '微信';
+    if (value === 2) return '支付宝';
+    return '';
+});
 </script>

+ 1 - 1
src/views/recycleOrder/components/order-detail.vue

@@ -14,7 +14,7 @@
                 <div style="margin-left: 10px"></div>
                 <el-button @click="handleCancel" type="danger">关闭弹窗</el-button>
                 <div style="display: flex">
-                    <el-button type="primary" @click="handleOtherAuditGood">其余审核良好</el-button>
+                    <el-button type="primary" @click="handleOtherAuditGood" v-if="orderDetail.status == 9 || orderDetail.status == 8">其余审核良好</el-button>
                     <el-button type="warning" @click="handleFirstCheck" v-if="orderDetail.status == 2">初步审核</el-button>
                     <el-button type="success" @click="handleConfirmReceipt"
                         v-if="orderDetail.status == 6">确认收货</el-button>

+ 13 - 1
src/views/recycleOrder/components/order-page-all.vue

@@ -70,6 +70,10 @@
                             @click="handleLogisticsSigning(row)">
                             [物流签收]
                         </el-button>
+                        <el-button type="success" link v-if="row.status == 5 || row.status == 7"
+                            v-permission="usePermission('signDelivery')" @click="handleSignDelivery(row)">
+                            [快递签收]
+                        </el-button>
                         <el-button type="success" link v-if="row.status == 6"
                             v-permission="usePermission('confirmReceipt')" @click="handleConfirmReceipt(row)">
                             [确认收货]
@@ -418,7 +422,15 @@ function handleLogisticsSigning(row) {
         })
     });
 }
-
+//快递签收
+function handleSignDelivery(row) {
+    messageBoxConfirm({
+        message: '确认快递签收?',
+        fetch: () => proxy.$http.post('/order/orderInfo/adminDeliverySigned', {
+            orderId: row.orderId
+        })
+    });
+}
 //物流揽件
 function materialPickup(row) {
     messageBoxConfirm({

+ 2 - 22
src/views/recycleOrder/components/order-remarks.vue

@@ -15,7 +15,7 @@
 
         </el-form>
 
-        <orderTimeline :records="activities" title="备注历史记录" :orderId="form.orderId"></orderTimeline>
+        <orderTimeline title="备注历史记录" :orderId="form.orderId"></orderTimeline>
 
         <template #footer>
             <el-button @click="handleCancel">关闭</el-button>
@@ -64,6 +64,7 @@ const handleSubmit = () => {
                 if (res.data.code === 200) {
                     EleMessage.success('操作成功');
                     handleCancel();
+                    emit('refresh');
                 } else {
                     EleMessage.error(res.data.msg);
                 }
@@ -92,27 +93,6 @@ const rules = reactive({
     ]
 });
 
-const activities = [
-    {
-        content: 'Event start',
-        timestamp: '2018-04-15',
-        color: '#0bbd87',
-        icon: ChatDotSquare
-    },
-    {
-        content: 'Approved',
-        timestamp: '2018-04-13',
-        color: '#0bbd87',
-        icon: ChatDotSquare
-    },
-    {
-        content: 'Success',
-        timestamp: '2018-04-11',
-        color: '#0bbd87',
-        icon: ChatDotSquare
-    }
-];
-
 defineExpose({
     handleOpen
 });

+ 20 - 12
src/views/recycleOrder/components/order-timeline.vue

@@ -18,7 +18,7 @@
 </template>
 
 <script setup>
-import { watch, ref } from 'vue';
+import { watch, ref, onMounted } from 'vue';
 import request from '@/utils/request';
 import { Flag } from '@element-plus/icons-vue';
 
@@ -33,20 +33,28 @@ const props = defineProps({
     }
 });
 
-//记录上一次orderId
-const lastOrderId = ref('');
 const records = ref([]);
+const loading = ref(false);
+
 //获取备注
-const getRemarks = () => {
-    if (!props.orderId) return;
-    if (lastOrderId.value != props.orderId) {
-        lastOrderId.value = props.orderId;
-        records.value.length = 0
-        request.get(`/order/remark/list?orderId=${props.orderId}`).then((res) => {
-            records.value = res.data.data;
-        });
+const getRemarks = async () => {
+    if (!props.orderId || loading.value) return;
+    
+    loading.value = true;
+    try {
+        const res = await request.get(`/order/remark/list?orderId=${props.orderId}`);
+        records.value = res.data.data;
+    } catch (error) {
+        console.error('Failed to fetch remarks:', error);
+    } finally {
+        loading.value = false;
     }
 };
 
-watch(() => props.orderId, getRemarks);
+watch(() => props.orderId, (newVal, oldVal) => {
+    if (newVal && newVal !== oldVal) {
+        records.value = [];
+        getRemarks();
+    }
+}, { immediate: true });
 </script>

+ 48 - 0
src/views/recycleOrder/components/refund-customer.vue

@@ -0,0 +1,48 @@
+<template>
+    <div class="recycle-order-number">
+        <div class="common-text">
+            <el-text>昵称:</el-text>
+            <el-text>{{ row.userNick }}
+                <el-tag type="success" size="small" v-if="platformType">
+                    {{ platformType }}
+                </el-tag>
+            </el-text>
+        </div>
+        <div class="common-text">
+            <el-text>收件人:</el-text>
+            <el-text v-if="!row.receiveName">暂无信息</el-text>
+            <el-text v-else>{{ formatName(row.receiveName) }}({{ formatPhone(row.receiveMobile) }})</el-text>
+        </div>
+        <div class="common-text">
+            <el-text>省市区:</el-text>
+            <el-text>{{ row.receiveSsq || '-' }}</el-text>
+        </div>
+        <div class="common-text">
+            <el-text>地址:</el-text>
+            <el-text>{{ row.receiveAddress || '-' }}</el-text>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { formatName, formatPhone } from '@/utils/common';
+import { computed } from 'vue';
+
+const props = defineProps({
+    row: {
+        type: Object,
+        default: () => { }
+    },
+    isReturn: {
+        type: Boolean,
+        default: false
+    }
+});
+
+const platformType = computed(() => {
+    const value = props.row.plat;
+    if (value === 1) return '微信';
+    if (value === 2) return '支付宝';
+    return '';
+});
+</script>

+ 2 - 2
src/views/recycleOrder/detail/order-base-info.vue

@@ -39,7 +39,7 @@
                 </div>
                 <div class="common-text">
                     <el-text>预约时间:</el-text>
-                    <el-text>{{ formatTime  }}</el-text>
+                    <el-text>{{ formatTime }}</el-text>
                 </div>
             </el-col>
             <el-col :span="8">
@@ -145,7 +145,7 @@ const columns = ref([
     {
         label: '审核书款',
         prop: 'finalMoney',
-        formatter: (row) => row.finalMoney ? '¥' + row.finalMoney : '待核算'
+        formatter: (row) => typeof row.finalMoney == 'number' ? '¥' + row.finalMoney : '待核算'
     },
     { label: '下单时间', prop: 'orderTime', slot: 'orderTime', width: 200 },
     { label: '交易状态', prop: 'status', slot: 'status', width: 240 }

+ 5 - 1
src/views/recycleOrder/detail/order-book-list.vue

@@ -197,8 +197,12 @@ function handleOtherAuditGood() {
             });
         }
     });
+    let data = {
+        orderIds: [props.detail.orderId],
+        checkType: 2
+    }
     //后端接口批量审核
-    request.post('/order/orderInfo/adminCheckOrder', stsList).then((res) => {
+    request.post('/order/orderInfo/adminCheckBatch', data).then((res) => {
         if (res.data.code == 200) {
             ElMessage.success('操作成功');
         } else {

+ 165 - 220
src/views/recycleOrder/needReturned/index.vue

@@ -1,264 +1,209 @@
 <template>
-  <ele-page flex-table>
-    <!-- 搜索表单 -->
-    <return-search @search="reload" />
-    <ele-card :body-style="{ paddingTop: '8px' }" flex-table>
-      <!-- 表格 -->
-      <ele-pro-table
-        ref="tableRef"
-        row-key="postId"
-        :columns="columns"
-        :datasource="datasource"
-        :show-overflow-tooltip="true"
-        v-model:selections="selections"
-        highlight-current-row
-        :export-config="{ fileName: '需退回订单' }"
-        cache-key="needReturnedTable"
-        :tools="false"
-      >
-        <template #status="{ row }">
-          <dict-data
-            code="sys_normal_disable"
-            type="tag"
-            :model-value="row.status"
-          />
-        </template>
-        <template #isPush="{ row }">
-          <dict-data code="is_push" type="tag" :model-value="row.status" />
-        </template>
-        <template #isFirstOrder="{ row }">
-          <dict-data
-            code="is_first_order"
-            type="tag"
-            :model-value="row.status"
-          />
-        </template>
-        <template #orderNumber="{ row }">
-          <order-number :row="row" isReturn></order-number>
-        </template>
-        <template #customer="{ row }">
-          <order-customer :row="row" isReturn></order-customer>
-        </template>
-        <template #amount="{ row }">
-          <div class="common-text flex flex-col">
-            <el-text>余额:</el-text>
-            <el-text>邮费:¥ 0 </el-text>
-          </div>
-        </template>
-        <template #remarks="{ row }">
-          <el-popover trigger="hover" width="240px">
-            <template #reference>
-              <el-button
-                :icon="Flag"
-                link
-                style="font-size: 20px"
-                @click="handleRemarks(row)"
-              >
-              </el-button>
-            </template>
-            <orderTimeline
-              :records="activities"
-              title="备注历史记录"
-            ></orderTimeline>
-          </el-popover>
-        </template>
+    <ele-page flex-table>
+        <!-- 搜索表单 -->
+        <return-search @search="reload" />
+        <ele-card :body-style="{ paddingTop: '8px' }" flex-table>
+            <!-- 表格 -->
+            <ele-pro-table ref="tableRef" row-key="postId" :columns="columns" :datasource="datasource"
+                :show-overflow-tooltip="true" v-model:selections="selections" highlight-current-row
+                :export-config="{ fileName: '需退回订单' }" cache-key="needReturnedTable" :tools="false">
+                <template #status="{ row }">
+                    <dict-data code="refund_status" type="text" :model-value="row.status" />
+                </template>
+                <template #isPush="{ row }">
+                    <el-tag type="success" v-if="row.checkStatus == 1">已推送</el-tag>
+                    <el-tag type="danger" v-else>未推送</el-tag>
+                </template>
+                <template #isFirstOrder="{ row }">
+                    <dict-data code="is_first_order" type="tag" :model-value="row.firstOrder" />
+                </template>
+                <template #orderNumber="{ row }">
+                    <order-number :row="row" isReturn></order-number>
+                </template>
+                <template #customer="{ row }">
+                    <refund-customer :row="row"></refund-customer>
+                </template>
+                <template #amount="{ row }">
+                    <div class="common-text flex flex-col">
+                        <el-text>余额</el-text>
+                        <el-text>邮费:¥ {{ row.expressMoney || '0' }} </el-text>
+                    </div>
+                </template>
+                <template #remarks="{ row }">
+                    <el-popover trigger="hover" width="240px" @show="handleShowPopover(row)" @hide="showOrderId = ''">
+                        <template #reference>
+                            <el-icon style="cursor: pointer" :size="24" :color="row.remarkLabel || '#777777'"
+                                @click="handleRemarks(row)">
+                                <Flag />
+                            </el-icon>
+                        </template>
+                        <orderTimeline :orderId="showOrderId" title="备注历史记录"></orderTimeline>
+                    </el-popover>
+                </template>
 
-        <template #action="{ row }">
-          <div>
-            <el-button
-              type="success"
-              link
-              v-permission="'recycleOrder:needReturned:detail'"
-              @click="toOrderDetail(row)"
-            >
-              [订单详情]
-            </el-button>
-            <el-button
-              color="#7728f5"
-              link
-              plain
-              v-permission="'recycleOrder:needReturned:manualDelivery'"
-              @click="handleManualDelivery(row)"
-            >
-              [手工发货]
-            </el-button>
-            <el-button
-              type="danger"
-              link
-              v-permission="'recycleOrder:needReturned:cancel'"
-              @click="cancelOrder(row)"
-            >
-              [取消订单]
-            </el-button>
-            <el-button
-              type="warning"
-              link
-              v-permission="'recycleOrder:needReturned:log'"
-              @click="openOrderLog(row)"
-            >
-              [订单日志]
-            </el-button>
-          </div>
-        </template>
-      </ele-pro-table>
-    </ele-card>
+                <template #action="{ row }">
+                    <div>
+                        <el-button type="success" link v-permission="'recycleOrder:needReturned:detail'"
+                            @click="toOrderDetail(row)">
+                            [订单详情]
+                        </el-button>
+                        <el-button color="#7728f5" link plain v-permission="'recycleOrder:needReturned:manualDelivery'"
+                            @click="handleManualDelivery(row)">
+                            [手工发货]
+                        </el-button>
+                        <el-button type="danger" link v-permission="'recycleOrder:needReturned:cancel'"
+                            @click="cancelOrder(row)">
+                            [取消订单]
+                        </el-button>
+                        <el-button type="warning" link v-permission="'recycleOrder:needReturned:log'"
+                            @click="openOrderLog(row)">
+                            [订单日志]
+                        </el-button>
+                    </div>
+                </template>
+            </ele-pro-table>
+        </ele-card>
 
-    <slot></slot>
-    <orderRemarks ref="remarksRef" />
-    <orderLog ref="logRef" />
-  </ele-page>
+        <slot></slot>
+        <orderRemarks ref="remarksRef" />
+        <orderLog ref="logRef" />
+    </ele-page>
 </template>
 
 <script setup>
-  import { ref, getCurrentInstance } from 'vue';
-  import { ElMessageBox } from 'element-plus/es';
-  import { Flag, ChatDotSquare } from '@element-plus/icons-vue';
-  import returnSearch from './return-search.vue';
-  import OrderNumber from '@/views/recycleOrder/components/order-number.vue';
-  import OrderCustomer from '@/views/recycleOrder/components/order-customer.vue';
-  import { useDictData } from '@/utils/use-dict-data';
-  import orderRemarks from '@/views/recycleOrder/components/order-remarks.vue';
-  import orderTimeline from '@/views/recycleOrder/components/order-timeline.vue';
-  import orderLog from '@/views/recycleOrder/components/order-log.vue'
-  import { useRouter } from 'vue-router';
-  let router = useRouter();
+import { ref, getCurrentInstance } from 'vue';
+import { ElMessageBox } from 'element-plus/es';
+import { Flag, ChatDotSquare } from '@element-plus/icons-vue';
+import returnSearch from './return-search.vue';
+import OrderNumber from '@/views/recycleOrder/components/order-number.vue';
+import RefundCustomer from '@/views/recycleOrder/components/refund-customer.vue';
+import { useDictData } from '@/utils/use-dict-data';
+import orderRemarks from '@/views/recycleOrder/components/order-remarks.vue';
+import orderTimeline from '@/views/recycleOrder/components/order-timeline.vue';
+import orderLog from '@/views/recycleOrder/components/order-log.vue'
+import { useRouter } from 'vue-router';
+let router = useRouter();
 
-  let props = defineProps({
+let props = defineProps({
     pageConfig: {
-      type: Object,
-      default: () => ({
-        cacheKey: 'recycleOrderTable',
-        fileName: '需退回订单'
-      })
+        type: Object,
+        default: () => ({
+            cacheKey: 'recycleOrderTable',
+            fileName: '需退回订单'
+        })
     },
-    pageUrl: { type: String, default: '/system/post/list' },
+    pageUrl: { type: String, default: '/order/orderInfo/refund/pageList' },
     exportUrl: { type: String, default: '/system/post/export' }
-  });
-  let { proxy } = getCurrentInstance();
-  /** 字典数据 */
-  const [statusDicts] = useDictData(['sys_normal_disable']);
+});
+let { proxy } = getCurrentInstance();
+/** 字典数据 */
+const [statusDicts] = useDictData(['sys_normal_disable']);
 
-  /** 表格实例 */
-  const tableRef = ref(null);
+/** 表格实例 */
+const tableRef = ref(null);
 
-  /** 表格列配置 */
-  const columns = ref([
+/** 表格列配置 */
+const columns = ref([
     {
-      type: 'selection',
-      columnKey: 'selection',
-      width: 50,
-      align: 'center',
-      fixed: 'left'
+        type: 'selection',
+        columnKey: 'selection',
+        width: 50,
+        align: 'center',
+        fixed: 'left'
     },
-    { label: '单号', prop: 'orderNumber', slot: 'orderNumber', minWidth: 180 },
-    { label: '客户', prop: 'customer', slot: 'customer', minWidth: 380 },
-    { label: '金额', prop: 'amount', slot: 'amount', minWidth: 100 },
-    { label: '是否推送', prop: 'isPush', slot: 'isPush' },
+    { label: '单号', prop: 'refundOrderId', slot: 'orderNumber', minWidth: 180 },
+    { label: '客户', prop: 'userNick', slot: 'customer', minWidth: 380 },
+    { label: '金额', prop: 'balanceMoney', slot: 'amount', minWidth: 100 },
+    { label: '是否推送', prop: 'plat', slot: 'isPush' },
     {
-      label: '订单状态',
-      prop: 'status',
-      slot: 'status',
-      formatter: (row) =>
-        statusDicts.value.find((d) => d.dictValue == row.status)?.dictLabel
+        label: '订单状态',
+        prop: 'status',
+        slot: 'status',
+        formatter: (row) =>
+            statusDicts.value.find((d) => d.dictValue == row.status)?.dictLabel
     },
     {
-      label: '入库状态',
-      prop: 'status',
-      slot: 'status',
-      formatter: (row) =>
-        statusDicts.value.find((d) => d.dictValue == row.status)?.dictLabel
+        label: '入库状态',
+        prop: 'status',
+        formatter: (row) => row.stockStatus == 1 ? '已入库' : '-'
     },
-    { label: '是否首单', prop: 'isFirstOrder', slot: 'isFirstOrder' },
-    { label: '备注', prop: 'remarks', slot: 'remarks' },
+    { label: '是否首单', prop: 'firstOrder', slot: 'isFirstOrder' },
+    { label: '备注', prop: 'remarkLabel', slot: 'remarks' },
     {
-      columnKey: 'action',
-      label: '操作',
-      width: 120,
-      align: 'center',
-      slot: 'action',
-      hideInPrint: true,
-      hideInExport: true
+        columnKey: 'action',
+        label: '操作',
+        width: 120,
+        align: 'center',
+        slot: 'action',
+        hideInPrint: true,
+        hideInExport: true
     }
-  ]);
+]);
 
-  /** 表格选中数据 */
-  const selections = ref([]);
+/** 表格选中数据 */
+const selections = ref([]);
 
-  /** 当前编辑数据 */
-  const current = ref(null);
+/** 当前编辑数据 */
+const current = ref(null);
 
-  /** 是否显示编辑弹窗 */
-  const showEdit = ref(false);
+/** 是否显示编辑弹窗 */
+const showEdit = ref(false);
 
-  async function queryPage(params) {
+async function queryPage(params) {
     const res = await proxy.$http.get(props.pageUrl, { params });
     if (res.data.code === 200) {
-      return res.data;
+        return res.data;
     }
     return Promise.reject(new Error(res.data.msg));
-  }
+}
 
-  /** 表格数据源 */
-  const datasource = ({ pages, where, orders }) => {
+/** 表格数据源 */
+const datasource = ({ pages, where, orders }) => {
     return queryPage({ ...where, ...orders, ...pages });
-  };
+};
 
-  /** 搜索 */
-  const reload = (where) => {
+/** 搜索 */
+const reload = (where) => {
     tableRef.value?.reload?.({ page: 1, where });
-  };
+};
 
-  //订单详情
-  function toOrderDetail(row) {
+//订单详情
+function toOrderDetail(row) {
     router.push({ path: '/recycleOrder/detail', query: { id: row.postId } });
-  }
-  function messageBoxConfirm({ message, url, row }) {
+}
+function messageBoxConfirm({ message, url, row }) {
     ElMessageBox.confirm(message, '提示', {
-      confirmButtonText: '确定',
-      cancelButtonText: '关闭',
-      type: 'warning'
+        confirmButtonText: '确定',
+        cancelButtonText: '关闭',
+        type: 'warning'
     }).then(() => {
-      console.log(row, 'row');
+        console.log(row, 'row');
     });
-  }
+}
 
-  //取消订单
-  function cancelOrder(row) {
+//取消订单
+function cancelOrder(row) {
     messageBoxConfirm({ message: '确认取消?', url: '', row });
-  }
-  //人工发货
-  function handleManualDelivery(row) {
+}
+//人工发货
+function handleManualDelivery(row) {
     messageBoxConfirm({ message: '确认人工发货?', url: '', row });
-  }
-  //订单日志
-  const logRef = ref(null);
-  const openOrderLog = (row) => {
+}
+//订单日志
+const logRef = ref(null);
+const openOrderLog = (row) => {
     logRef.value?.handleOpen(row);
-  };
+};
 
-  //修改备注
-  const remarksRef = ref(null);
-  function handleRemarks(row) {
+//修改备注
+const remarksRef = ref(null);
+function handleRemarks(row) {
     remarksRef.value?.handleOpen(row);
-  }
-  const activities = [
-    {
-      content: 'Event start',
-      timestamp: '2018-04-15',
-      color: '#0bbd87',
-      icon: ChatDotSquare
-    },
-    {
-      content: 'Approved',
-      timestamp: '2018-04-13',
-      color: '#0bbd87',
-      icon: ChatDotSquare
-    },
-    {
-      content: 'Success',
-      timestamp: '2018-04-11',
-      color: '#0bbd87',
-      icon: ChatDotSquare
-    }
-  ];
+}
+
+//备注弹窗显示
+const showOrderId = ref();
+function handleShowPopover(row) {
+    showOrderId.value = row.originOrderId;
+}
 </script>