瀏覽代碼

feat: 对接部分支付配置接口

叶静 1 周之前
父節點
當前提交
9d8e17e116

+ 2 - 2
.env.production

@@ -1,10 +1,10 @@
 ##### VITE SheepJS配置
 SHEEP_VERSION = v1.4.0
 
-SHEEP_BASE_URL = https://shop.fusenlink.com
+SHEEP_BASE_URL =  http://124.222.152.234:8501
 
 # 开发环境接口域名
-SHEEP_DEV_BASE_URL = https://shop.fusenlink.com
+SHEEP_DEV_BASE_URL =  http://124.222.152.234:8501
 
 # 开发环境上传文件接口域名
  SHEEP_UPLOAD_BASE_URL = /operating

+ 62 - 0
src/app/admin/api/index.js

@@ -347,4 +347,66 @@ export default {
   banner: {
     ...CRUD('/mall/banner'),
   },
+
+  // 支付配置管理
+  payment: {
+    // 支付方式管理
+    method: {
+      // 获取支付方式列表
+      list: (params) =>
+        request({
+          url: '/cif/payment/method/list',
+          method: 'POST',
+          data: params,
+        }),
+      midUpdate: (data) =>
+        request({
+          url: '/cif/mid/channel/method/update',
+          method: 'POST',
+          data,
+        }),
+      // 更新支付方式
+      update: (data) =>
+        request({
+          url: '/cif/payment/method/update',
+          method: 'POST',
+          data,
+        }),
+    },
+
+    // 支付通道管理
+    channel: {
+      // 获取支付通道列表
+      list: (params) =>
+        request({
+          url: '/cif/payment/channel/list',
+          method: 'POST',
+          data: params,
+        }),
+
+      // 新增支付通道
+      add: (data) =>
+        request({
+          url: '/cif/payment/channel/add',
+          method: 'POST',
+          data,
+        }),
+
+      // 更新支付通道
+      update: (data) =>
+        request({
+          url: '/cif/payment/channel/update',
+          method: 'POST',
+          data,
+        }),
+
+      // 删除支付通道(软删除)
+      delete: (id) =>
+        request({
+          url: '/cif/payment/channel/update',
+          method: 'POST',
+          data: { id, isValid: 0 },
+        }),
+    },
+  },
 };

+ 11 - 44
src/app/admin/routes/index.js

@@ -49,42 +49,9 @@ export default {
             title: '菜单权限',
           },
         },
-        {
-          path: 'adminlog',
-          name: 'admin.auth.adminlog',
-          component: () => import('@/app/admin/views/auth/adminLog/index.vue'),
-          meta: {
-            title: '操作记录',
-          },
-        },
-      ],
-    },
-    {
-      path: 'config',
-      name: 'admin.config',
-      component: Content,
-      meta: {
-        title: '系统设置',
-      },
-      children: [
-        {
-          path: 'basic',
-          name: 'admin.config.basic',
-          component: () => import('@/app/admin/views/config/basic.vue'),
-          meta: {
-            title: '系统信息',
-          },
-        },
-        {
-          path: 'easysms',
-          name: 'admin.config.easysms',
-          component: () => import('@/app/admin/views/config/easysms.vue'),
-          meta: {
-            title: '短信配置',
-          },
-        },
       ],
     },
+
     {
       path: 'notification',
       name: 'admin.notification',
@@ -92,16 +59,7 @@ export default {
       meta: {
         title: '消息通知',
       },
-      children: [
-        {
-          path: 'config',
-          name: 'admin.notification.config',
-          component: () => import('@/app/admin/views/notification/config/index.vue'),
-          meta: {
-            title: '消息配置',
-          },
-        },
-      ],
+      children: [],
     },
     {
       path: 'banner',
@@ -112,5 +70,14 @@ export default {
         icon: 'Picture',
       },
     },
+    {
+      path: 'payment',
+      name: 'admin.payment',
+      component: () => import('@/app/admin/views/payment/index.vue'),
+      meta: {
+        title: '支付配置',
+        icon: 'CreditCard',
+      },
+    },
   ],
 };

