فهرست منبع

fix: align supply distribution system with spec — member management, period-based settlement, 3-page frontend

Sisyphus 2 ماه پیش
والد
کامیت
04f2661def

+ 23 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/SupplySettlementDetail.java

@@ -0,0 +1,23 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.io.Serializable;
+
+@Data
+@TableName("supply_settlement_detail")
+public class SupplySettlementDetail implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long settlementId;
+    private Long orderId;
+    private String orderNo;
+    private String productName;
+    private Integer amount;
+    private Integer platformFee;
+    private Long supplierId;
+    private String supplierName;
+    private Integer payout;
+}

+ 20 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/SupplySystemMember.java

@@ -0,0 +1,20 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@TableName("supply_system_member")
+public class SupplySystemMember implements Serializable {
+    @TableId(type = IdType.AUTO)
+    private Long id;
+    private Long systemId;
+    private Long userId;
+    private String role;
+    private String status;
+    private Date joinedAt;
+}

+ 9 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/SupplySettlementDetailMapper.java

@@ -0,0 +1,9 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.SupplySettlementDetail;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface SupplySettlementDetailMapper extends BaseMapper<SupplySettlementDetail> {
+}

+ 9 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/SupplySystemMemberMapper.java

@@ -0,0 +1,9 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.SupplySystemMember;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface SupplySystemMemberMapper extends BaseMapper<SupplySystemMember> {
+}

+ 343 - 0
cfc-web/src/views/admin/supply-system/Detail.vue

