瀏覽代碼

feat: 新增供应链管理相关页面
- 成本管理页面
- 交付管理页面
- 支付管理页面
- 权重管理页面

wangyuhao 4 月之前
父節點
當前提交
0994456079
共有 4 個文件被更改,包括 1008 次插入0 次删除
  1. 210 0
      src/views/supply/cost/index.vue
  2. 231 0
      src/views/supply/delivery/index.vue
  3. 197 0
      src/views/supply/payment/index.vue
  4. 370 0
      src/views/supply/weights/index.vue

+ 210 - 0
src/views/supply/cost/index.vue

@@ -0,0 +1,210 @@
+<template>
+  <div class="app-container">
+    <div class="page-header">
+      <h2><i class="el-icon-s-order"></i> 供应商成本分析</h2>
+      <p class="page-desc">分析各供应商针对特定产品的报价及成本竞争力</p>
+    </div>
+
+    <!-- 搜索框 -->
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-search"></i> 查询产品成本分析</span>
+      </div>
+      <el-form :inline="true" class="form-inline">
+        <el-form-item label="产品编码">
+          <el-input
+            v-model="inputProductCode"
+            placeholder="请输入产品编码(如:20220606J0100MR4)"
+            style="width: 300px"
+            @keyup.enter.native="fetchCostData(inputProductCode)"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="fetchCostData(inputProductCode)"
+            >分析成本</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 表格数据 -->
+    <el-card v-loading="loading" class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-document"></i> 成本详情表格</span>
+        <el-button
+          v-if="costDetails.length > 0"
+          style="float: right; padding: 3px 0"
+          type="text"
+          @click="exportData"
+        >
+          导出数据
+        </el-button>
+      </div>
+
+      <el-table
+        v-if="costDetails.length > 0"
+        :data="costDetails"
+        highlight-current-row
+        style="width: 100%"
+      >
+        <el-table-column prop="供应商名称" label="供应商名称" width="200" />
+        <el-table-column prop="参考价" label="参考价" width="120">
+          <template slot-scope="scope">
+            ¥{{ parseFloat(scope.row.参考价).toFixed(2) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="成本排名" label="成本排名" width="120">
+          <template slot-scope="scope"> 第{{ scope.row.成本排名 }}名 </template>
+        </el-table-column>
+        <el-table-column prop="成本分数" label="成本分数" width="120">
+          <template slot-scope="scope">
+            {{ parseFloat(scope.row.成本分数).toFixed(2) }}
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div v-else class="no-data">
+        <p v-if="error" class="error">{{ error }}</p>
+        <p v-else>暂无成本数据,请输入产品编码进行分析</p>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import { download } from "@/utils";
+import request from "@/utils/request";
+
+export default {
+  name: "SupplyCostAnalysis",
+  data() {
+    return {
+      inputProductCode: "",
+      costDetails: [],
+      loading: false,
+      error: "",
+    };
+  },
+  created() {
+    // 如果有传入的 productCode,则自动触发分析
+    if (this.$route.query.productCode) {
+      this.inputProductCode = this.$route.query.productCode;
+      this.fetchCostData(this.inputProductCode);
+    }
+  },
+  methods: {
+    // 获取成本数据
+    async fetchCostData(code) {
+      if (!code) {
+        this.$modal.msgError("请输入产品编码");
+        return;
+      }
+
+      this.loading = true;
+      this.error = "";
+
+      try {
+        // 使用项目标准的request方式调用API
+        const response = await request({
+          url: `/system/supplier/cost/${code}`,
+          method: "get",
+        });
+
+        if (response.code === 200) {
+          this.costDetails = response.data.cost_details || [];
+          this.$modal.msgSuccess("成本分析完成");
+        } else {
+          this.error = response.msg || "获取成本数据失败";
+          this.$modal.msgError(this.error);
+        }
+      } catch (err) {
+        console.error("获取成本数据失败:", err);
+        this.error = err.message || "获取成本数据失败";
+        this.$modal.msgError(this.error);
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 导出数据
+    exportData() {
+      if (!this.costDetails || this.costDetails.length === 0) {
+        this.$modal.msgError("暂无数据可导出");
+        return;
+      }
+
+      // 创建CSV内容
+      const header = ["供应商名称", "参考价", "成本排名", "成本分数"].join(",");
+      const csvContent = [
+        header,
+        ...this.costDetails.map((row) =>
+          [
+            `"${row.供应商名称}"`,
+            row.参考价,
+            `第${row.成本排名}名`,
+            row.成本分数,
+          ].join(",")
+        ),
+      ].join("\n");
+
+      // 下载文件
+      const blob = new Blob(["\ufeff" + csvContent], {
+        type: "text/csv;charset=utf-8;",
+      });
+      download(blob, `供应商成本分析_${new Date().getTime()}.csv`);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+}
+
+.page-header {
+  margin-bottom: 20px;
+
+  h2 {
+    font-size: 24px;
+    font-weight: 600;
+    color: #303133;
+    margin-bottom: 8px;
+
+    i {
+      margin-right: 8px;
+      color: #409eff;
+    }
+  }
+
+  .page-desc {
+    color: #909399;
+    font-size: 14px;
+    margin: 0;
+  }
+}
+
+.box-card {
+  margin-bottom: 20px;
+}
+
+.form-inline {
+  display: flex;
+  align-items: center;
+}
+
+.no-data {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+
+  .error {
+    color: #f56c6c;
+  }
+}
+
+::v-deep .el-card__header {
+  font-weight: bold;
+}
+</style>

+ 231 - 0
src/views/supply/delivery/index.vue

@@ -0,0 +1,231 @@
+<template>
+  <div class="app-container">
+    <div class="page-header">
+      <h2><i class="el-icon-s-opportunity"></i> 供应商交付分析</h2>
+      <p class="page-desc">分析各供应商针对特定产品的交付表现</p>
+    </div>
+
+    <!-- 搜索框 -->
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-search"></i> 查询产品交付分析</span>
+      </div>
+      <el-form :inline="true" class="form-inline">
+        <el-form-item label="产品编码">
+          <el-input
+            v-model="inputProductCode"
+            placeholder="请输入产品编码(如:20220606J0100MR4)"
+            style="width: 300px"
+            @keyup.enter.native="fetchDeliveryData(inputProductCode)"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="fetchDeliveryData(inputProductCode)"
+            >分析交付</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 表格数据 -->
+    <el-card v-loading="loading" class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-document"></i> 交付详情表格</span>
+        <el-button
+          v-if="deliveryDetails.length > 0"
+          style="float: right; padding: 3px 0"
+          type="text"
+          @click="exportData"
+        >
+          导出数据
+        </el-button>
+      </div>
+
+      <el-table
+        v-if="deliveryDetails.length > 0"
+        :data="deliveryDetails"
+        highlight-current-row
+        style="width: 100%"
+      >
+        <el-table-column prop="供应商名称" label="供应商名称" width="150" />
+        <el-table-column prop="交付分数" label="交付分数" width="120">
+          <template slot-scope="scope">
+            {{ parseFloat(scope.row.交付分数).toFixed(2) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="D1_准时率" label="准时率 (%)" width="120">
+          <template slot-scope="scope">
+            {{ parseFloat(scope.row.D1_准时率).toFixed(2) }}%
+          </template>
+        </el-table-column>
+        <el-table-column prop="D2_平均偏差" label="平均偏差 (天)" width="130">
+          <template slot-scope="scope">
+            {{ parseFloat(scope.row.D2_平均偏差).toFixed(2) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="D3_最长延迟" label="最长延迟 (天)" width="130">
+          <template slot-scope="scope">
+            {{ parseFloat(scope.row.D3_最长延迟).toFixed(2) }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="D4_满足率" label="满足率 (%)" width="120">
+          <template slot-scope="scope">
+            {{ parseFloat(scope.row.D4_满足率).toFixed(2) }}%
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div v-else class="no-data">
+        <p v-if="error" class="error">{{ error }}</p>
+        <p v-else>暂无交付数据,请输入产品编码进行分析</p>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import { download } from "@/utils";
+import request from "@/utils/request";
+
+export default {
+  name: "SupplyDeliveryAnalysis",
+  data() {
+    return {
+      inputProductCode: "",
+      deliveryDetails: [],
+      loading: false,
+      error: "",
+    };
+  },
+  created() {
+    // 如果有传入的 productCode,则自动触发分析
+    if (this.$route.query.productCode) {
+      this.inputProductCode = this.$route.query.productCode;
+      this.fetchDeliveryData(this.inputProductCode);
+    }
+  },
+  methods: {
+    // 获取交付数据
+    async fetchDeliveryData(code) {
+      if (!code) {
+        this.$modal.msgError("请输入产品编码");
+        return;
+      }
+
+      this.loading = true;
+      this.error = "";
+
+      try {
+        // 使用项目标准的request方式调用API
+        const response = await request({
+          url: `/system/supplier/delivery/${code}`,
+          method: "get",
+        });
+
+        if (response.code === 200) {
+          this.deliveryDetails = response.data.delivery_details || [];
+          this.$modal.msgSuccess("交付分析完成");
+        } else {
+          this.error = response.msg || "获取交付数据失败";
+          this.$modal.msgError(this.error);
+        }
+      } catch (err) {
+        console.error("获取交付数据失败:", err);
+        this.error = err.message || "获取交付数据失败";
+        this.$modal.msgError(this.error);
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 导出数据
+    exportData() {
+      if (!this.deliveryDetails || this.deliveryDetails.length === 0) {
+        this.$modal.msgError("暂无数据可导出");
+        return;
+      }
+
+      // 创建CSV内容
+      const header = [
+        "供应商名称",
+        "交付分数",
+        "准时率(%)",
+        "平均偏差(天)",
+        "最长延迟(天)",
+        "满足率(%)",
+      ].join(",");
+      const csvContent = [
+        header,
+        ...this.deliveryDetails.map((row) =>
+          [
+            `"${row.供应商名称}"`,
+            parseFloat(row.交付分数).toFixed(2),
+            parseFloat(row.D1_准时率).toFixed(2),
+            parseFloat(row.D2_平均偏差).toFixed(2),
+            parseFloat(row.D3_最长延迟).toFixed(2),
+            parseFloat(row.D4_满足率).toFixed(2),
+          ].join(",")
+        ),
+      ].join("\n");
+
+      // 下载文件
+      const blob = new Blob(["\ufeff" + csvContent], {
+        type: "text/csv;charset=utf-8;",
+      });
+      download(blob, `供应商交付分析_${new Date().getTime()}.csv`);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+}
+
+.page-header {
+  margin-bottom: 20px;
+
+  h2 {
+    font-size: 24px;
+    font-weight: 600;
+    color: #303133;
+    margin-bottom: 8px;
+
+    i {
+      margin-right: 8px;
+      color: #409eff;
+    }
+  }
+
+  .page-desc {
+    color: #909399;
+    font-size: 14px;
+    margin: 0;
+  }
+}
+
+.box-card {
+  margin-bottom: 20px;
+}
+
+.form-inline {
+  display: flex;
+  align-items: center;
+}
+
+.no-data {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+
+  .error {
+    color: #f56c6c;
+  }
+}
+
+::v-deep .el-card__header {
+  font-weight: bold;
+}
+</style>

+ 197 - 0
src/views/supply/payment/index.vue

@@ -0,0 +1,197 @@
+<template>
+  <div class="app-container">
+    <div class="page-header">
+      <h2><i class="el-icon-s-finance"></i> 供应商账期分析</h2>
+      <p class="page-desc">分析各供应商的结算账期条件</p>
+    </div>
+
+    <!-- 搜索框 -->
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-search"></i> 查询产品账期分析</span>
+      </div>
+      <el-form :inline="true" class="form-inline">
+        <el-form-item label="产品编码">
+          <el-input
+            v-model="inputProductCode"
+            placeholder="请输入产品编码(如:20220606J0100MR4)"
+            style="width: 300px"
+            @keyup.enter.native="fetchPaymentData(inputProductCode)"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="fetchPaymentData(inputProductCode)"
+            >分析账期</el-button
+          >
+        </el-form-item>
+      </el-form>
+    </el-card>
+
+    <!-- 表格数据 -->
+    <el-card v-loading="loading" class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-document"></i> 账期详情表格</span>
+        <el-button
+          v-if="paymentDetails.length > 0"
+          style="float: right; padding: 3px 0"
+          type="text"
+          @click="exportData"
+        >
+          导出数据
+        </el-button>
+      </div>
+
+      <el-table
+        v-if="paymentDetails.length > 0"
+        :data="paymentDetails"
+        highlight-current-row
+        style="width: 100%"
+      >
+        <el-table-column prop="供应商名称" label="供应商名称" width="200" />
+        <el-table-column prop="账期分数" label="账期分数" width="120">
+          <template slot-scope="scope">
+            {{ parseFloat(scope.row.账期分数).toFixed(2) }}
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div v-else class="no-data">
+        <p v-if="error" class="error">{{ error }}</p>
+        <p v-else>暂无账期数据,请输入产品编码进行分析</p>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+import { download } from "@/utils";
+import request from "@/utils/request";
+
+export default {
+  name: "SupplyPaymentAnalysis",
+  data() {
+    return {
+      inputProductCode: "",
+      paymentDetails: [],
+      loading: false,
+      error: "",
+    };
+  },
+  created() {
+    // 如果有传入的 productCode,则自动触发分析
+    if (this.$route.query.productCode) {
+      this.inputProductCode = this.$route.query.productCode;
+      this.fetchPaymentData(this.inputProductCode);
+    }
+  },
+  methods: {
+    // 获取账期数据
+    async fetchPaymentData(code) {
+      if (!code) {
+        this.$modal.msgError("请输入产品编码");
+        return;
+      }
+
+      this.loading = true;
+      this.error = "";
+
+      try {
+        // 使用项目标准的request方式调用API
+        const response = await request({
+          url: `/system/supplier/payment/${code}`,
+          method: "get",
+        });
+
+        if (response.code === 200) {
+          this.paymentDetails = response.data.payment_details || [];
+          this.$modal.msgSuccess("账期分析完成");
+        } else {
+          this.error = response.msg || "获取账期数据失败";
+          this.$modal.msgError(this.error);
+        }
+      } catch (err) {
+        console.error("获取账期数据失败:", err);
+        this.error = err.message || "获取账期数据失败";
+        this.$modal.msgError(this.error);
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 导出数据
+    exportData() {
+      if (!this.paymentDetails || this.paymentDetails.length === 0) {
+        this.$modal.msgError("暂无数据可导出");
+        return;
+      }
+
+      // 创建CSV内容
+      const header = ["供应商名称", "账期分数"].join(",");
+      const csvContent = [
+        header,
+        ...this.paymentDetails.map((row) =>
+          [`"${row.供应商名称}"`, parseFloat(row.账期分数).toFixed(2)].join(",")
+        ),
+      ].join("\n");
+
+      // 下载文件
+      const blob = new Blob(["\ufeff" + csvContent], {
+        type: "text/csv;charset=utf-8;",
+      });
+      download(blob, `供应商账期分析_${new Date().getTime()}.csv`);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+}
+
+.page-header {
+  margin-bottom: 20px;
+
+  h2 {
+    font-size: 24px;
+    font-weight: 600;
+    color: #303133;
+    margin-bottom: 8px;
+
+    i {
+      margin-right: 8px;
+      color: #409eff;
+    }
+  }
+
+  .page-desc {
+    color: #909399;
+    font-size: 14px;
+    margin: 0;
+  }
+}
+
+.box-card {
+  margin-bottom: 20px;
+}
+
+.form-inline {
+  display: flex;
+  align-items: center;
+}
+
+.no-data {
+  text-align: center;
+  padding: 40px 0;
+  color: #909399;
+
+  .error {
+    color: #f56c6c;
+  }
+}
+
+::v-deep .el-card__header {
+  font-weight: bold;
+}
+</style>

+ 370 - 0
src/views/supply/weights/index.vue

@@ -0,0 +1,370 @@
+<template>
+  <div class="app-container">
+    <div class="page-header">
+      <h2><i class="el-icon-setting"></i> 权重配置管理</h2>
+      <p class="page-desc">自定义成本、交付、账期三个维度的评估权重</p>
+    </div>
+
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-edit-outline"></i> 权重配置</span>
+      </div>
+
+      <el-form
+        :model="weights"
+        :rules="rules"
+        ref="weightsForm"
+        label-width="120px"
+      >
+        <el-form-item label="成本权重" prop="成本">
+          <el-slider
+            v-model="weights.成本"
+            :step="0.01"
+            :min="0"
+            :max="1"
+            show-input
+            @change="onWeightChange"
+          />
+        </el-form-item>
+
+        <el-form-item label="交付权重" prop="交付">
+          <el-slider
+            v-model="weights.交付"
+            :step="0.01"
+            :min="0"
+            :max="1"
+            show-input
+            @change="onWeightChange"
+          />
+        </el-form-item>
+
+        <el-form-item label="账期权重" prop="账期">
+          <el-slider
+            v-model="weights.账期"
+            :step="0.01"
+            :min="0"
+            :max="1"
+            show-input
+            @change="onWeightChange"
+          />
+        </el-form-item>
+
+        <el-form-item>
+          <div class="weight-summary">
+            <p>权重总和: {{ totalWeight.toFixed(2) }}</p>
+            <p v-if="Math.abs(totalWeight - 1) > 0.001" class="warning">
+              警告: 权重总和应为1
+            </p>
+          </div>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button
+            type="primary"
+            :disabled="Math.abs(totalWeight - 1) > 0.001"
+            @click="updateWeights"
+          >
+            保存权重
+          </el-button>
+          <el-button @click="resetWeights">重置</el-button>
+        </el-form-item>
+      </el-form>
+
+      <div
+        v-if="message"
+        class="el-alert"
+        :class="'el-alert--' + (isError ? 'error' : 'success')"
+      >
+        <div class="el-alert__content">
+          <span class="el-alert__description">{{ message }}</span>
+        </div>
+      </div>
+    </el-card>
+
+    <!-- 当前权重展示 -->
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span><i class="el-icon-data-line"></i> 当前评估维度权重配置</span>
+      </div>
+
+      <div class="weight-display">
+        <div class="weight-info">
+          当前配置:成本 {{ (weights.成本 * 100).toFixed(0) }}% | 交付
+          {{ (weights.交付 * 100).toFixed(0) }}% | 账期
+          {{ (weights.账期 * 100).toFixed(0) }}%
+        </div>
+
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <div class="info-box">
+              <div class="info-label">💰 成本维度</div>
+              <div class="info-value" style="color: #5b6cff">
+                {{ (weights.成本 * 100).toFixed(0) }}%
+              </div>
+              <div class="info-detail">
+                评分规则:价格排名<br />
+                第1名: 100分<br />
+                第2名: 90分<br />
+                第3名: 80分
+              </div>
+            </div>
+          </el-col>
+
+          <el-col :span="8">
+            <div class="info-box">
+              <div class="info-label">🚚 交付维度</div>
+              <div class="info-value" style="color: #52c41a">
+                {{ (weights.交付 * 100).toFixed(0) }}%
+              </div>
+              <div class="info-detail">
+                D1-准时率: 50%<br />
+                D2-平均偏差: 30%<br />
+                D3-最长延迟: 10%<br />
+                D4-数量满足率: 10%
+              </div>
+            </div>
+          </el-col>
+
+          <el-col :span="8">
+            <div class="info-box">
+              <div class="info-label">💳 账期维度</div>
+              <div class="info-value" style="color: #ff9800">
+                {{ (weights.账期 * 100).toFixed(0) }}%
+              </div>
+              <div class="info-detail">
+                ≥90天: 100分<br />
+                ≥60天: 90分<br />
+                ≥45天: 80分<br />
+                ≥30天: 60分
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+      </div>
+    </el-card>
+  </div>
+</template>
+
+<script>
+import request from "@/utils/request";
+
+export default {
+  name: "SupplyWeightsConfig",
+  data() {
+    return {
+      weights: {
+        成本: 0.4,
+        交付: 0.4,
+        账期: 0.2,
+      },
+      loading: false,
+      message: "",
+      isError: false,
+      rules: {
+        成本: [
+          { required: true, message: "请输入成本权重", trigger: "blur" },
+          {
+            type: "number",
+            min: 0,
+            max: 1,
+            message: "权重应在0到1之间",
+            trigger: "blur",
+          },
+        ],
+        交付: [
+          { required: true, message: "请输入交付权重", trigger: "blur" },
+          {
+            type: "number",
+            min: 0,
+            max: 1,
+            message: "权重应在0到1之间",
+            trigger: "blur",
+          },
+        ],
+        账期: [
+          { required: true, message: "请输入账期权重", trigger: "blur" },
+          {
+            type: "number",
+            min: 0,
+            max: 1,
+            message: "权重应在0到1之间",
+            trigger: "blur",
+          },
+        ],
+      },
+    };
+  },
+  computed: {
+    // 计算权重总和
+    totalWeight() {
+      return this.weights.成本 + this.weights.交付 + this.weights.账期;
+    },
+  },
+  created() {
+    this.fetchWeights();
+  },
+  methods: {
+    // 获取当前权重配置
+    async fetchWeights() {
+      this.loading = true;
+      try {
+        const response = await request({
+          url: "/system/supplier/weights",
+          method: "get",
+        });
+        this.weights = response.data || {
+          成本: 0.4,
+          交付: 0.4,
+          账期: 0.2,
+        };
+        this.$modal.msgSuccess("权重配置加载成功");
+      } catch (err) {
+        console.error("获取权重配置失败:", err);
+        this.message = "获取权重配置失败";
+        this.isError = true;
+        this.$modal.msgError(this.message);
+      } finally {
+        this.loading = false;
+      }
+    },
+
+    // 更新权重配置
+    async updateWeights() {
+      if (Math.abs(this.totalWeight - 1) > 0.001) {
+        this.message = "权重总和必须为1";
+        this.isError = true;
+        this.$modal.msgError(this.message);
+        return;
+      }
+
+      try {
+        const response = await request({
+          url: "/system/supplier/weights",
+          method: "put",
+          data: this.weights,
+        });
+        this.message = response.msg || "权重更新成功";
+        this.isError = false;
+        this.$modal.msgSuccess(this.message);
+      } catch (err) {
+        console.error("更新权重配置失败:", err);
+        this.message = err.message || "更新权重配置失败";
+        this.isError = true;
+        this.$modal.msgError(this.message);
+      }
+    },
+
+    // 重置权重
+    resetWeights() {
+      this.weights = {
+        成本: 0.4,
+        交付: 0.4,
+        账期: 0.2,
+      };
+      this.$modal.msgInfo("权重已重置为默认值");
+    },
+
+    // 权重变更事件
+    onWeightChange() {
+      this.message = "";
+      this.isError = false;
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+}
+
+.page-header {
+  margin-bottom: 20px;
+
+  h2 {
+    font-size: 24px;
+    font-weight: 600;
+    color: #303133;
+    margin-bottom: 8px;
+
+    i {
+      margin-right: 8px;
+      color: #409eff;
+    }
+  }
+
+  .page-desc {
+    color: #909399;
+    font-size: 14px;
+    margin: 0;
+  }
+}
+
+.box-card {
+  margin-bottom: 20px;
+}
+
+.weight-summary {
+  margin: 20px 0;
+  padding: 15px;
+  background: #f8f9fa;
+  border-radius: 4px;
+  border-left: 4px solid #409eff;
+
+  p {
+    margin: 0 0 5px 0;
+    font-size: 14px;
+    color: #606266;
+  }
+}
+
+.warning {
+  color: #e6a23c;
+  font-weight: 600;
+}
+
+.weight-display {
+  .weight-info {
+    margin-bottom: 20px;
+    color: #666;
+    font-size: 14px;
+  }
+}
+
+.info-box {
+  background: #f8f9fa;
+  padding: 20px;
+  border-radius: 4px;
+  border: 1px solid #ebeef5;
+  transition: all 0.3s;
+
+  &:hover {
+    transform: translateY(-2px);
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  }
+
+  .info-label {
+    font-size: 12px;
+    color: #909399;
+    margin-bottom: 10px;
+    font-weight: 600;
+  }
+
+  .info-value {
+    font-size: 24px;
+    font-weight: 700;
+    margin-bottom: 12px;
+    color: #303133;
+  }
+
+  .info-detail {
+    font-size: 13px;
+    color: #909399;
+    line-height: 1.8;
+  }
+}
+
+::v-deep .el-card__header {
+  font-weight: bold;
+}
+</style>