+ 131 - 0
src/app/admin/views/payment/components/ChannelManage.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="channel-manage" v-loading="loading">
+    <el-table height="100%" class="sa-table" :data="tableData" stripe>
+      <template #empty>
+        <sa-empty />
+      </template>
+
+      <el-table-column prop="channelCode" label="支付通道编号" min-width="120"> </el-table-column>
+
+      <el-table-column prop="channelName" label="通道名称" min-width="150"> </el-table-column>
+
+      <el-table-column prop="merchantNum" label="商户号" min-width="150"> </el-table-column>
+
+      <el-table-column prop="appid" label="APPID" min-width="200"> </el-table-column>
+
+      <el-table-column prop="secretKey" label="密钥" min-width="300">
+        <template #default="scope">
+          {{ scope.row.secretKey }}
+        </template>
+      </el-table-column>
+
+      <el-table-column label="操作" min-width="150" fixed="right">
+        <template #default="scope">
+          <el-button class="is-link" type="primary" @click="editChannel(scope.row)">
+            编辑
+          </el-button>
+          <el-popconfirm
+            width="fit-content"
+            confirm-button-text="确认"
+            cancel-button-text="取消"
+            title="确认删除这个支付通道?"
+            @confirm="deleteChannel(scope.row.id)"
+          >
+            <template #reference>
+              <el-button class="is-link" type="danger">删除</el-button>
+            </template>
+          </el-popconfirm>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup>
+  import { onMounted, ref } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import { useModal } from '@/sheep/hooks';
+  import api from '../../../api';
+  import ChannelEdit from '../edit.vue';
+
+  const loading = ref(false);
+  const tableData = ref([]);
+
+  // 获取支付通道数据
+  async function getData() {
+    loading.value = true;
+    try {
+      const { code, data } = await api.payment.channel.list({});
+
+      if (code == 200) {
+        tableData.value = data || [];
+      }
+    } catch (error) {
+      console.error('获取支付通道失败:', error);
+      ElMessage.error('获取数据失败');
+    } finally {
+      loading.value = false;
+    }
+  }
+
+  // 编辑通道
+  function editChannel(channel) {
+    useModal(
+      ChannelEdit,
+      {
+        title: '编辑支付通道',
+        type: 'edit',
+        id: channel.id,
+        data: channel,
+      },
+      {
+        confirm: () => {
+          getData();
+        },
+      },
+    );
+  }
+
+  // 删除通道
+  async function deleteChannel(id) {
+    try {
+      const { code } = await api.payment.channel.delete(id);
+      if (code == 200) {
+        ElMessage.success('删除成功');
+        getData();
+      }
+    } catch (error) {
+      console.error('删除支付通道失败:', error);
+      ElMessage.error('删除失败');
+    }
+  }
+
+  // 暴露方法给父组件调用
+  defineExpose({
+    getData,
+  });
+
+  onMounted(() => {
+    getData();
+  });
+</script>
+
+<style lang="scss" scoped>
+  .channel-manage {
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+
+    .sa-table-wrap {
+      flex: 1;
+      margin-top: 16px;
+    }
+
+    .secret-key {
+      font-family: 'Courier New', monospace;
+      font-size: 12px;
+      word-break: break-all;
+      line-height: 1.4;
+    }
+  }
+</style>

+ 247 - 0
src/app/admin/views/payment/components/CollectionConfig.vue