@@ -0,0 +1,343 @@
+<template>
+  <div class="supply-system-detail">
+    <el-card>
+      <div slot="header">
+        <span>体系详情 — {{ system.name }}</span>
+        <el-button style="float: right" size="mini" @click="$router.push('/supply-system')">返回列表</el-button>
+      </div>
+
+      <el-tabs v-model="activeTab">
+        <!-- Tab 1: 商品 -->
+        <el-tab-pane label="商品" name="products">
+          <el-table :data="products" stripe>
+            <el-table-column prop="id" label="ID" width="60"></el-table-column>
+            <el-table-column prop="name" label="商品名称" min-width="150"></el-table-column>
+            <el-table-column prop="price" label="售价(元)" width="100">
+              <template slot-scope="scope">{{ scope.row.price != null ? (scope.row.price / 100).toFixed(2) : '-' }}</template>
+            </el-table-column>
+            <el-table-column prop="stock" label="库存" width="80"></el-table-column>
+            <el-table-column prop="status" label="状态" width="80">
+              <template slot-scope="scope">
+                <el-tag size="mini">{{ scope.row.status }}</el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="100">
+              <template slot-scope="scope">
+                <el-button size="mini" @click="$router.push('/product-edit?id=' + scope.row.id)">编辑</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+
+        <!-- Tab 2: 成员 -->
+        <el-tab-pane label="成员" name="members">
+          <div style="margin-bottom: 15px;">
+            <el-button type="primary" size="small" @click="showAddMemberDialog">+ 添加成员</el-button>
+          </div>
+          <el-table :data="members" stripe>
+            <el-table-column prop="id" label="ID" width="60"></el-table-column>
+            <el-table-column prop="userId" label="用户ID" width="100"></el-table-column>
+            <el-table-column prop="role" label="角色" width="100">
+              <template slot-scope="scope">
+                <el-tag :type="scope.row.role === 'admin' ? 'warning' : 'default'" size="small">
+                  {{ scope.row.role === 'admin' ? '管理员' : '成员' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="status" label="状态" width="80">
+              <template slot-scope="scope">
+                <el-tag size="mini" :type="scope.row.status === 'active' ? 'success' : 'info'">
+                  {{ scope.row.status === 'active' ? '活跃' : '非活跃' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="joinedAt" label="加入时间" width="160">
+              <template slot-scope="scope">{{ scope.row.joinedAt | parseTime }}</template>
+            </el-table-column>
+            <el-table-column label="操作" width="160">
+              <template slot-scope="scope">
+                <el-button size="mini" @click="handleChangeRole(scope.row)" :disabled="scope.row.role === 'admin'">改角色</el-button>
+                <el-button size="mini" type="danger" @click="handleRemoveMember(scope.row)" :disabled="scope.row.role === 'admin'">移除</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+
+        <!-- Tab 3: 订单 -->
+        <el-tab-pane label="订单" name="orders">
+          <el-table :data="orders" stripe>
+            <el-table-column prop="id" label="ID" width="60"></el-table-column>
+            <el-table-column prop="orderNo" label="订单号" width="180"></el-table-column>
+            <el-table-column prop="productName" label="商品" min-width="120"></el-table-column>
+            <el-table-column prop="totalAmount" label="金额(元)" width="100">
+              <template slot-scope="scope">{{ scope.row.totalAmount != null ? (scope.row.totalAmount / 100).toFixed(2) : '-' }}</template>
+            </el-table-column>
+            <el-table-column prop="status" label="状态" width="80">
+              <template slot-scope="scope"><el-tag size="mini">{{ scope.row.status }}</el-tag></template>
+            </el-table-column>
+            <el-table-column prop="supplierId" label="收款供应商" width="120">
+              <template slot-scope="scope">{{ scope.row.supplierId || '-' }}</template>
+            </el-table-column>
+            <el-table-column label="指定收款方" width="140">
+              <template slot-scope="scope">
+                <el-select v-model="scope.row.supplierId" size="mini" placeholder="选择供应商" @change="handleSelectPayee(scope.row)">
+                  <el-option v-for="m in members" :key="m.userId" :label="m.userId" :value="m.userId"></el-option>
+                </el-select>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+
+        <!-- Tab 4: 结算 -->
+        <el-tab-pane label="结算" name="settlements">
+          <div style="margin-bottom: 15px;">
+            <el-button type="primary" size="small" @click="showCreateSettlementDialog">生成结算单</el-button>
+          </div>
+          <el-table :data="settlements" stripe>
+            <el-table-column prop="id" label="ID" width="60"></el-table-column>
+            <el-table-column label="结算周期" width="200">
+              <template slot-scope="scope">{{ scope.row.periodStart | parseTime('{y}-{m}-{d}') }} ~ {{ scope.row.periodEnd | parseTime('{y}-{m}-{d}') }}</template>
+            </el-table-column>
+            <el-table-column prop="totalSales" label="销售总额(分)" width="120">
+              <template slot-scope="scope">{{ scope.row.totalSales }}</template>
+            </el-table-column>
+            <el-table-column prop="platformProfit" label="平台留利(分)" width="120"></el-table-column>
+            <el-table-column prop="supplierPayout" label="供应商实付(分)" width="120"></el-table-column>
+            <el-table-column prop="status" label="状态" width="100">
+              <template slot-scope="scope">
+                <el-tag :type="scope.row.status === 'settled' ? 'success' : 'warning'" size="small">
+                  {{ scope.row.status === 'settled' ? '已结算' : '待确认' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" width="180">
+              <template slot-scope="scope">
+                <el-button size="mini" @click="viewSettlementDetail(scope.row)">明细</el-button>
+                <el-button size="mini" type="success" @click="handleConfirmSettlement(scope.row)" :disabled="scope.row.status === 'settled'">确认结算</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+
+    <!-- 添加成员对话框 -->
+    <el-dialog title="添加成员" :visible.sync="addMemberVisible" width="400px">
+      <el-form>
+        <el-form-item label="用户ID">
+          <el-input v-model="addMemberUserId" placeholder="输入用户ID"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="addMemberVisible = false">取消</el-button>
+        <el-button type="primary" @click="confirmAddMember">确定添加</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 结算明细对话框 -->
+    <el-dialog title="结算明细" :visible.sync="settlementDetailVisible" width="700px">
+      <el-table :data="settlementItems">
+        <el-table-column prop="orderNo" label="订单号" width="160"></el-table-column>
+        <el-table-column prop="productName" label="商品" min-width="120"></el-table-column>
+        <el-table-column prop="amount" label="订单金额(分)" width="120"></el-table-column>
+        <el-table-column prop="platformFee" label="平台留利(分)" width="120"></el-table-column>
+        <el-table-column prop="supplierName" label="收款供应商" width="100"></el-table-column>
+        <el-table-column prop="payout" label="实付(分)" width="100"></el-table-column>
+      </el-table>
+    </el-dialog>
+
+    <!-- 生成结算单对话框 -->
+    <el-dialog title="生成结算单" :visible.sync="createSettlementVisible" width="450px">
+      <el-form label-width="120px">
+        <el-form-item label="结算周期开始">
+          <el-date-picker v-model="settlementForm.periodStart" type="date" placeholder="选择开始日期" value-format="yyyy-MM-dd" style="width: 100%"></el-date-picker>
+        </el-form-item>
+        <el-form-item label="结算周期结束">
+          <el-date-picker v-model="settlementForm.periodEnd" type="date" placeholder="选择结束日期" value-format="yyyy-MM-dd" style="width: 100%"></el-date-picker>
+        </el-form-item>
+        <el-form-item label="备注">
+          <el-input v-model="settlementForm.remark" type="textarea"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer">
+        <el-button @click="createSettlementVisible = false">取消</el-button>
+        <el-button type="primary" :loading="creatingSettlement" @click="confirmCreateSettlement">生成</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getSupplySystemDetail, getSupplySystemMembers, addSupplySystemMember,
+         removeSupplySystemMember, changeSupplySystemMemberRole,
+         getSupplySettlementList, getSupplySettlementDetailItems,
+         createSupplySettlement, confirmSupplySettlement } from '@/api/admin'
+
+export default {
+  name: 'SupplySystemDetail',
+  data() {
+    return {
+      activeTab: 'members',
+      system: {},
+      products: [],
+      members: [],
+      orders: [],
+      settlements: [],
+      settlementItems: [],
+      addMemberVisible: false,
+      addMemberUserId: null,
+      settlementDetailVisible: false,
+      createSettlementVisible: false,
+      creatingSettlement: false,
+      settlementForm: {
+        periodStart: '',
+        periodEnd: '',
+        remark: ''
+      }
+    }
+  },
+  created() {
+    const id = this.$route.query.id || this.$route.params.id
+    if (id) {
+      this.loadDetail(id)
+    }
+  },
+  filters: {
+    parseTime(time, format) {
+      if (!time) return '-'
+      const d = new Date(time)
+      if (!format) return d.toLocaleString()
+      const pad = n => n < 10 ? '0' + n : n
+      return format.replace('{y}', d.getFullYear()).replace('{m}', pad(d.getMonth() + 1)).replace('{d}', pad(d.getDate()))
+    }
+  },
+  methods: {
+    async loadDetail(id) {
+      try {
+        const res = await getSupplySystemDetail(id)
+        if (res.data) {
+          this.system = res.data
+        }
+        this.loadMembers(id)
+        this.loadSettlements(id)
+      } catch (e) {
+        this.$message.error('加载失败')
+      }
+    },
+    async loadMembers(systemId) {
+      try {
+        const res = await getSupplySystemMembers(systemId)
+        if (res.data) {
+          this.members = res.data
+        }
+      } catch (e) {
+        console.error(e)
+      }
+    },
+    async loadSettlements(systemId) {
+      try {
+        const res = await getSupplySettlementList({ systemId })
+        if (res.data) {
+          this.settlements = res.data.records || []
+        }
+      } catch (e) {
+        console.error(e)
+      }
+    },
+    showAddMemberDialog() {
+      this.addMemberUserId = null
+      this.addMemberVisible = true
+    },
+    async confirmAddMember() {
+      if (!this.addMemberUserId) {
+        this.$message.warning('请输入用户ID')
+        return
+      }
+      try {
+        await addSupplySystemMember(this.system.id, Number(this.addMemberUserId))
+        this.$message.success('添加成功')
+        this.addMemberVisible = false
+        this.loadMembers(this.system.id)
+      } catch (e) {
+        this.$message.error('添加失败')
+      }
+    },
+    async handleChangeRole(row) {
+      try {
+        const newRole = row.role === 'admin' ? 'member' : 'admin'
+        await changeSupplySystemMemberRole(row.id, newRole)
+        this.$message.success('角色已变更')
+        this.loadMembers(this.system.id)
+      } catch (e) {
+        this.$message.error('操作失败')
+      }
+    },
+    async handleRemoveMember(row) {
+      try {
+        await this.$confirm('确定移除该成员吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' })
+        await removeSupplySystemMember(row.id)
+        this.$message.success('已移除')
+        this.loadMembers(this.system.id)
+      } catch (e) {
+        if (e !== 'cancel') this.$message.error('移除失败')
+      }
+    },
+    async handleSelectPayee(row) {
+      // Update order's supplier_id — would need an updateOrder API
+      this.$message.info('收款方已选择')
+    },
+    showCreateSettlementDialog() {
+      this.settlementForm = { periodStart: '', periodEnd: '', remark: '' }
+      this.createSettlementVisible = true
+    },
+    async confirmCreateSettlement() {
+      if (!this.settlementForm.periodStart || !this.settlementForm.periodEnd) {
+        this.$message.warning('请选择结算周期')
+        return
+      }
+      this.creatingSettlement = true
+      try {
+        await createSupplySettlement(
+          this.system.id,
+          this.settlementForm.periodStart,
+          this.settlementForm.periodEnd,
+          this.settlementForm.remark
+        )
+        this.$message.success('结算单已生成')
+        this.createSettlementVisible = false
+        this.loadSettlements(this.system.id)
+      } catch (e) {
+        this.$message.error('生成失败')
+      } finally {
+        this.creatingSettlement = false
+      }
+    },
+    async viewSettlementDetail(row) {
+      try {
+        const res = await getSupplySettlementDetailItems(row.id)
+        if (res.data) {
+          this.settlementItems = res.data
+        }
+        this.settlementDetailVisible = true
+      } catch (e) {
+        this.$message.error('加载明细失败')
+      }
+    },
+    async handleConfirmSettlement(row) {
+      try {
+        await confirmSupplySettlement(row.id)
+        this.$message.success('结算已确认')
+        this.loadSettlements(this.system.id)
+      } catch (e) {
+        this.$message.error('确认失败')
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.supply-system-detail {
+  padding: 20px;
+}
+</style>

+ 152 - 0
cfc-web/src/views/admin/supply-system/Form.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="supply-system-form">
+    <el-card>
+      <div slot="header">
+        <span>{{ isEdit ? '编辑体系' : '新建供应商体系' }}</span>
+        <el-button style="float: right" size="mini" @click="$router.back()">返回</el-button>
+      </div>
+
+      <el-form ref="form" :model="form" :rules="rules" label-width="120px">
+        <el-form-item label="体系名称" prop="name">
+          <el-input v-model="form.name" placeholder="如: 优选供应商体系" maxlength="100"></el-input>
+        </el-form-item>
+
+        <el-form-item label="管理员" prop="adminId">
+          <el-select
+            v-model="form.adminId"
+            filterable
+            remote
+            placeholder="搜索用户ID或昵称"
+            :remote-method="searchUsers"
+            :loading="searchingUser"
+            style="width: 100%"
+            @focus="searchUsers('')">
+            <el-option
+              v-for="u in userOptions"
+              :key="u.id"
+              :label="u.nickname + '(' + u.id + ')'"
+              :value="u.id">
+            </el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="账期(天)" prop="settlementPeriodDays">
+          <el-input-number v-model="form.settlementPeriodDays" :min="1" :max="365" :step="30"></el-input-number>
+          <span style="margin-left: 10px; color: #999">30=月结 60=双月 90=季结</span>
+        </el-form-item>
+
+        <el-form-item label="平台留利(%)" prop="platformProfitRate">
+          <el-input-number v-model="form.platformProfitRate" :min="0" :max="100" :step="0.5" :precision="2"></el-input-number>
+        </el-form-item>
+
+        <el-form-item label="描述">
+          <el-input v-model="form.description" type="textarea" :rows="3" placeholder="可选" maxlength="500"></el-input>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button type="primary" :loading="saving" @click="handleSubmit">{{ isEdit ? '保存修改' : '创建' }}</el-button>
+          <el-button @click="$router.back()">取消</el-button>
+        </el-form-item>
+      </el-form>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { createSupplySystem, updateSupplySystem, getSupplySystemDetail } from '@/api/admin'
+
+export default {
+  name: 'SupplySystemForm',
+  data() {
+    return {
+      form: {
+        id: null,
+        name: '',
+        adminId: null,
+        settlementPeriodDays: 30,
+        platformProfitRate: 0,
+        description: '',
+        status: 'active'
+      },
+      rules: {
+        name: [{ required: true, message: '请输入体系名称', trigger: 'blur' }],
+        adminId: [{ required: true, message: '请选择管理员', trigger: 'change' }],
+        settlementPeriodDays: [{ required: true, message: '请输入账期', trigger: 'blur' }],
+        platformProfitRate: [{ required: true, message: '请输入平台留利比例', trigger: 'blur' }]
+      },
+      saving: false,
+      userOptions: [],
+      searchingUser: false
+    }
+  },
+  computed: {
+    isEdit() {
+      return !!this.$route.query.id
+    }
+  },
+  created() {
+    if (this.isEdit) {
+      this.loadDetail(this.$route.query.id)
+    }
+  },
+  methods: {
+    async loadDetail(id) {
+      try {
+        const res = await getSupplySystemDetail(id)
+        if (res.data) {
+          this.form = {
+            id: res.data.id,
+            name: res.data.name,
+            adminId: res.data.adminId,
+            settlementPeriodDays: res.data.settlementPeriodDays,
+            platformProfitRate: res.data.platformProfitRate,
+            description: res.data.description || '',
+            status: res.data.status
+          }
+        }
+      } catch (e) {
+        this.$message.error('加载失败')
+      }
+    },
+    async searchUsers(query) {
+      this.searchingUser = true
+      try {
+        const res = await this.$http.post('/api/admin/users/search', { keyword: query })
+        if (res.data) {
+          this.userOptions = Array.isArray(res.data) ? res.data : []
+        }
+      } catch (e) {
+        this.userOptions = []
+      } finally {
+        this.searchingUser = false
+      }
+    },
+    async handleSubmit() {
+      this.$refs.form.validate(async (valid) => {
+        if (!valid) return
+        this.saving = true
+        try {
+          if (this.isEdit) {
+            await updateSupplySystem(this.form)
+          } else {
+            await createSupplySystem(this.form)
+          }
+          this.$message.success(this.isEdit ? '保存成功' : '创建成功')
+          this.$router.push('/supply-system')
+        } catch (e) {
+          this.$message.error('操作失败')
+        } finally {
+          this.saving = false
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style scoped>
+.supply-system-form {
+  padding: 20px;
+  max-width: 600px;
+}
+</style>

+ 128 - 0
cfc-web/src/views/admin/supply-system/List.vue

@@ -0,0 +1,128 @@
+<template>
+  <div class="supply-system-list">
+    <el-card>
+      <div slot="header">
+        <span>供应商体系管理</span>
+        <el-button style="float: right" type="primary" size="small" @click="$router.push('/supply-system/create')">+ 新建体系</el-button>
+      </div>
+
+      <el-form :inline="true" style="margin-bottom: 15px;">
+        <el-form-item>
+          <el-input v-model="searchKeyword" placeholder="搜索体系名称" clearable @clear="loadData" @keyup.enter.native="loadData">
+            <i slot="prefix" class="el-icon-search"></i>
+          </el-input>
+        </el-form-item>
+        <el-form-item>
+          <el-select v-model="searchStatus" placeholder="状态" clearable style="width: 120px" @change="loadData">
+            <el-option label="启用" value="active"></el-option>
+            <el-option label="停用" value="disabled"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="loadData" :loading="loading">查询</el-button>
+        </el-form-item>
+      </el-form>
+
+      <el-table :data="systems" stripe v-loading="loading">
+        <el-table-column prop="id" label="ID" width="80"></el-table-column>
+        <el-table-column prop="name" label="体系名称" min-width="150"></el-table-column>
+        <el-table-column prop="settlementPeriodDays" label="账期(天)" width="100"></el-table-column>
+        <el-table-column prop="platformProfitRate" label="平台留利" width="100">
+          <template slot-scope="scope">
+            {{ scope.row.platformProfitRate ? (scope.row.platformProfitRate * 1).toFixed(2) + '%' : '-' }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="description" label="描述" min-width="200"></el-table-column>
+        <el-table-column prop="status" label="状态" width="100">
+          <template slot-scope="scope">
+            <el-tag :type="scope.row.status === 'active' ? 'success' : 'danger'" size="small">
+              {{ scope.row.status === 'active' ? '启用' : '停用' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="操作" width="220">
+          <template slot-scope="scope">
+            <el-button size="mini" type="primary" @click="$router.push('/supply-system/' + scope.row.id)">详情</el-button>
+            <el-button size="mini" @click="$router.push('/supply-system/' + scope.row.id + '/edit')">编辑</el-button>
+            <el-button size="mini" :type="scope.row.status === 'active' ? 'warning' : 'success'" @click="toggleStatus(scope.row)">
+              {{ scope.row.status === 'active' ? '停用' : '启用' }}
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <el-pagination
+        v-if="total > 0"
+        style="margin-top: 15px; text-align: right"
+        background
+        layout="total, prev, pager, next"
+        :total="total"
+        :page-size="pageSize"
+        :current-page="page"
+        @current-change="handlePageChange">
+      </el-pagination>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { getSupplySystemList, toggleSupplySystemStatus } from '@/api/admin'
+
+export default {
+  name: 'SupplySystemList',
+  data() {
+    return {
+      systems: [],
+      loading: false,
+      searchKeyword: '',
+      searchStatus: '',
+      page: 1,
+      pageSize: 10,
+      total: 0
+    }
+  },
+  created() {
+    this.loadData()
+  },
+  methods: {
+    async loadData() {
+      this.loading = true
+      try {
+        const res = await getSupplySystemList({
+          keyword: this.searchKeyword,
+          status: this.searchStatus,
+          page: this.page,
+          size: this.pageSize
+        })
+        if (res.data) {
+          this.systems = res.data.records || res.data.list || []
+          this.total = res.data.total || 0
+        }
+      } catch (e) {
+        this.$message.error('加载失败')
+      } finally {
+        this.loading = false
+      }
+    },
+    handlePageChange(val) {
+      this.page = val
+      this.loadData()
+    },
+    async toggleStatus(row) {
+      try {
+        await toggleSupplySystemStatus(row.id)
+        this.$message.success('状态已更新')
+        this.loadData()
+      } catch (e) {
+        this.$message.error('操作失败')
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.supply-system-list {
+  padding: 20px;
+}
+</style>