Răsfoiți Sursa

接口对接

hurx 1 lună în urmă
părinte
comite
20385c355f

+ 23 - 0
src/api/pc/cost/creditApply.ts

@@ -0,0 +1,23 @@
+import request from '@/utils/request';
+
+/**
+ * 查询额度申请列表
+ */
+export function getCreditApplyList(params?: any) {
+  return request({
+    url: '/customer/pcCreditApply/list',
+    method: 'get',
+    params: params
+  });
+}
+
+/**
+ * 新增额度申请
+ */
+export function addCreditApply(data: any) {
+  return request({
+    url: '/customer/pcCreditApply',
+    method: 'post',
+    data: data
+  });
+}

+ 44 - 0
src/api/pc/cost/itemExpense.ts

@@ -0,0 +1,44 @@
+import request from '@/utils/request';
+
+/**
+ * 查询分项费用列表
+ */
+export function getItemExpenseList(params?: any) {
+  return request({
+    url: '/customer/pcCustomerExpenseType/list',
+    method: 'get',
+    params: params
+  });
+}
+
+/**
+ * 新增分项费用
+ */
+export function addItemExpense(data: any) {
+  return request({
+    url: '/customer/pcCustomerExpenseType',
+    method: 'post',
+    data: data
+  });
+}
+
+/**
+ * 修改分项费用
+ */
+export function updateItemExpense(data: any) {
+  return request({
+    url: '/customer/pcCustomerExpenseType',
+    method: 'put',
+    data: data
+  });
+}
+
+/**
+ * 删除分项费用
+ */
+export function deleteItemExpense(ids: number[]) {
+  return request({
+    url: `/customer/pcCustomerExpenseType/${ids.join(',')}`,
+    method: 'delete'
+  });
+}

+ 30 - 0
src/api/pc/cost/types.ts

@@ -0,0 +1,30 @@
+/**
+ * 分享费用
+ */
+export interface ItemExpense {
+  id?: number;
+  customerId?: number;
+  customerNo?: string;
+  expenseName?: string;
+  type?: string;
+  [key: string]: any;
+}
+
+export interface CreditApply {
+  id?: number;
+  customerId?: number;
+  customerNo?: string;
+  applyNo?: string;
+  monthPurchase?: number;
+  yearPurchase?: number;
+  applyAmount?: number;
+  amountPeriod?: number;
+  mainPurchase?: string;
+  otherPurchase?: string;
+  cooperationImage?: string;
+  approvalStatus?: string;
+  approvalComment?: string;
+  oldAmount?: number;
+  remark?: string;
+  [key: string]: any;
+}

+ 11 - 0
src/api/pc/enterprise/order.ts

@@ -89,6 +89,17 @@ export const orderPay = (params: any) => {
   });
 };
 