@@ -0,0 +1,247 @@
+<template>
+  <div class="collection-config" v-loading="loading">
+    <el-table height="100%" class="sa-table" :data="tableData" stripe>
+      <template #empty>
+        <sa-empty />
+      </template>
+
+      <el-table-column label="代收支付方式" min-width="150" align="center">
+        <template #default="scope">
+          <div class="method-cell">
+            <div class="method-name">{{ scope.row.methodName }}</div>
+            <el-switch
+              v-model="scope.row.status"
+              :active-value="1"
+              :inactive-value="0"
+              @change="handleMethodStatusChange(scope.row)"
+            />
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="代收支付通道" min-width="200" align="center">
+        <template #default="scope">
+          <div class="channel-list">
+            <div
+              v-for="channel in scope.row.midChannelMethodBOList"
+              :key="channel.id"
+              class="channel-item"
+            >
+              {{ channel.paymentChannel.channelName }}
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="权重" min-width="200" align="center">
+        <template #default="scope">
+          <div class="weight-list">
+            <div
+              v-for="channel in scope.row.midChannelMethodBOList"
+              :key="channel.id"
+              class="weight-item"
+            >
+              <el-input
+                v-model="channel.weight"
+                type="number"
+                :min="0"
+                size="small"
+                style="width: 80px"
+              />
+              <span class="weight-percent ml-10px">
+                {{ calculateWeightPercent(scope.row, channel.weight) }}%
+              </span>
+              <el-button
+                size="small"
+                type="primary"
+                @click="handleWeightSave(scope.row, channel)"
+                style="margin-left: 8px"
+              >
+                保存
+              </el-button>
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="通道状态" min-width="150" align="center">
+        <template #default="scope">
+          <div class="status-list">
+            <div
+              v-for="channel in scope.row.midChannelMethodBOList"
+              :key="channel.id"
+              class="status-item"
+            >
+              <el-switch
+                v-model="channel.status"
+                :active-value="1"
+                :inactive-value="0"
+                @change="handleChannelStatusChange(channel)"
+              />
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup>
+  import { onMounted, ref } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import api from '../../../api';
+
+  const loading = ref(false);
+  const tableData = ref([]);
+
+  // 获取代收配置数据
+  async function getData() {
+    loading.value = true;
+    try {
+      const { code, data } = await api.payment.method.list({
+        agencyService: 1, // 代收
+      });
+
+      if (code == 200) {
+        tableData.value = data || [];
+      }
+    } catch (error) {
+      console.error('获取代收配置失败:', error);
+      ElMessage.error('获取数据失败');
+    } finally {
+      loading.value = false;
+    }
+  }
+
+  // 计算权重百分比
+  function calculateWeightPercent(method, currentWeight) {
+    const totalWeight = method.midChannelMethodBOList.reduce((sum, channel) => {
+      return sum + (parseInt(channel.weight) || 0);
+    }, 0);
+
+    if (totalWeight === 0) return 0;
+    return (((parseInt(currentWeight) || 0) / totalWeight) * 100).toFixed(1);
+  }
+
+  // 处理支付方式状态变更
+  async function handleMethodStatusChange(method) {
+    try {
+      const { code } = await api.payment.method.update({
+        id: method.id,
+        status: method.status,
+      });
+
+      if (code == 200) {
+        ElMessage.success('状态更新成功');
+      }
+    } catch (error) {
+      console.error('更新支付方式状态失败:', error);
+      ElMessage.error('状态更新失败');
+      // 回滚状态
+      method.status = method.status === 1 ? 0 : 1;
+    }
+  }
+
+  // 处理通道状态变更
+  async function handleChannelStatusChange(channel) {
+    try {
+      const { code } = await api.payment.method.midUpdate({
+        id: channel.id,
+        status: channel.status,
+      });
+
+      if (code == 200) {
+        ElMessage.success('通道状态更新成功');
+      }
+    } catch (error) {
+      console.error('更新通道状态失败:', error);
+      ElMessage.error('通道状态更新失败');
+      // 回滚状态
+      channel.status = channel.status === 1 ? 0 : 1;
+    }
+  }
+
+  // 处理权重保存
+  async function handleWeightSave(method, channel) {
+    try {
+      const { code } = await api.payment.method.midUpdate({
+        id: channel.id,
+        weight: parseInt(channel.weight) || 0,
+      });
+
+      if (code == 200) {
+        ElMessage.success('权重保存成功');
+        // 重新获取数据以更新百分比显示
+        getData();
+      }
+    } catch (error) {
+      console.error('保存权重失败:', error);
+      ElMessage.error('权重保存失败');
+      // 重新获取数据以恢复原始值
+      getData();
+    }
+  }
+
+  // 暴露方法给父组件调用
+  defineExpose({
+    getData,
+  });
+
+  onMounted(() => {
+    getData();
+  });
+</script>
+
+<style lang="scss" scoped>
+  .collection-config {
+    height: 100%;
+
+    .method-cell {
+      align-items: center;
+      gap: 12px;
+
+      .method-name {
+        font-weight: 500;
+      }
+    }
+
+    .channel-list,
+    .weight-list,
+    .status-list {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      gap: 0;
+      padding: 8px;
+    }
+
+    .channel-item,
+    .weight-item,
+    .status-item {
+      display: flex;
+      align-items: center;
+      min-height: 60px;
+      padding: 8px 12px;
+      width: 100%;
+      justify-content: center;
+
+      &:not(:last-child) {
+        border-bottom: 1px solid var(--el-border-color-light);
+        margin-bottom: 8px;
+        padding-bottom: 12px;
+      }
+    }
+
+    .weight-item {
+      gap: 8px;
+      flex-wrap: wrap;
+      justify-content: center;
+
+      .weight-percent {
+        color: var(--el-color-primary);
+        font-weight: 500;
+        min-width: 50px;
+      }
+    }
+  }
+</style>

+ 152 - 0
src/app/admin/views/payment/components/PayoutConfig.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="payout-config" v-loading="loading">
+    <el-table height="100%" class="sa-table" :data="tableData" stripe>
+      <template #empty>
+        <sa-empty />
+      </template>
+
+      <el-table-column label="代付支付方式" min-width="150" align="center">
+        <template #default="scope">
+          <span class="method-name">{{ scope.row.methodName }}</span>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="代付支付通道" min-width="200" align="center">
+        <template #default="scope">
+          <div class="channel-list">
+            <div
+              v-for="channel in scope.row.midChannelMethodBOList"
+              :key="channel.id"
+              class="channel-item"
+            >
+              {{ channel.paymentChannel.channelName }}
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+
+      <el-table-column label="通道状态" min-width="150" align="center">
+        <template #default="scope">
+          <div class="status-list">
+            <div
+              v-for="channel in scope.row.midChannelMethodBOList"
+              :key="channel.id"
+              class="status-item"
+            >
+              <el-switch
+                v-model="channel.status"
+                :active-value="1"
+                :inactive-value="0"
+                @change="handleChannelStatusChange(channel)"
+              />
+            </div>
+          </div>
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup>
+  import { onMounted, ref } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import api from '../../../api';
+
+  const loading = ref(false);
+  const tableData = ref([]);
+
+  // 获取代付配置数据
+  async function getData() {
+    loading.value = true;
+    try {
+      const { code, data } = await api.payment.method.list({
+        agencyService: 2, // 代付
+      });
+
+      if (code == 200) {
+        tableData.value = data || [];
+      }
+    } catch (error) {
+      console.error('获取代付配置失败:', error);
+      ElMessage.error('获取数据失败');
+    } finally {
+      loading.value = false;
+    }
+  }
+
+  // 处理通道状态变更
+  async function handleChannelStatusChange(channel) {
+    try {
+      const { code } = await api.payment.method.midUpdate({
+        id: channel.id,
+        status: channel.status,
+      });
+
+      if (code == 200) {
+        ElMessage.success('通道状态更新成功');
+      }
+    } catch (error) {
+      console.error('更新通道状态失败:', error);
+      ElMessage.error('通道状态更新失败');
+      // 回滚状态
+      channel.status = channel.status === 1 ? 0 : 1;
+    }
+  }
+
+  // 暴露方法给父组件调用
+  defineExpose({
+    getData,
+  });
+
+  onMounted(() => {
+    getData();
+  });
+</script>
+
+<style lang="scss" scoped>
+  .payout-config {
+    height: 100%;
+
+    .method-cell {
+      display: flex;
+      align-items: center;
+
+      .method-name {
+        font-weight: 500;
+      }
+    }
+
+    .channel-list,
+    .weight-list,
+    .status-list {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      gap: 0;
+      padding: 8px;
+    }
+
+    .channel-item,
+    .weight-item,
+    .status-item {
+      display: flex;
+      align-items: center;
+      min-height: 40px;
+      padding: 8px 12px;
+      width: 100%;
+      justify-content: center;
+
+      &:not(:last-child) {
+        border-bottom: 1px solid var(--el-border-color-light);
+        margin-bottom: 8px;
+        padding-bottom: 12px;
+      }
+    }
+
+    .weight-display {
+      color: #909399;
+      font-style: italic;
+    }
+  }
+</style>

+ 148 - 0
src/app/admin/views/payment/edit.vue