+/**
+ * 根据批量确认收货
+ */
+export function batchConfirmation(orderIds: number[]) {
+  return request({
+    url: '/order/pcOrder/batchConfirmation',
+    method: 'get',
+    params: { orderIds: orderIds.join(',') }
+  });
+}
+
 // ==================== 订单管理 ====================
 
 /**

+ 5 - 5
src/api/pc/enterprise/orderReturn.ts

@@ -8,7 +8,7 @@ import { OrderReturn } from './orderReturnTypes';
  */
 export function getOrderReturnList(params?: any) {
   return request({
-    url: '/pcOrder/orderReturn/list',
+    url: '/order/pcOrder/orderReturn/list',
     method: 'get',
     params: params
   });
@@ -19,7 +19,7 @@ export function getOrderReturnList(params?: any) {
  */
 export function getOrderReturnInfo(id: number) {
   return request({
-    url: `/pcOrder/orderReturn/${id}`,
+    url: `/order/pcOrder/orderReturn/${id}`,
     method: 'get'
   });
 }
@@ -30,7 +30,7 @@ export function getOrderReturnInfo(id: number) {
  */
 export function addOrderReturn(data: OrderReturn) {
   return request({
-    url: '/pcOrder/orderReturn',
+    url: '/order/pcOrder/orderReturn',
     method: 'post',
     data: data
   });
@@ -42,7 +42,7 @@ export function addOrderReturn(data: OrderReturn) {
  */
 export function updateOrderReturn(data: OrderReturn) {
   return request({
-    url: '/pcOrder/orderReturn',
+    url: '/order/pcOrder/orderReturn',
     method: 'put',
     data: data
   });
@@ -54,7 +54,7 @@ export function updateOrderReturn(data: OrderReturn) {
  */
 export function deleteOrderReturn(ids: number[]) {
   return request({
-    url: `/pcOrder/orderReturn/${ids.join(',')}`,
+    url: `/order/pcOrder/orderReturn/${ids.join(',')}`,
     method: 'delete'
   });
 }

+ 2 - 1
src/utils/siteConfig.ts

@@ -64,7 +64,8 @@ export const SITE_ROUTES: Record<any, string[]> = {
     '/cost/quotaControl/apply',
     '/enterprise/purchasePlan',
     '/organization/approvalFlow',
-    '/organization/approvalFlow/create'
+    '/organization/approvalFlow/create',
+    '/order/orderManage/detail/:orderNo'
   ], //订单列表
 
   i: ['/i'], //个人信息

+ 80 - 64
src/views/cost/itemExpense/index.vue

@@ -6,12 +6,20 @@
     </div>
 
     <el-table :data="expenseList" border>
-      <el-table-column prop="name" label="分项费用名称" min-width="200" />
-      <el-table-column prop="currentQuota" label="现有额度(年)" min-width="150" align="center" />
-      <el-table-column prop="usedQuota" label="已用额度(年)" min-width="150" align="center" />
+      <el-table-column prop="expenseName" label="分项费用名称" min-width="200" />
+      <el-table-column prop="currentQuota" label="现有额度(年)" min-width="150" align="center">
+        <template #default="{ row }">
+          <span>{{ row.currentQuota || '0.00' }}</span>
+        </template>
+      </el-table-column>
+      <el-table-column prop="usedQuota" label="已用额度(年)" min-width="150" align="center">
+        <template #default="{ row }">
+          <span>{{ row.usedQuota || '0.00' }}</span>
+        </template>
+      </el-table-column>
       <el-table-column prop="status" label="状态" min-width="100" align="center">
         <template #default="{ row }">
-          <span :class="['status-text', row.status === '启用' ? 'active' : '']">{{ row.status }}</span>
+          <span :class="['status-text', row.status === '启用' ? 'active' : '']">{{ row.status == '0' ? '启用' : '禁用' }}</span>
         </template>
       </el-table-column>
       <el-table-column label="操作" width="100" align="center">
@@ -25,16 +33,16 @@
     <!-- 新增/编辑弹窗 -->
     <el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px" destroy-on-close>
       <el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px">
-        <el-form-item label="分项费用名称" prop="name">
-          <el-input v-model="formData.name" placeholder="请输入分项费用名称" />
+        <el-form-item label="分项费用名称" prop="expenseName">
+          <el-input v-model="formData.expenseName" placeholder="请输入分项费用名称" />
         </el-form-item>
-        <el-form-item label="现有额度(年)">
+        <!-- <el-form-item label="现有额度(年)">
           <el-input-number v-model="formData.currentQuota" :min="0" :precision="2" controls-position="right" style="width: 100%" />
-        </el-form-item>
+        </el-form-item> -->
         <el-form-item label="状态">
           <el-radio-group v-model="formData.status">
-            <el-radio label="启用">启用</el-radio>
-            <el-radio label="停用">停用</el-radio>
+            <el-radio label="0">启用</el-radio>
+            <el-radio label="1">停用</el-radio>
           </el-radio-group>
         </el-form-item>
       </el-form>
@@ -47,49 +55,60 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, computed } from 'vue'
-import { ElMessage, ElMessageBox } from 'element-plus'
-import { PageTitle } from '@/components'
+import { ref, reactive, computed } from 'vue';
+import { ElMessage, ElMessageBox } from 'element-plus';
+import { getItemExpenseList, addItemExpense, updateItemExpense, deleteItemExpense } from '@/api/pc/cost/itemExpense';
+import { PageTitle } from '@/components';
+import { id } from 'element-plus/es/locale/index.mjs';
 
-const dialogVisible = ref(false)
-const formRef = ref()
-const editingRow = ref<any>(null)
+const dialogVisible = ref(false);
+const formRef = ref();
+const editingRow = ref<any>(null);
 
 const formData = reactive({
-  name: '',
+  id: 0,
+  expenseName: '',
   currentQuota: 0,
-  status: '启用'
-})
+  type: '',
+  status: '0'
+});
 
 const formRules = {
   name: [{ required: true, message: '请输入分项费用名称', trigger: 'blur' }]
-}
+};
 
-const dialogTitle = computed(() => editingRow.value ? '编辑分项费用' : '新建分项费用')
+const dialogTitle = computed(() => (editingRow.value ? '编辑分项费用' : '新建分项费用'));
 
-const expenseList = ref([
-  { id: 1, name: '常规费用', currentQuota: '0.00', usedQuota: '0.00', status: '启用' },
-  { id: 2, name: '办公用品', currentQuota: '0.00', usedQuota: '0.00', status: '启用' },
-  { id: 3, name: '设备采购', currentQuota: '0.00', usedQuota: '0.00', status: '启用' },
-  { id: 4, name: '耗材费用', currentQuota: '0.00', usedQuota: '0.00', status: '启用' },
-  { id: 5, name: '维修费用', currentQuota: '0.00', usedQuota: '0.00', status: '启用' }
-])
+const expenseList = ref([]);
+
+const loadItemExpense = async () => {
+  try {
+    const res = await getItemExpenseList();
+    if (res.code === 200 && res.rows) {
+      expenseList.value = res.rows;
+    }
+  } catch (error) {
+    console.error('获取分项费用失败:', error);
+    ElMessage.error('获取分项费用失败');
+  }
+};
 
 const handleAdd = () => {
-  editingRow.value = null
-  formData.name = ''
-  formData.currentQuota = 0
-  formData.status = '启用'
-  dialogVisible.value = true
-}
+  editingRow.value = null;
+  formData.expenseName = '';
+  formData.currentQuota = 0;
+  formData.status = '0';
+  dialogVisible.value = true;
+};
 
 const handleEdit = (row: any) => {
-  editingRow.value = row
-  formData.name = row.name
-  formData.currentQuota = parseFloat(row.currentQuota) || 0
-  formData.status = row.status
-  dialogVisible.value = true
-}
+  editingRow.value = row;
+  formData.id = row.id;
+  formData.expenseName = row.expenseName;
+  formData.currentQuota = parseFloat(row.currentQuota) || 0;
+  formData.status = row.status;
+  dialogVisible.value = true;
+};
 
 const handleDelete = (row: any) => {
   ElMessageBox.confirm(`确定要删除"${row.name}"吗?`, '提示', {
@@ -97,36 +116,31 @@ const handleDelete = (row: any) => {
     cancelButtonText: '取消',
     type: 'warning'
   }).then(() => {
-    const index = expenseList.value.findIndex(item => item.id === row.id)
+    const index = expenseList.value.findIndex((item) => item.id === row.id);
     if (index > -1) {
-      expenseList.value.splice(index, 1)
+      expenseList.value.splice(index, 1);
     }
-    ElMessage.success('删除成功')
-  })
-}
+    ElMessage.success('删除成功');
+  });
+};
 
 const handleSubmit = async () => {
-  const valid = await formRef.value?.validate()
-  if (!valid) return
+  const valid = await formRef.value?.validate();
+  if (!valid) return;
   if (editingRow.value) {
-    Object.assign(editingRow.value, {
-      name: formData.name,
-      currentQuota: formData.currentQuota.toFixed(2),
-      status: formData.status
-    })
-    ElMessage.success('编辑成功')
+    await updateItemExpense(formData);
+    ElMessage.success('编辑成功');
+    loadItemExpense();
   } else {
-    expenseList.value.push({
-      id: expenseList.value.length + 1,
-      name: formData.name,
-      currentQuota: formData.currentQuota.toFixed(2),
-      usedQuota: '0.00',
-      status: formData.status
-    })
-    ElMessage.success('新建成功')
+    await addItemExpense(formData);
+    ElMessage.success('新建成功');
+    loadItemExpense();
   }
-  dialogVisible.value = false
-}
+  dialogVisible.value = false;
+};
+onMounted(() => {
+  loadItemExpense();
+});
 </script>
 
 <style scoped lang="scss">