@@ -0,0 +1,148 @@
+<template>
+  <el-container>
+    <el-main v-loading="loading" element-loading-text="加载中...">
+      <el-form :model="form.model" :rules="form.rules" ref="formRef" label-width="120px">
+        <el-form-item label="通道编号" prop="channelCode">
+          <el-input
+            v-model="form.model.channelCode"
+            placeholder="请输入支付通道编号"
+            maxlength="50"
+            show-word-limit
+          />
+        </el-form-item>
+
+        <el-form-item label="通道名称" prop="channelName">
+          <el-input
+            v-model="form.model.channelName"
+            placeholder="请输入通道名称"
+            maxlength="100"
+            show-word-limit
+          />
+        </el-form-item>
+
+        <el-form-item label="商户号" prop="merchantNum">
+          <el-input
+            v-model="form.model.merchantNum"
+            placeholder="请输入商户号"
+            maxlength="100"
+            show-word-limit
+          />
+        </el-form-item>
+
+        <el-form-item label="APPID" prop="appid">
+          <el-input
+            v-model="form.model.appid"
+            placeholder="请输入应用ID"
+            maxlength="200"
+            show-word-limit
+          />
+        </el-form-item>
+
+        <el-form-item label="密钥" prop="secretKey">
+          <el-input
+            v-model="form.model.secretKey"
+            type="textarea"
+            :rows="4"
+            placeholder="请输入密钥"
+            maxlength="1000"
+            show-word-limit
+          />
+        </el-form-item>
+      </el-form>
+    </el-main>
+    <el-footer class="sa-footer--submit">
+      <el-button v-if="modal.params.type == 'add'" type="primary" @click="confirm">保存</el-button>
+      <el-button v-if="modal.params.type == 'edit'" type="primary" @click="confirm">更新</el-button>
+    </el-footer>
+  </el-container>
+</template>
+
+<script setup>
+  import { onMounted, reactive, ref, unref } from 'vue';
+  import { ElMessage } from 'element-plus';
+  import api from '../../api';
+
+  const emit = defineEmits(['modalCallBack']);
+  const props = defineProps({
+    modal: {
+      type: Object,
+    },
+  });
+
+  // 添加 编辑 form
+  let formRef = ref(null);
+  const loading = ref(false);
+
+  const form = reactive({
+    model: {
+      channelCode: '',
+      channelName: '',
+      merchantNum: '',
+      appid: '',
+      secretKey: '',
+    },
+    rules: {
+      channelCode: [{ required: true, message: '请输入支付通道编号', trigger: 'blur' }],
+      channelName: [{ required: true, message: '请输入通道名称', trigger: 'blur' }],
+      merchantNum: [{ required: true, message: '请输入商户号', trigger: 'blur' }],
+      appid: [{ required: true, message: '请输入应用ID', trigger: 'blur' }],
+      secretKey: [{ required: true, message: '请输入密钥', trigger: 'blur' }],
+    },
+  });
+
+  // 获取详情
+  async function getDetail(data) {
+    loading.value = true;
+    try {
+      form.model.channelCode = data.channelCode || '';
+      form.model.channelName = data.channelName || '';
+      form.model.merchantNum = data.merchantNum || '';
+      form.model.appid = data.appid || '';
+      form.model.secretKey = data.secretKey || '';
+    } finally {
+      loading.value = false;
+    }
+  }
+
+  // 表单关闭时提交
+  async function confirm() {
+    unref(formRef).validate(async (valid) => {
+      if (!valid) return;
+
+      let submitForm = { ...form.model };
+
+      if (props.modal.params.type == 'edit') {
+        submitForm.id = props.modal.params.id;
+      }
+
+      const { code } =
+        props.modal.params.type == 'add'
+          ? await api.payment.channel.add(submitForm)
+          : await api.payment.channel.update(submitForm);
+
+      if (code == 200) {
+        ElMessage.success('保存成功');
+        emit('modalCallBack', { event: 'confirm' });
+      }
+    });
+  }
+
+  async function init() {
+    if (props.modal.params.type === 'edit' && props.modal.params.data) {
+      await getDetail(props.modal.params.data);
+    }
+  }
+
+  onMounted(() => {
+    init();
+  });
+</script>
+
+<style lang="scss" scoped>
+  // .el-textarea {
+  //   :deep(.el-textarea__inner) {
+  //     font-family: 'Courier New', monospace;
+  //     font-size: 14px;
+  //   }
+  // }
+</style>

+ 107 - 0
src/app/admin/views/payment/index.vue

@@ -0,0 +1,107 @@
+<template>
+  <el-container class="payment-config">
+    <el-header class="sa-header">
+      <el-tabs class="sa-tabs" v-model="activeTab" @tab-change="handleTabChange">
+        <el-tab-pane label="代收配置" name="collection"></el-tab-pane>
+        <el-tab-pane label="代付配置" name="payout"></el-tab-pane>
+        <el-tab-pane label="支付通道" name="channel"></el-tab-pane>
+      </el-tabs>
+      <div class="sa-title sa-flex sa-row-between">
+        <div class="label sa-flex">
+          <span class="left"></span>
+        </div>
+        <div>
+          <el-button
+            class="sa-button-refresh"
+            icon="RefreshRight"
+            @click="refreshCurrentTab"
+          ></el-button>
+          <el-button v-if="activeTab === 'channel'" icon="Plus" type="primary" @click="addChannel">
+            新增通道
+          </el-button>
+        </div>
+      </div>
+    </el-header>
+    <el-main class="sa-p-0">
+      <div class="sa-table-wrap panel-block panel-block--bottom">
+        <CollectionConfig v-if="activeTab === 'collection'" ref="collectionRef" />
+        <PayoutConfig v-if="activeTab === 'payout'" ref="payoutRef" />
+        <ChannelManage v-if="activeTab === 'channel'" ref="channelRef" />
+      </div>
+    </el-main>
+  </el-container>
+</template>
+
+<script setup>
+  import { ref } from 'vue';
+  import { useModal } from '@/sheep/hooks';
+  import CollectionConfig from './components/CollectionConfig.vue';
+  import PayoutConfig from './components/PayoutConfig.vue';
+  import ChannelManage from './components/ChannelManage.vue';
+  import ChannelEdit from './edit.vue';
+
+  // 当前激活的Tab
+  const activeTab = ref('collection');
+
+  // 组件引用
+  const collectionRef = ref();
+  const payoutRef = ref();
+  const channelRef = ref();
+
+  // Tab切换处理
+  function handleTabChange(tabName) {
+    activeTab.value = tabName;
+    // 切换Tab时重新调用对应组件的接口
+    refreshCurrentTab();
+  }
+
+  // 刷新当前Tab的数据
+  function refreshCurrentTab() {
+    switch (activeTab.value) {
+      case 'collection':
+        collectionRef.value?.getData?.();
+        break;
+      case 'payout':
+        payoutRef.value?.getData?.();
+        break;
+      case 'channel':
+        channelRef.value?.getData?.();
+        break;
+    }
+  }
+
+  // 新增支付通道
+  function addChannel() {
+    useModal(
+      ChannelEdit,
+      {
+        title: '新增支付通道',
+        type: 'add',
+      },
+      {
+        confirm: () => {
+          channelRef.value?.getData?.();
+        },
+      },
+    );
+  }
+</script>
+
+<style lang="scss" scoped>
+  .payment-config {
+    height: 100%;
+
+    .payment-tabs {
+      height: 100%;
+
+      :deep(.el-tabs__content) {
+        height: calc(100% - 40px);
+        padding: 0;
+      }
+
+      :deep(.el-tab-pane) {
+        height: 100%;
+      }
+    }
+  }
+</style>

+ 27 - 27
src/app/notice/index.vue