@@ -154,6 +168,8 @@ const handleSubmit = async () => {
 
 .status-text {
   color: #999;
-  &.active { color: #67c23a; }
+  &.active {
+    color: #67c23a;
+  }
 }
 </style>

+ 76 - 47
src/views/cost/quotaControl/apply.vue

@@ -1,32 +1,34 @@
 <template>
   <div class="quota-apply-container">
     <div class="page-header">
-      <el-button type="primary" link @click="handleBack"><el-icon><ArrowLeft /></el-icon>返回</el-button>
+      <el-button type="primary" link @click="handleBack"
+        ><el-icon><ArrowLeft /></el-icon>返回</el-button
+      >
       <span class="page-title">额度申请</span>
     </div>
 
     <el-form ref="formRef" :model="formData" :rules="rules" label-position="top" class="apply-form">
       <div class="form-row">
-        <el-form-item label="月度采购金额" prop="monthAmount">
-          <el-input v-model="formData.monthAmount" placeholder="请输入">
+        <el-form-item label="月度采购金额" prop="monthPurchase">
+          <el-input v-model="formData.monthPurchase" placeholder="请输入">
             <template #suffix>元</template>
           </el-input>
         </el-form-item>
-        <el-form-item label="年度采购金额" prop="yearAmount">
-          <el-input v-model="formData.yearAmount" placeholder="请输入">
+        <el-form-item label="年度采购金额" prop="yearPurchase">
+          <el-input v-model="formData.yearPurchase" placeholder="请输入">
             <template #suffix>元</template>
           </el-input>
         </el-form-item>
       </div>
 
       <div class="form-row">
-        <el-form-item label="申请信用金额" prop="creditAmount">
-          <el-input v-model="formData.creditAmount" placeholder="请输入">
+        <el-form-item label="申请信用金额" prop="applyAmount">
+          <el-input v-model="formData.applyAmount" placeholder="请输入">
             <template #suffix>元</template>
           </el-input>
         </el-form-item>
-        <el-form-item label="账期时间" prop="accountPeriod">
-          <el-select v-model="formData.accountPeriod" placeholder="请选择" style="width: 100%">
+        <el-form-item label="账期时间" prop="amountPeriod">
+          <el-select v-model="formData.amountPeriod" placeholder="请选择" style="width: 100%">
             <el-option label="30天" value="30" />
             <el-option label="60天" value="60" />
             <el-option label="90天" value="90" />
@@ -34,19 +36,24 @@
         </el-form-item>
       </div>
 
-      <el-form-item label="主要办公采购类目" prop="category">
-        <div class="category-tags">
-          <div v-for="item in categoryList" :key="item" :class="['tag-item', { active: formData.category === item }]" @click="formData.category = item">
-            {{ item }}
+      <el-form-item label="主要办公采购类目" prop="mainPurchase">
+        <div class="mainPurchase-tags">
+          <div
+            v-for="item in categoryList"
+            :key="item.value"
+            :class="['tag-item', { active: formData.mainPurchase === item.value }]"
+            @click="formData.mainPurchase = item.value"
+          >
+            {{ item.label }}
           </div>
         </div>
       </el-form-item>
 
-      <el-form-item label="其他采购类目" prop="otherCategory">
-        <el-input v-model="formData.otherCategory" type="textarea" :rows="2" placeholder="请输入" maxlength="50" show-word-limit />
+      <el-form-item label="其他采购类目" prop="otherPurchase">
+        <el-input v-model="formData.otherPurchase" type="textarea" :rows="2" placeholder="请输入" maxlength="50" show-word-limit />
       </el-form-item>
 
-      <el-form-item label="上传合作协议" prop="agreement">
+      <el-form-item label="上传合作协议" prop="cooperationImage">
         <el-upload action="#" :auto-upload="false" :limit="1" list-type="picture-card">
           <div class="upload-content">
             <el-icon><Plus /></el-icon>
@@ -64,38 +71,48 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive } from 'vue'
-import { useRouter } from 'vue-router'
-import { ArrowLeft, Plus } from '@element-plus/icons-vue'
-import { ElMessage } from 'element-plus'
-
-const router = useRouter()
-const formRef = ref()
+import { ref, reactive } from 'vue';
+import { useRouter } from 'vue-router';
+import { ArrowLeft, Plus } from '@element-plus/icons-vue';
+import { ElMessage } from 'element-plus';
+import { addCreditApply } from '@/api/pc/cost/creditApply';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { purchase_item } = toRefs<any>(proxy?.useDict('purchase_item'));
+const router = useRouter();
+const formRef = ref();
 
 const formData = reactive({
-  monthAmount: '',
-  yearAmount: '',
-  creditAmount: '',
-  accountPeriod: '',
-  category: '办公耗材',
-  otherCategory: ''
-})
-
-const categoryList = ['办公耗材', '办公设备', '数码设备', '办公日用', '办公日用', '办公日用', '办公日用', '办公日用', '办公日用']
-
+  monthPurchase: '',
+  yearPurchase: '',
+  applyAmount: '',
+  amountPeriod: '',
+  mainPurchase: '0',
+  otherPurchase: '',
+  cooperationImage: ''
+});
+
+const categoryList = computed(() => purchase_item.value || []);
 const rules = {
-  monthAmount: [{ required: true, message: '请输入月度采购金额', trigger: 'blur' }],
-  creditAmount: [{ required: true, message: '请输入申请信用金额', trigger: 'blur' }]
-}
+  monthPurchase: [{ required: true, message: '请输入月度采购金额', trigger: 'blur' }],
+  applyAmount: [{ required: true, message: '请输入申请信用金额', trigger: 'blur' }]
+};
 