@@ -144,33 +144,33 @@
       ]);
 
       const noticeList = ref([
-        {
-          id: 1,
-          data: {
-            message_title: '系统通知',
-            message_text: '欢迎使用商城管理系统,您有新的订单需要处理。',
-          },
-          create_time: '2024-01-15 10:30:00',
-          read_time: null,
-        },
-        {
-          id: 2,
-          data: {
-            message_title: '订单提醒',
-            message_text: '您有一个新的订单等待确认,订单号:#202401150001',
-          },
-          create_time: '2024-01-15 09:15:00',
-          read_time: '2024-01-15 10:00:00',
-        },
-        {
-          id: 3,
-          data: {
-            message_title: '库存警告',
-            message_text: '商品"BOLON经典太阳镜"库存不足,当前库存:5件',
-          },
-          create_time: '2024-01-15 08:45:00',
-          read_time: null,
-        },
+        // {
+        //   id: 1,
+        //   data: {
+        //     message_title: '系统通知',
+        //     message_text: '欢迎使用商城管理系统,您有新的订单需要处理。',
+        //   },
+        //   create_time: '2024-01-15 10:30:00',
+        //   read_time: null,
+        // },
+        // {
+        //   id: 2,
+        //   data: {
+        //     message_title: '订单提醒',
+        //     message_text: '您有一个新的订单等待确认,订单号:#202401150001',
+        //   },
+        //   create_time: '2024-01-15 09:15:00',
+        //   read_time: '2024-01-15 10:00:00',
+        // },
+        // {
+        //   id: 3,
+        //   data: {
+        //     message_title: '库存警告',
+        //     message_text: '商品"BOLON经典太阳镜"库存不足,当前库存:5件',
+        //   },
+        //   create_time: '2024-01-15 08:45:00',
+        //   read_time: null,
+        // },
       ]);
 
       const noticeUnreadNum = computed(() => {

+ 3 - 1
src/app/shop/admin/order/order.service.js

@@ -1,5 +1,6 @@
 import Content from '@/sheep/layouts/content.vue';
 import { request } from '@/sheep/request';
+import { REPORT } from '@/sheep/request/crud';
 
 // 订单状态配置
 export const ORDER_STATUS = {
@@ -79,7 +80,6 @@ export function getPayTypeText(payType) {
   return ORDER_STATUS.PAY_TYPE[payType] || payType || '--';
 }
 import { SELECT, CRUD } from '@/sheep/request/crud';
-import { EXPORT } from '@/sheep/request/export';
 
 const route = {
   path: 'order',
@@ -127,6 +127,8 @@ const route = {
 const api = {
   order: {
     ...CRUD('mall/order'),
+    exportDelivery: (params, filename, typeName) =>
+      REPORT('mall/order', params, filename, typeName),
     // 发货
     dispatch: (data) =>
       request({

+ 1 - 1
src/app/shop/admin/order/order/batchDispatch.vue

@@ -114,7 +114,7 @@
             dispatchForm.append(name, dispatchData[name]);
           }
 
-          let { error, data } = await api.order.dispatchByUpload(dispatchForm);
+          let { code, data } = await api.order.dispatchByUpload(dispatchForm);
           if (code == '200')
             useModal(
               OrderLoopDispatch,

+ 13 - 6
src/app/shop/admin/order/order/index.vue

@@ -49,17 +49,14 @@
                 icon="RefreshRight"
                 @click="getData()"
               ></el-button>
-              <el-button
-                :loading="exportLoading"
-                :disabled="exportLoading"
-                @click="onExport('export')"
+              <el-button :loading="exportLoading" :disabled="exportLoading" @click="onExport()"
                 >订单导出</el-button
               >
               <el-button
                 v-if="currentStatus == 'nosend'"
                 :loading="exportLoading"
                 :disabled="exportLoading"
-                @click="onExport('exportDelivery')"
+                @click="onExportDelivery()"
                 >导出发货单</el-button
               >
             </div>
@@ -408,7 +405,7 @@
 
   // 导出订单/导出发货单
   const exportLoading = ref(false);
-  async function onExport(type) {
+  async function onExport() {
     exportLoading.value = true;
     try {
       // 构建导出参数,使用当前搜索条件但不包含分页参数
@@ -430,8 +427,18 @@
     exportLoading.value = false;
   }
 
+  async function onExportDelivery() {
+    try {
+      exportLoading.value = true;
+      await api.order.exportDelivery({}, '发货订单', 'exportDelivery');
+    } finally {
+      exportLoading.value = false;
+    }
+  }
+
   const batchHandleTools = [
     {
+      operType: 'all',
       type: 'all',
       label: '批量发货',
       buttonType: 'default',

+ 7 - 7
src/sheep/request/crud.js

@@ -134,8 +134,8 @@ export const REPORT = async (url, params, filename = '导出数据', typeName =
     // 发送导出请求
     response = await request({
       url: url + `/${typeName}`,
-      method: typeName == 'export' ? 'POST' : 'GET',
-      ...(typeName == 'export' ? { data: params } : { params }),
+      method: typeName == 'report' ? 'GET' : 'POST',
+      ...(typeName == 'report' ? { params } : { data: params }),
       responseType: 'blob', // 用于文件下载
       options: {
         showSuccessMessage: false,
@@ -170,11 +170,11 @@ export const REPORT = async (url, params, filename = '导出数据', typeName =
       }
 
       // 检查返回的 code
-      if (errorData.code !== '200') {
-        const errorMessage = errorData.message || '导出失败';
-        ElMessage.error(errorMessage);
-        return Promise.reject(new Error(errorMessage));
-      }
+      // if (errorData.code !== '200') {
+      //   const errorMessage = errorData.message || '导出失败';
+      //   ElMessage.error(errorMessage);
+      //   return Promise.reject(new Error(errorMessage));
+      // }
     }
   } catch (error) {
     console.error('导出失败:', error);