-const handleBack = () => { router.back() }
+const handleBack = () => {
+  router.back();
+};
 
 const handleSave = async () => {
-  const valid = await formRef.value?.validate()
-  if (!valid) return
-  ElMessage.success('申请提交成功')
-  router.back()
-}
+  const valid = await formRef.value?.validate();
+  if (!valid) return;
+  try {
+    await addCreditApply(formData);
+    ElMessage.success('保存成功');
+    handleBack();
+  } catch (error) {
+    ElMessage.error('保存失败');
+  }
+  router.back();
+};
 </script>
 
 <style scoped lang="scss">
@@ -110,7 +127,11 @@ const handleSave = async () => {
   align-items: center;
   gap: 10px;
   margin-bottom: 25px;
-  .page-title { font-size: 16px; font-weight: bold; color: #333; }
+  .page-title {
+    font-size: 16px;
+    font-weight: bold;
+    color: #333;
+  }
 }
 
 .apply-form {
@@ -136,7 +157,7 @@ const handleSave = async () => {
   }
 }
 
-.category-tags {
+.mainPurchase-tags {
   display: flex;
   flex-wrap: wrap;
   gap: 10px;
@@ -150,8 +171,13 @@ const handleSave = async () => {
     background: #f5f5f5;
     transition: all 0.2s;
 
-    &:hover { color: #e60012; }
-    &.active { background: #e60012; color: #fff; }
+    &:hover {
+      color: #e60012;
+    }
+    &.active {
+      background: #e60012;
+      color: #fff;
+    }
   }
 }
 
@@ -162,7 +188,10 @@ const handleSave = async () => {
   justify-content: center;
   color: #999;
   font-size: 12px;
-  .el-icon { font-size: 20px; margin-bottom: 5px; }
+  .el-icon {
+    font-size: 20px;
+    margin-bottom: 5px;
+  }
 }
 
 .form-actions {

+ 73 - 34
src/views/cost/quotaControl/index.vue

@@ -8,7 +8,9 @@
     <!-- 额度统计卡片 -->
     <div class="quota-cards">
       <div class="quota-card">
-        <div class="card-icon"><el-icon><CreditCard /></el-icon></div>
+        <div class="card-icon">
+          <el-icon><CreditCard /></el-icon>
+        </div>
         <div class="card-info">
           <div class="card-label">当前额度 ></div>
           <div class="card-value">32</div>
@@ -31,14 +33,20 @@
     <!-- 信用额度申请记录 -->
     <div class="section-title">信用额度申请记录</div>
     <el-table :data="recordList" border>
-      <el-table-column prop="applyTime" label="申请时间" min-width="120" align="center" />
-      <el-table-column prop="monthAmount" label="月度采购金额" min-width="120" align="center" />
-      <el-table-column prop="yearAmount" label="预估年度采购金额" min-width="140" align="center" />
-      <el-table-column prop="creditAmount" label="申请信用金额" min-width="120" align="center" />
-      <el-table-column prop="category" label="主要采购类目" min-width="120" align="center" />
-      <el-table-column prop="status" label="申请状态" min-width="100" align="center">
+      <el-table-column prop="createTime" label="申请时间" min-width="120" align="center" />
+      <el-table-column prop="monthPurchase" label="月度采购金额" min-width="120" align="center" />
+      <el-table-column prop="yearPurchase" label="预估年度采购金额" min-width="140" align="center" />
+      <el-table-column prop="applyAmount" label="申请信用金额" min-width="120" align="center" />
+      <el-table-column prop="category" label="主要采购类目" min-width="120" align="center">
+        <template #default="{ row }">
+          {{ getDictLabel(purchase_item, row.mainPurchase) }}
+        </template>
+      </el-table-column>
+      <el-table-column prop="approvalStatus" label="申请状态" min-width="100" align="center">
         <template #default="{ row }">
-          <span :class="['status-text', getStatusClass(row.status)]">{{ row.status }}</span>
+          <span :class="['status-text', getStatusClass(row.approvalStatus)]">{{
+            row.approvalStatus == '0' ? '待审核' : row.approvalStatus == '1' ? '已通过' : '已拒绝'
+          }}</span>
         </template>
       </el-table-column>
     </el-table>
@@ -46,31 +54,48 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
-import { useRouter } from 'vue-router'
-import { CreditCard } from '@element-plus/icons-vue'
-import { PageTitle } from '@/components'
-
-const router = useRouter()
-
-const recordList = ref([
-  { id: 1, applyTime: '2025-11-30', monthAmount: '0.00', yearAmount: '0.00', creditAmount: '0.00', category: '食品饮料', status: '待审批' },
-  { id: 2, applyTime: '2025-11-29', monthAmount: '0.00', yearAmount: '0.00', creditAmount: '0.00', category: '食品饮料', status: '已通过' },
-  { id: 3, applyTime: '2025-11-25', monthAmount: '0.00', yearAmount: '0.00', creditAmount: '0.00', category: '食品饮料', status: '已通过' },
-  { id: 4, applyTime: '2025-12-05', monthAmount: '0.00', yearAmount: '0.00', creditAmount: '0.00', category: '食品饮料', status: '已通过' },
-  { id: 5, applyTime: '2025-12-07', monthAmount: '0.00', yearAmount: '0.00', creditAmount: '0.00', category: '食品饮料', status: '已通过' },
-  { id: 6, applyTime: '2025-12-07', monthAmount: '0.00', yearAmount: '0.00', creditAmount: '0.00', category: '食品饮料', status: '已通过' }
-])
+import { ref } from 'vue';
+import { useRouter } from 'vue-router';
+import { CreditCard } from '@element-plus/icons-vue';
+import { PageTitle } from '@/components';
+import { getCreditApplyList } from '@/api/pc/cost/creditApply';
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { purchase_item } = toRefs<any>(proxy?.useDict('purchase_item'));
+const router = useRouter();
+
+const recordList = ref([]);
+
+const loadCreditApply = async () => {
+  try {
+    const res = await getCreditApplyList();
+    if (res.code === 200 && res.rows) {
+      recordList.value = res.rows;
+    }
+  } catch (error) {
+    console.error('获取分项费用失败:', error);
+    ElMessage.error('获取分项费用失败');
+  }
+};
+
+const getDictLabel = (dictOptions: any[], value: string) => {
+  if (!dictOptions || !value) return value;
+  const dict = dictOptions.find((item) => item.value === value);
+  return dict ? dict.label : value;
+};
 
 const getStatusClass = (status: string) => {
-  if (status === '已通过') return 'success'
-  if (status === '待审批') return 'warning'
-  return ''
-}
+  if (status === '已通过') return 'success';
+  if (status === '待审批') return 'warning';
+  return '';
+};
 
 const handleApplyQuota = () => {
-  router.push('/cost/quotaControl/apply')
-}
+  router.push('/cost/quotaControl/apply');
+};
+
+onMounted(() => {
+  loadCreditApply();
+});
 </script>
 
 <style scoped lang="scss">
@@ -85,7 +110,9 @@ const handleApplyQuota = () => {
   justify-content: space-between;
   align-items: center;
   margin-bottom: 20px;
-  :deep(.page-title) { margin-bottom: 0; }
+  :deep(.page-title) {
+    margin-bottom: 0;
+  }
 }
 
 .quota-cards {
@@ -115,8 +142,16 @@ const handleApplyQuota = () => {
     }
 
     .card-info {
-      .card-label { font-size: 13px; color: #999; margin-bottom: 5px; }
-      .card-value { font-size: 24px; font-weight: bold; color: #333; }
+      .card-label {
+        font-size: 13px;
+        color: #999;
+        margin-bottom: 5px;
+      }
+      .card-value {
+        font-size: 24px;
+        font-weight: bold;
+        color: #333;
+      }
     }
   }
 }
@@ -139,7 +174,11 @@ const handleApplyQuota = () => {
 }
 
 .status-text {
-  &.success { color: #67c23a; }
-  &.warning { color: #e6a23c; }
+  &.success {
+    color: #67c23a;
+  }
+  &.warning {
+    color: #e6a23c;
+  }
 }
 </style>

+ 42 - 30
src/views/order/afterSale/index.vue

@@ -43,11 +43,11 @@
       <div class="filter-bar">
         <span class="filter-label">状态</span>
         <el-select v-model="queryParams.status" placeholder="请选择" style="width: 100px" clearable>
-          <el-option label="申请中" value="applying" />
-          <el-option label="已退货" value="returned" />
-          <el-option label="已拒绝" value="rejected" />
-          <el-option label="已完成" value="completed" />
-          <el-option label="已取消" value="cancelled" />
+          <el-option label="申请中" value="0" />
+          <el-option label="已退货" value="1" />
+          <el-option label="已拒绝" value="2" />
+          <el-option label="已完成" value="3" />
+          <el-option label="已取消" value="4" />
         </el-select>
       </div>
 
@@ -81,7 +81,7 @@
               </div>
             </div>
             <div class="col-time">{{ item.applyTime }}</div>
-            <div class="col-type">{{ item.serviceType }}</div>
+            <div class="col-type">{{ getDictLabel(service_type, item.serviceType) }}</div>
             <div class="col-status">
               <span :class="['status-text', getStatusClass(item.status)]">{{ item.statusText }}</span>
             </div>
@@ -90,6 +90,9 @@
         </div>
         <el-empty v-if="afterSaleList.length === 0" description="暂无售后记录" />
       </div>
+      <div class="pagination-wrapper">
+        <TablePagination v-model:page="pagination.page" v-model:pageSize="pagination.pageSize" :total="pagination.total" />
+      </div>
     </template>
 
     <template v-else>
@@ -155,6 +158,9 @@
         </el-table-column>
       </el-table>
       <el-empty v-if="complaintList.length === 0" description="暂无投诉与建议" />
+      <div class="pagination-wrapper">
+        <TablePagination v-model:page="pagination.page" v-model:pageSize="pagination.pageSize" :total="pagination.total" />
+      </div>
     </template>
 
     <el-dialog v-model="complaintDialogVisible" :title="complaintDialogTitle" width="500px">
@@ -181,7 +187,8 @@ import { ref, reactive, computed, onMounted } from 'vue';
 import { useRouter } from 'vue-router';
 import { Search, RefreshRight, Tools, ChatLineSquare, Picture } from '@element-plus/icons-vue';
 import { ElMessage, ElMessageBox } from 'element-plus';
-import { getOrderReturnList, getOrderReturnInfo, addOrderReturn, updateOrderReturn, deleteOrderReturn } from '@/api/pc/enterprise/orderReturn';
+import { PageTitle, SearchBar, TablePagination } from '@/components';
+import { getOrderReturnList, getOrderReturnInfo, addOrderReturn, updateOrderReturn } from '@/api/pc/enterprise/orderReturn';
 import type { OrderReturn } from '@/api/pc/enterprise/orderReturnTypes';
 import {
   getComplaintsSuggestionsList,
@@ -189,9 +196,10 @@ import {
   updateComplaintsSuggestions,
   deleteComplaintsSuggestions
 } from '@/api/pc/valueAdded';
-import { lo } from 'element-plus/es/locale/index.mjs';
+import { status } from 'nprogress';
+import { stat } from 'fs';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
-const { complaints_suggestion_type } = toRefs<any>(proxy?.useDict('complaints_suggestion_type'));
+const { service_type, complaints_suggestion_type } = toRefs<any>(proxy?.useDict('service_type', 'complaints_suggestion_type'));
 
 const router = useRouter();
 const activeMainTab = ref('return');
@@ -201,7 +209,7 @@ const complaintDialogTitle = ref('新增投诉与建议');
 const complaintFormRef = ref();
 const currentComplaint = ref<any>(null);
 const loading = ref(false);
-
+const pagination = reactive({ page: 1, pageSize: 5, total: 0 });
 const mainTabs = [
   { key: 'return', label: '退换货', icon: RefreshRight },
   { key: 'repair', label: '返修/维修', icon: Tools },
@@ -210,20 +218,20 @@ const mainTabs = [
 
 const statusTabs = [
   { key: 'all', label: '全部订单' },
-  { key: 'applying', label: '申请中' },
-  { key: 'returned', label: '已退货' },
-  { key: 'rejected', label: '已拒绝' },
-  { key: 'completed', label: '已完成' },
-  { key: 'cancelled', label: '已取消' }
+  { key: '0', label: '申请中' },
+  { key: '1', label: '已退货' },
+  { key: '2', label: '已拒绝' },
+  { key: '3', label: '已完成' },
+  { key: '4', label: '已取消' }
 ];
 
 const complaintStatusTabs = [
   { key: 'all', label: '全部订单' },
-  { key: 'applying', label: '申请中' },
-  { key: 'returned', label: '已退货' },
-  { key: 'rejected', label: '已拒绝' },
-  { key: 'completed', label: '已完成' },
-  { key: 'cancelled', label: '已取消' }
+  { key: '0', label: '申请中' },
+  { key: '1', label: '已退货' },
+  { key: '2', label: '已拒绝' },
+  { key: '3', label: '已完成' },
+  { key: '4', label: '已取消' }
 ];
 
 const queryParams = reactive({ keyword: '', dateRange: null, status: '', handleResult: '', feedbackType: '' });
@@ -241,8 +249,10 @@ const loadAfterSaleData = async () => {
   try {
     loading.value = true;
     const res = await getOrderReturnList({
+      pageNum: pagination.page,
+      pageSize: pagination.pageSize,
       returnStatus: activeStatusTab.value === 'all' ? '' : activeStatusTab.value,
-      serviceType: '0'
+      serviceType: activeMainTab.value === 'return' ? '1' : activeMainTab.value === 'repair' ? '3' : ''
     });
 
     if (res.code === 200 && res.rows) {
@@ -258,8 +268,9 @@ const loadAfterSaleData = async () => {
         serviceType: item.serviceType,
         status: item.returnStatus,
         statusText: getStatusText(item.returnStatus),
-        type: item.serviceType === '0' ? 'return' : 'repair'
+        type: item.serviceType === '1' ? 'return' : 'repair'
       }));
+      pagination.total = res.total | 0;
     }
   } catch (error) {
     console.error('加载售后数据失败:', error);
@@ -278,11 +289,11 @@ const getDictLabel = (dictOptions: any[], value: string) => {
 // 获取状态文本
 const getStatusText = (status?: string) => {
   const statusMap: Record<string, string> = {
-    'applying': '申请中',
-    'returned': '已退货',
-    'rejected': '已拒绝',
-    'completed': '已完成',
-    'cancelled': '已取消'
+    '0': '申请中',
+    '1': '已退货',
+    '2': '已拒绝',
+    '3': '已完成',
+    '4': '已取消'
   };
   return statusMap[status || ''] || status || '未知';
 };
@@ -300,7 +311,7 @@ const complaintList = ref([]);
 const handleMainTabChange = (key: string) => {
   activeMainTab.value = key;
   activeStatusTab.value = 'all';
-  if (key !== 'complaint') {
+  if (key != 'complaint') {
     loadAfterSaleData();
   } else {
     loadComplaintData();
@@ -318,7 +329,7 @@ onMounted(() => {
   loadAfterSaleData();
 });
 const getStatusClass = (status: string) => {
-  const map: Record<string, string> = { applying: 'warning', returned: 'success', rejected: 'danger', completed: 'success', cancelled: 'info' };
+  const map: Record<string, string> = { 0: 'warning', 1: 'success', 2: 'danger', 3: 'success', 4: 'info' };
   return map[status] || 'info';
 };
 const handleViewDetail = (item: any) => {
@@ -366,10 +377,11 @@ const handleSubmitComplaint = async () => {
 };
 
 const loadComplaintData = async () => {
-  const params: any = {};
+  const params: any = { pageNum: pagination.page, pageSize: pagination.pageSize };
   const res = await getComplaintsSuggestionsList(params);
   if (res.code === 200 && res.rows) {
     complaintList.value = res.rows;
+    pagination.total = res.total || 0;
   }
 };
 </script>

+ 10 - 8
src/views/order/orderAudit/index.vue

@@ -38,12 +38,13 @@
         check-strictly
         :render-after-expand="false"
         clearable
-      ></el-tree-select>
-      <span class="filter-label">筛选</span>
+      >
+      </el-tree-select>
+      <!-- <span class="filter-label">筛选</span>
       <el-select v-model="queryParams.filter1" placeholder="请选择" style="width: 100px" clearable>
         <el-option label="条件1" value="1" />
         <el-option label="条件2" value="2" />
-      </el-select>
+      </el-select> -->
     </div>
 
     <!-- 订单列表 -->
@@ -92,7 +93,7 @@
             <div class="product-cell amount-cell">
               <div class="amount-info">
                 <span class="label">支付款</span>
-                <span class="value highlight">¥{{ order.payAmount }}</span>
+                <span class="value highlight">¥{{ order.payableAmount }}</span>
               </div>
               <div class="amount-info">
                 <span class="label">{{ order.payMethod }}</span>
@@ -243,7 +244,7 @@ const loadOrderList = async () => {
         id: item.id,
         orderTime: item.createTime,
         orderNo: item.orderNo,
-        payAmount: item.payAmount,
+        payableAmount: item.payableAmount,
         payMethod: item.payMethod,
         checkStatus: item.checkStatus,
         fileCount: 0,
@@ -341,20 +342,21 @@ const handleStatusTabChange = () => {
 };
 
 onMounted(() => {
+  loadDeptTree();
   loadOrderList();
 });
 
 const getStatusText = (checkStatus: string) => {
   const map: Record<string, string> = {
     '0': '待审批',
-    '1': '已完成',
-    '2': '已完成'
+    '1': '审批通过',
+    '2': '审批驳回'
   };
   return map[checkStatus] || checkStatus;
 };
 
 const getStatusClass = (checkStatus: string) => {
-  if (checkStatus === '1' || checkStatus === '2') return 'success';
+  if (checkStatus === '1') return 'success';
   return 'warning';
 };
 

+ 1 - 0
src/views/order/orderEvaluation/index.vue

@@ -395,6 +395,7 @@ onMounted(() => {
   padding: 20px;
   background: #fff;
   min-height: 100%;
+  width: 100%;
 }
 .search-bar {
   display: flex;

+ 1 - 1
src/views/order/orderManage/detail.vue

@@ -134,7 +134,7 @@ import { ElMessage } from 'element-plus';
 
 const router = useRouter();
 const route = useRoute();
-const orderId = ref<number | string>(0);
+const orderId = ref<any>(0);
 const currentStep = ref(1);
 const loading = ref(false);
 

+ 95 - 15
src/views/order/orderManage/index.vue

@@ -116,7 +116,9 @@
               <span class="status-text" :style="{ color: getStatusColor(order.status) }">{{ order.statusText }}</span>
               <el-button type="primary" link size="small" @click="handleViewDetail(order)">查看订单轨迹</el-button>
               <template v-if="order.auditStatus"
-                ><span :class="['audit-status', getAuditStatusClass(order.auditStatus)]">{{ order.auditStatus }}</span
+                ><span :class="['audit-status', getAuditStatusClass(order.auditStatus)]">{{
+                  order.auditStatus == '0' ? '待审批' : order.auditStatus == '1' ? '审批通过' : '审批驳回'
+                }}</span
                 ><el-button type="primary" link size="small">查看审批流</el-button></template
               >
               <el-button v-if="order.fileCount" type="primary" link size="small">审核文件({{ order.fileCount }})</el-button>
@@ -134,6 +136,10 @@
             </div>
           </div>
         </div>
+        <!-- 显示更多商品提示 -->
+        <div v-if="!order.expanded && order.products.length > 1" class="more-products-hint">
+          该订单共 {{ order.products.length }} 件商品,点击展开查看全部
+        </div>
       </div>
       <el-empty v-if="orderList.length === 0" description="暂无订单" />
     </div>
@@ -155,7 +161,7 @@
             ></template
           ></el-dropdown
         >
-        <el-button type="danger">批量确认收货</el-button>
+        <el-button type="danger" @click="batchConfirmationBtn">批量确认收货</el-button>
       </div>
     </div>
     <!-- 分页 -->
@@ -203,11 +209,21 @@ import { useRouter } from 'vue-router';
 import { Search, ArrowDown, Delete, Document, Clock, Box, CircleCheck, CircleClose, Picture } from '@element-plus/icons-vue';
 import type { CheckboxValueType } from 'element-plus';
 import { TablePagination } from '@/components';
-import { getOrderList, getOrderStatusStats, getOrderProducts, cancelOrder, deleteOrder, addOrderEvaluation } from '@/api/pc/enterprise/order';
+import {
+  getOrderList,
+  getOrderStatusStats,
+  getOrderProducts,
+  cancelOrder,
+  deleteOrder,
+  batchConfirmation,
+  addOrderEvaluation
+} from '@/api/pc/enterprise/order';
 import type { OrderMain, OrderStatusStats } from '@/api/pc/enterprise/orderTypes';
 import { ElMessage, ElMessageBox } from 'element-plus';
 import { getDeptTree } from '@/api/pc/organization';
 import { DeptInfo } from '@/api/pc/organization/types';
+import { addProductShoppingCart } from '@/api/goods/index';
+import { onPath } from '@/utils/siteConfig';
 const { proxy } = getCurrentInstance() as ComponentInternalInstance;
 const { order_status, pay_method } = toRefs<any>(proxy?.useDict('order_status', 'pay_method'));
 
@@ -310,6 +326,15 @@ const loadDeptTree = async () => {
   }
 };
 
+/** 单个加入购物车 */
+const handleAddCart = (item: any) => {
+  addProductShoppingCart({ productId: item.id, productNum: 1 }).then((res: any) => {
+    if (res.code == 200) {
+      ElMessage.success('已加入购物车');
+    }
+  });
+};
+
 // 获取订单列表
 const fetchOrderList = async () => {
   loading.value = true;
@@ -404,21 +429,34 @@ const getOrderActions = (order: any) => {
   }
   return actions;
 };
-const handleExpand = async (order: any) => {
-  console.log('handleExpand 被调用, order.id:', order.id, 'order.expanded:', order.expanded);
 
+const batchConfirmationBtn = async () => {
+  const ids = allOrders.value.filter((o) => o.checked).map((o) => o.id);
+
+  try {
+    const res = await batchConfirmation([...ids]);
+    if (res.code === 200) {
+      ElMessage.success('批量确认成功');
+      fetchOrderList();
+    } else {
+      ElMessage.error('批量确认失败');
+    }
+    return;
+  } catch (error) {
+    console.error('批量确认失败:', error);
+    ElMessage.error('批量确认失败');
+  }
+};
+const handleExpand = async (order: any) => {
   const orderIndex = allOrders.value.findIndex((o) => o.id === order.id);
   if (orderIndex === -1) return;
 
   const currentOrder = allOrders.value[orderIndex];
-  console.log('找到订单, currentOrder.expanded:', currentOrder.expanded);
 
   if (!currentOrder.expanded && currentOrder.products.length === 0) {
-    console.log('需要加载商品');
     try {
       const res = await getOrderProducts([order.id]);
       if (res.code === 200 && res.rows) {
-        console.log('后端返回的商品数据:', res.rows);
         const products = res.rows.map((p: any) => ({
           image: p.productImage || '',
           name: p.productName || '',
@@ -427,11 +465,8 @@ const handleExpand = async (order: any) => {
           price: p.orderPrice || 0,
           quantity: p.orderQuantity || 0
         }));
-        console.log('商品加载完成, products.length:', products.length);
-
         // 替换整个数组以触发响应式更新
         allOrders.value = allOrders.value.map((o, i) => (i === orderIndex ? { ...o, expanded: true, products } : o));
-        console.log('已更新数组,expanded 设置为 true');
         return;
       }
     } catch (error) {
@@ -440,10 +475,8 @@ const handleExpand = async (order: any) => {
     }
   }
 
-  console.log('切换 expanded 状态, 从', currentOrder.expanded, '到', !currentOrder.expanded);
   // 替换整个数组以触发响应式更新
   allOrders.value = allOrders.value.map((o, i) => (i === orderIndex ? { ...o, expanded: !o.expanded } : o));
-  console.log('已更新数组,expanded 已切换');
 };
 const handleSelectAll = (val: CheckboxValueType) => {
   orderList.value.forEach((order) => {
@@ -451,12 +484,46 @@ const handleSelectAll = (val: CheckboxValueType) => {
   });
 };
 
-const copyOrderNo = () => {};
+async function copyOrderNo() {
+  // 1. 先找出所有被勾选的订单
+  const checkedOrders = orderList.value.filter((o) => o.checked);
+
+  let orderNoStr = '';
+
+  if (checkedOrders.length > 0) {
+    // ✅ 情况 A:有勾选的,复制勾选的(支持多选)
+    orderNoStr = checkedOrders.map((o) => o.orderNo).join(',');
+  } else {
+    // ⚠️ 情况 B:没勾选任何项
+    // 策略 1:如果列表不为空,默认复制第一个
+    if (orderList.value.length > 0) {
+      orderNoStr = orderList.value[0].orderNo;
+      ElMessage.warning('未选择订单,已默认复制第一个订单号');
+    } else {
+      ElMessage.error('列表为空,无法复制');
+      return;
+    }
+  }
+
+  // 2. 执行复制逻辑
+  try {
+    await navigator.clipboard.writeText(orderNoStr);
+    ElMessage.success(`成功复制 ${checkedOrders.length || 1} 个订单号`);
+  } catch (err) {
+    const textarea = document.createElement('textarea');
+    textarea.value = orderNoStr;
+    document.body.appendChild(textarea);
+    textarea.select();
+    document.execCommand('copy');
+    document.body.removeChild(textarea);
+    ElMessage.success(`成功复制 ${checkedOrders.length || 1} 个订单号`);
+  }
+}
 const handleOrderCheck = () => {
   selectAll.value = orderList.value.every((order) => order.checked);
 };
 const handleViewDetail = (order: any) => {
-  router.push(`/order/orderManage/detail/${order.orderNo}`);
+  router.push(`/order/orderManage/detail/${order.id}`);
 };
 const handleQuery = () => {
   queryParams.pageNum = 1;
@@ -484,6 +551,9 @@ const handleAction = (action: string, order: any) => {
     case '评价':
       handleEvaluate(order);
       break;
+    case '再次购买':
+      handleAddCart(order);
+      break;
     default:
       ElMessage.info(`${action}功能开发中`);
   }
@@ -582,6 +652,7 @@ onMounted(() => {
   padding: 20px;
   background: #fff;
   min-height: 100%;
+  width: 100%;
   display: flex;
   flex-direction: column;
   max-height: calc(100vh - 120px); // 减去顶部导航栏和其他元素高度
@@ -795,8 +866,17 @@ onMounted(() => {
         gap: 3px;
       }
     }
+    .more-products-hint {
+      padding: 10px 15px;
+      background: #f5f5f5;
+      font-size: 12px;
+      color: #666;
+      text-align: center;
+      border-top: 1px solid #f0f0f0;
+    }
   }
 }
+
 .bottom-bar {
   background: #fafafa;
   border: 1px solid #eee;

+ 1 - 1
src/views/reconciliation/billManage/index.vue

@@ -29,7 +29,7 @@
       </el-table-column>
       <el-table-column label="操作" width="100" align="center">
         <template #default="{ row }">
-          <el-button type="primary" link size="small" @click="handleView(row)">查看</el-button>
+          <!-- <el-button type="primary" link size="small" @click="handleView(row)">查看</el-button> -->
           <el-button type="danger" link size="small" @click="handleConfirm(row)" :disabled="row.billStatus !== '1'">确认</el-button>
         </template>
       </el-table-column>

+ 2 - 2
src/views/reconciliation/invoiceManage/index.vue

@@ -17,9 +17,9 @@
         </template>
       </el-table-column>
       <el-table-column label="操作" width="100" align="center">
-        <template #default="{ row }">
+        <!-- <template #default="{ row }">
           <el-button type="primary" link size="small" @click="handleView(row)">查看</el-button>
-        </template>
+        </template> -->
       </el-table-column>
     </el-table>
 

+ 5 - 4
src/views/valueAdded/complaint/index.vue

@@ -91,10 +91,11 @@ const handleSubmit = async () => {
   padding: 20px;
   background: #fff;
   min-height: 100%;
+  width: calc(100% - 20px);
 }
 
 .complaint-form {
-  max-width: 600px;
+  max-width: 800px;
 }
 
 .type-tags {
@@ -130,13 +131,13 @@ const handleSubmit = async () => {
 .tag-group {
   display: flex;
   flex-wrap: wrap;
-  gap: 5px;
+  gap: 10px;
   .tag-item {
-    padding: 5px 10px;
+    padding: 10px 20px;
     border: 1px solid #ddd;
     border-radius: 4px;
     cursor: pointer;
-    font-size: 10px;
+    font-size: 12px;
     color: #666;
     transition: all 0.2s;
     &:hover {