From 193377e7fb0bbbcfe89dda4274abbabeb293ae07 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 11 九月 2026 11:46:38 +0800
Subject: [PATCH] feat(salesLedger): 新增库存不足时自动生成生产主计划功能

---
 src/views/salesManagement/salesLedger/index.vue |  574 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 525 insertions(+), 49 deletions(-)

diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index ccf90b4..0c25737 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -1151,6 +1151,7 @@
                 border
                 size="small"
                 max-height="260"
+                empty-text="鏆傛棤鍙敤搴撳瓨锛屽彲鍦ㄤ笅鏂圭敓鎴愮敓浜т富璁″垝琛ュ厖"
                 style="width: 100%"
               >
                 <el-table-column label="鎵瑰彿" prop="batchNo" min-width="180" />
@@ -1193,6 +1194,63 @@
                   </template>
                 </el-table-column>
               </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-- 搴撳瓨涓嶈冻鏃讹細鑷姩鐢熸垚鐢熶骇涓昏鍒掑苟涓嬪彂 -->
+        <el-row :gutter="30" v-if="isStockInsufficient">
+          <el-col :span="24">
+            <el-form-item>
+              <el-alert
+                type="warning"
+                :closable="false"
+                show-icon
+                style="width: 100%; margin-bottom: 12px"
+              >
+                <template #title>
+                  <template v-if="pendingNeed > 0">
+                    搴撳瓨涓嶈冻锛氬彲鐢ㄥ簱瀛樺悎璁�
+                    <strong>{{ availableStockTotal }}</strong> 锛屽緟鍙戣揣鏁伴噺
+                    <strong>{{ pendingNeed }}</strong> 锛岀己鍙�
+                    <strong>{{ pendingNeed - availableStockTotal }}</strong>
+                    锛屽彲鐢熸垚鐢熶骇涓昏鍒掑苟鑷姩涓嬪彂
+                  </template>
+                  <template v-else>
+                    褰撳墠鏆傛棤鍙敤搴撳瓨锛堝彲鐢�
+                    <strong>{{ availableStockTotal }}</strong>
+                    锛夛紝鍙敓鎴愮敓浜т富璁″垝骞惰嚜鍔ㄤ笅鍙�
+                  </template>
+                </template>
+              </el-alert>
+              <div
+                style="
+                  display: flex;
+                  align-items: center;
+                  gap: 12px;
+                  width: 100%;
+                  padding: 12px 16px;
+                  background: #fdf6ec;
+                  border-radius: 4px;
+                "
+              >
+                <span style="white-space: nowrap; font-size: 14px"
+                  >璁″垝鐢熶骇鏁伴噺锛�</span
+                >
+                <el-input-number
+                  v-model="planQuantity"
+                  :min="0.01"
+                  :precision="2"
+                  :step="1"
+                  controls-position="right"
+                  style="width: 180px"
+                />
+                <el-button
+                  type="warning"
+                  :loading="generatePlanLoading"
+                  @click="handleGenerateAndDispatchPlan"
+                  >鐢熸垚鐢熶骇涓昏鍒掑苟涓嬪彂</el-button
+                >
+              </div>
             </el-form-item>
           </el-col>
         </el-row>
@@ -1258,50 +1316,162 @@
     <!-- 妗嗘灦璁㈠崟鍒楄〃寮圭獥 -->
     <el-dialog
       v-model="frameworkOrderListVisible"
-      title="妗嗘灦璁㈠崟鍒楄〃"
       width="80%"
+      top="6vh"
       :close-on-click-modal="false"
+      class="framework-order-dialog"
     >
-      <el-alert
-        v-if="frameworkContractShippedQty !== null"
-        type="info"
-        :closable="false"
-        style="margin-bottom: 12px"
-        :title="'鐖舵鏋跺悎鍚岀疮璁″凡鍙戣揣鏁伴噺锛�' + frameworkContractShippedQty"
-      />
-      <el-table :data="frameworkOrderList" border :row-key="(row) => row.id">
+      <template #header>
+        <div class="fo-header">
+          <span class="fo-header__title">妗嗘灦璁㈠崟鍒楄〃</span>
+          <span class="fo-header__sub">
+            鐖跺悎鍚岋細{{ currentFrameworkContract?.salesContractNo || "--" }}
+          </span>
+        </div>
+      </template>
+
+      <div class="fo-summary">
+        <div class="fo-summary__item">
+          <div class="fo-summary__label">璁㈠崟鏁�</div>
+          <div class="fo-summary__value">
+            {{ frameworkOrderListLoading ? "--" : frameworkOrderList.length }}
+          </div>
+        </div>
+        <div class="fo-summary__divider" />
+        <div class="fo-summary__item">
+          <div class="fo-summary__label">浜у搧鏁�</div>
+          <div class="fo-summary__value">
+            {{ frameworkOrderListLoading ? "--" : frameworkOrderProductCount }}
+          </div>
+        </div>
+        <div class="fo-summary__divider" />
+        <div class="fo-summary__item">
+          <div class="fo-summary__label">绱宸插彂璐ф暟閲�</div>
+          <div class="fo-summary__value fo-summary__value--accent">
+            {{ frameworkContractShippedQty ?? "--" }}
+          </div>
+        </div>
+      </div>
+
+      <el-table
+        v-loading="frameworkOrderListLoading"
+        :data="frameworkOrderList"
+        :row-key="(row) => row.id"
+        :expand-row-keys="frameworkOrderExpandedKeys"
+        class="fo-table"
+      >
         <el-table-column type="expand">
           <template #default="props">
-            <el-table :data="props.row.products" border size="small">
-              <el-table-column label="浜у搧澶х被" prop="productCategory" />
-              <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
-              <el-table-column label="鍗曚綅" prop="unit" />
-              <el-table-column label="鎿嶄綔" width="80" align="center">
-                <template #default="scope">
-                  <el-button
-                    link
-                    type="primary"
-                    @click="shipFrameworkOrderProduct(scope.row, props.row)"
-                    >鍙戣揣
-                  </el-button>
-                </template>
-              </el-table-column>
-            </el-table>
+            <div class="fo-expand">
+              <div class="fo-expand__title">浜у搧鏄庣粏</div>
+              <el-table :data="props.row.products" border size="small">
+                <el-table-column
+                  label="浜у搧澶х被"
+                  prop="productCategory"
+                  min-width="120"
+                  show-overflow-tooltip
+                />
+                <el-table-column
+                  label="瑙勬牸鍨嬪彿"
+                  prop="specificationModel"
+                  min-width="150"
+                  show-overflow-tooltip
+                />
+                <el-table-column
+                  label="鏁伴噺"
+                  prop="quantity"
+                  width="90"
+                  align="center"
+                >
+                  <template #default="scope">
+                    {{ scope.row.quantity ?? "--" }}
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  label="鍗曚綅"
+                  prop="unit"
+                  width="80"
+                  align="center"
+                />
+                <el-table-column
+                  label="浜よ揣鏃ユ湡"
+                  prop="deliveryDate"
+                  width="130"
+                  align="center"
+                >
+                  <template #default="scope">
+                    {{ scope.row.deliveryDate || "--" }}
+                  </template>
+                </el-table-column>
+                <el-table-column label="鎿嶄綔" width="90" align="center">
+                  <template #default="scope">
+                    <el-button
+                      link
+                      type="primary"
+                      @click="shipFrameworkOrderProduct(scope.row, props.row)"
+                      >鍙戣揣
+                    </el-button>
+                  </template>
+                </el-table-column>
+              </el-table>
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="璁㈠崟缂栧彿" min-width="180">
+          <template #default="scope">
+            <span class="fo-order-no">
+              {{ scope.row.salesContractNo || "--" }}
+            </span>
+          </template>
+        </el-table-column>
+        <el-table-column label="浜у搧" width="90" align="center">
+          <template #default="scope">
+            <el-tag size="small" type="info" effect="light">
+              {{ (scope.row.products || []).length }} 椤�
+            </el-tag>
           </template>
         </el-table-column>
         <el-table-column
-          label="璁㈠崟缂栧彿"
-          prop="salesContractNo"
-          min-width="180"
-        />
-        <el-table-column label="椤圭洰鍚嶇О" prop="projectName" min-width="160" />
-        <el-table-column label="澶囨敞" prop="remarks" min-width="160" />
+          label="椤圭洰鍚嶇О"
+          prop="projectName"
+          min-width="160"
+          show-overflow-tooltip
+        >
+          <template #default="scope">{{ scope.row.projectName || "--" }}</template>
+        </el-table-column>
         <el-table-column
-          label="绱鍙戣揣鏁伴噺"
-          prop="shippedQuantity"
-          width="140"
-          align="center"
-        />
+          label="澶囨敞"
+          prop="remarks"
+          min-width="160"
+          show-overflow-tooltip
+        >
+          <template #default="scope">{{ scope.row.remarks || "--" }}</template>
+        </el-table-column>
+        <el-table-column label="鍙戣揣鐘舵��" width="170" align="center">
+          <template #default="scope">
+            <el-tag
+              v-if="Number(scope.row.shippedQuantity) > 0"
+              type="success"
+              size="small"
+              effect="light"
+              >宸插彂璐�</el-tag
+            >
+            <el-tag v-else type="info" size="small" effect="plain"
+              >鏈彂璐�</el-tag
+            >
+            <span class="fo-qty">
+              绱 {{ scope.row.shippedQuantity ?? 0 }}
+            </span>
+          </template>
+        </el-table-column>
+        <template #empty>
+          <el-empty
+            :description="
+              frameworkOrderListLoading ? '鍔犺浇涓�...' : '鏆傛棤妗嗘灦璁㈠崟'
+            "
+            :image-size="72"
+          />
+        </template>
       </el-table>
     </el-dialog>
   </div>
@@ -1340,6 +1510,11 @@
 import ImageUpload from "@/components/AttachmentUpload/image/index.vue";
 import { getCurrentDate } from "@/utils/index.js";
 import { listCustomer } from "@/api/basicData/customer.js";
+import {
+  productionPlanAdd,
+  productionPlanCombine,
+  productionPlanListPage,
+} from "@/api/productionPlan/productionPlan.js";
 
 const FileList = defineAsyncComponent(() =>
   import("@/components/Dialog/FileList.vue")
@@ -1562,6 +1737,30 @@
   },
 });
 const { deliveryForm, deliveryRules } = toRefs(deliveryFormData);
+
+// 鍙戣揣搴撳瓨涓嶈冻鏃惰嚜鍔ㄧ敓鎴愮敓浜т富璁″垝鐩稿叧
+// 鍙敤搴撳瓨鍚堣锛堟墍鏈夋壒娆″彲鐢ㄦ暟閲忎箣鍜岋級
+const availableStockTotal = computed(() =>
+  (deliveryForm.value?.batchNoList || []).reduce(
+    (sum, item) => sum + Number(getDeliveryBatchQuantity(item) || 0),
+    0
+  )
+);
+// 寰呭彂璐ф暟閲忥紙妗嗘灦鍚堝悓绛夊彲鑳戒负绌猴紝姝ゆ椂瑙嗕负鏃犳槑纭渶姹傞噺锛�
+const pendingNeed = computed(() =>
+  Number(currentDeliveryRow.value?.noQuantity || 0)
+);
+// 鏄惁鏄剧ず鐢熸垚鍏ュ彛锛�
+// 1) 瀹屽叏娌℃湁鍙敤搴撳瓨锛堝簱瀛樿〃鏍间负绌�/鍏ㄤ负0锛夊嵆鍙敓鎴愶紝鍏煎妗嗘灦鍚堝悓鏃犲緟鍙戣揣鏁伴噺鐨勫満鏅紱
+// 2) 鎴栧緟鍙戣揣鏁伴噺 > 0 涓斿彲鐢ㄥ簱瀛樹笉瓒充互瑕嗙洊銆�
+const isStockInsufficient = computed(() => {
+  if (availableStockTotal.value <= 0) return true;
+  return pendingNeed.value > 0 && availableStockTotal.value < pendingNeed.value;
+});
+// 璁″垝鐢熶骇鏁伴噺
+const planQuantity = ref(0);
+// 鐢熸垚骞朵笅鍙戞寜閽� loading
+const generatePlanLoading = ref(false);
 
 // 瀵煎叆鐩稿叧
 const importUploadRef = ref(null);
@@ -2994,6 +3193,15 @@
     batchNoList,
   };
   deliveryFileList.value = [];
+  // 璁$畻缂哄彛锛屼綔涓鸿鍒掔敓浜ф暟閲忛粯璁ゅ��
+  const totalStock = batchNoList.reduce(
+    (sum, item) => sum + Number(getDeliveryBatchQuantity(item) || 0),
+    0
+  );
+  planQuantity.value = Math.max(
+    0,
+    Number(row.noQuantity || 0) - totalStock
+  );
   deliveryFormVisible.value = true;
 };
 
@@ -3088,6 +3296,160 @@
   currentDeliveryRow.value = null;
 };
 
+// 涓荤敓浜ц鍒掑墿浣欏彲涓嬪彂鏁伴噺
+const remainingOfPlan = (plan) =>
+  Math.max(0, Number(plan?.qtyRequired || 0) - Number(plan?.quantityIssued || 0));
+
+// 鏌ヨ璇ヤ骇鍝�(瑙勬牸鍨嬪彿)涓嬨�屽皻鏈笅鍙戙�嶇殑涓荤敓浜ц鍒掑垪琛�
+// 宸蹭笅鍙戣繃锛堝摢鎬曟槸閮ㄥ垎涓嬪彂锛夌殑璁″垝涓嶅鐢紝涓嬫闇�鏂板缓
+const fetchPendingPlans = async ({ productModelId, productName, model }) => {
+  const params = { current: 1, size: 200 };
+  if (productName) params.productName = productName;
+  if (model) params.model = model;
+  const res = await productionPlanListPage(params);
+  const records = res?.data?.records || res?.data?.rows || [];
+  return records.filter((r) => {
+    const sameModel = productModelId
+      ? String(r.productModelId) === String(productModelId)
+      : !!model && r.model === model;
+    const notDispatched = Number(r.quantityIssued || 0) <= 0;
+    return sameModel && notDispatched && remainingOfPlan(r) > 0;
+  });
+};
+
+// 鍙栨渶鏂颁竴鏉★紙id 鏈�澶э級
+const pickNewestPlan = (plans) =>
+  plans.reduce((a, b) => (Number(b.id) > Number(a.id) ? b : a));
+
+// 搴撳瓨涓嶈冻/鏃犲簱瀛樻椂锛氳嚜鍔ㄧ敓鎴愮敓浜т富璁″垝骞跺叏閲忎笅鍙�
+const handleGenerateAndDispatchPlan = async () => {
+  const qty = Number(planQuantity.value || 0);
+  if (qty <= 0) {
+    proxy.$modal.msgWarning("璁″垝鐢熶骇鏁伴噺蹇呴』澶т簬0");
+    return;
+  }
+  try {
+    await proxy.$modal.confirm(
+      `褰撳墠搴撳瓨涓嶈冻锛岀‘璁ょ敓鎴�/涓嬪彂鐢熶骇涓昏鍒掞紙璁″垝鏁伴噺 ${qty}锛夊苟鍏ㄩ噺涓嬪彂锛焋
+    );
+  } catch {
+    return;
+  }
+
+  generatePlanLoading.value = true;
+  try {
+    const row = currentDeliveryRow.value || {};
+    const firstBatch = (deliveryForm.value?.batchNoList || [])[0] || {};
+    const productName = row.productCategory || firstBatch.productName || "";
+    const model = row.specificationModel || firstBatch.model || "";
+    const productModelId = row.productModelId || row.modelId || undefined;
+    const requiredDate =
+      row.deliveryDate || dayjs().add(7, "day").format("YYYY-MM-DD");
+    const createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
+    // 璁㈠崟缂栧彿锛堥攢鍞悎鍚屽彿锛夛細妗嗘灦璁㈠崟琛岀洿鎺ュ甫锛屾櫘閫氬彴璐﹁浠庣埗璁板綍鍙�
+    const salesContractNo =
+      row.salesContractNo ||
+      findLedgerRecordByRow(row)?.salesContractNo ||
+      "";
+
+    // productId锛氳/鎵规浼樺厛锛岀己澶辨椂鐢ㄤ骇鍝佸ぇ绫诲悕绉板湪浜у搧鏍戝弽鏌ワ紙涓庣紪杈戜骇鍝佷竴鑷达級
+    let productId = row.productId || firstBatch.productId;
+    if (!productId && productName) {
+      const options =
+        productOptions.value && productOptions.value.length > 0
+          ? productOptions.value
+          : await getProductOptions();
+      productId = findNodeIdByLabel(options, productName) || undefined;
+    }
+    if (!productId || !productModelId) {
+      proxy.$modal.msgError(
+        "鏈瘑鍒埌璇ヤ骇鍝佺殑浜у搧ID/瑙勬牸鍨嬪彿ID锛屾棤娉曠敓鎴愮敓浜т富璁″垝锛岃鑱旂郴绠$悊鍛�"
+      );
+      return;
+    }
+
+    // 鈶� 鍏堟煡璇ヤ骇鍝佹槸鍚﹀瓨鍦ㄣ�屽皻鏈笅鍙戙�嶇殑涓荤敓浜ц鍒掑彲澶嶇敤锛涘凡涓嬪彂杩囩殑涓嶅鐢紝鐩存帴鏂板缓
+    let target = null;
+    let dispatchQty = qty;
+    const existingPlans = await fetchPendingPlans({
+      productModelId,
+      productName,
+      model,
+    });
+    if (existingPlans.length > 0) {
+      target = pickNewestPlan(existingPlans);
+      dispatchQty = remainingOfPlan(target);
+    } else {
+      // 鈶� 鏃犲凡鏈夎鍒掑垯鏂板缓锛屽啀閫氳繃鏌ヨ鍒楄〃鍙栧洖鏂拌鍒� id锛坅dd 鍝嶅簲涓嶄竴瀹氬甫 id锛�
+      await productionPlanAdd({
+        id: null,
+        mpsNo: "",
+        // 鍚堝悓鍙烽�氳繃鍙拌处鍏宠仈锛歱roduction_plan.sales_ledger_id 鈫� sales_ledger.sales_contract_no
+        salesLedgerId: row.salesLedgerId ?? null,
+        salesLedgerProductId: row.id ?? null,
+        productId,
+        productModelId,
+        productName,
+        model,
+        qtyRequired: qty,
+        unit: row.unit || firstBatch.unit || "鏂�",
+        requiredDate,
+        promisedDeliveryDate: "",
+        remark: "閿�鍞彂璐ц嚜鍔ㄧ敓鎴�",
+        salesContractNo,
+        createTime,
+      });
+      const createdPlans = await fetchPendingPlans({
+        productModelId,
+        productName,
+        model,
+      });
+      if (createdPlans.length > 0) {
+        target = pickNewestPlan(createdPlans);
+        dispatchQty = remainingOfPlan(target) || qty;
+      }
+    }
+
+    if (!target || !target.id) {
+      proxy.$modal.msgError(
+        "鐢熶骇涓昏鍒掑凡鍒涘缓锛屼絾鏈兘鏌ヨ鍒拌鍒扞D锛岃鍓嶅線銆愮敓浜ц鍒掋�戦〉闈㈡墜鍔ㄤ笅鍙�"
+      );
+      return;
+    }
+
+    // 鈶� 鍏ㄩ噺涓嬪彂
+    const combineRes = await productionPlanCombine({
+      productName,
+      model,
+      totalAssignedQuantity: dispatchQty,
+      planCompleteTime: target.requiredDate || requiredDate,
+      productId: target.productId || productId || "",
+      salesContractNo: target.salesContractNo || salesContractNo || "",
+      createTime,
+      ids: [target.id],
+    });
+
+    if (combineRes?.code === 200) {
+      proxy.$modal.msgSuccess("鐢熶骇涓昏鍒掑凡涓嬪彂鎴愬姛");
+      closeDeliveryDia();
+      getList();
+    } else {
+      proxy.$modal.msgError(
+        `鐢熶骇涓昏鍒掍笅鍙戝け璐ワ細${
+          combineRes?.msg || "鏈煡閿欒"
+        }锛岃鍓嶅線銆愮敓浜ц鍒掋�戦〉闈㈡墜鍔ㄤ笅鍙慲
+      );
+    }
+  } catch (err) {
+    console.error("鑷姩鐢熸垚/涓嬪彂鐢熶骇涓昏鍒掑け璐ワ細", err);
+    if (!err?.response) {
+      proxy.$modal.msgError("鑷姩鐢熸垚/涓嬪彂鐢熶骇涓昏鍒掑け璐ワ紝璇风◢鍚庨噸璇曟垨鎵嬪姩鎿嶄綔");
+    }
+  } finally {
+    generatePlanLoading.value = false;
+  }
+};
+
 // 妗嗘灦鍚堝悓 / 妗嗘灦璁㈠崟鐩稿叧
 const frameworkOrderDialogVisible = ref(false);
 const frameworkOrderListVisible = ref(false);
@@ -3098,6 +3460,15 @@
 const frameworkOrderProducts = ref([]);
 const frameworkOrderList = ref([]);
 const frameworkContractShippedQty = ref(null);
+const frameworkOrderListLoading = ref(false);
+// 榛樿灞曞紑绗竴涓鍗�
+const frameworkOrderExpandedKeys = ref([]);
+const frameworkOrderProductCount = computed(() =>
+  frameworkOrderList.value.reduce(
+    (sum, order) => sum + (order.products?.length || 0),
+    0
+  )
+);
 
 const openFrameworkOrderDialog = async (row) => {
   currentFrameworkContract.value = row;
@@ -3144,22 +3515,34 @@
   currentFrameworkContract.value = row;
   frameworkContractShippedQty.value = null;
   frameworkOrderList.value = [];
+  frameworkOrderExpandedKeys.value = [];
+  frameworkOrderListLoading.value = true;
   frameworkOrderListVisible.value = true;
-  listFrameworkOrders({ parentContractId: row.id }).then(async (res) => {
-    const orders = res.data || [];
-    const withProducts = [];
-    for (const order of orders) {
-      let products = [];
-      try {
-        const productRes = await productList({ salesLedgerId: order.id, type: 1 });
-        products = productRes.data || [];
-      } catch (e) {
-        products = [];
+  listFrameworkOrders({ parentContractId: row.id })
+    .then(async (res) => {
+      const orders = res.data || [];
+      const withProducts = [];
+      for (const order of orders) {
+        let products = [];
+        try {
+          const productRes = await productList({
+            salesLedgerId: order.id,
+            type: 1,
+          });
+          products = productRes.data || [];
+        } catch (e) {
+          products = [];
+        }
+        withProducts.push({ ...order, products });
       }
-      withProducts.push({ ...order, products });
-    }
-    frameworkOrderList.value = withProducts;
-  });
+      frameworkOrderList.value = withProducts;
+      if (withProducts.length > 0) {
+        frameworkOrderExpandedKeys.value = [withProducts[0].id];
+      }
+    })
+    .finally(() => {
+      frameworkOrderListLoading.value = false;
+    });
   frameworkContractShippedQuantity({ parentContractId: row.id }).then((res) => {
     frameworkContractShippedQty.value = res.data ?? 0;
   });
@@ -3171,6 +3554,7 @@
   openDeliveryForm({
     ...productRow,
     salesLedgerId: orderRow.id,
+    salesContractNo: orderRow.salesContractNo,
   });
 };
 const currentFactoryName = ref("");
@@ -3369,6 +3753,98 @@
   }
 }
 
+/* 妗嗘灦璁㈠崟鍒楄〃寮圭獥 */
+.framework-order-dialog {
+  .fo-header {
+    display: flex;
+    align-items: baseline;
+    gap: 12px;
+
+    &__title {
+      font-size: 16px;
+      font-weight: 600;
+      color: #303133;
+    }
+
+    &__sub {
+      font-size: 13px;
+      color: #909399;
+    }
+  }
+
+  .fo-summary {
+    display: flex;
+    align-items: center;
+    padding: 14px 24px;
+    margin-bottom: 16px;
+    background: linear-gradient(90deg, #eef4ff 0%, #f7fafd 100%);
+    border: 1px solid #e2ecfb;
+    border-radius: 8px;
+
+    &__item {
+      flex: 1;
+    }
+
+    &__label {
+      margin-bottom: 6px;
+      font-size: 12px;
+      color: #909399;
+    }
+
+    &__value {
+      font-size: 18px;
+      font-weight: 600;
+      color: #303133;
+
+      &--accent {
+        color: var(--el-color-primary);
+      }
+    }
+
+    &__divider {
+      width: 1px;
+      height: 30px;
+      margin: 0 24px;
+      background: #dce7f7;
+    }
+  }
+
+  .fo-order-no {
+    font-weight: 500;
+    color: var(--el-color-primary);
+  }
+
+  .fo-qty {
+    margin-left: 8px;
+    font-size: 12px;
+    color: #606266;
+  }
+
+  .fo-expand {
+    padding: 12px 16px 16px 48px;
+    background: #fafbfd;
+
+    &__title {
+      margin-bottom: 8px;
+      font-size: 13px;
+      font-weight: 600;
+      color: #606266;
+    }
+  }
+
+  :deep(.fo-table) {
+    th.el-table__cell {
+      background-color: #f5f7fa;
+      color: #606266;
+      font-weight: 600;
+    }
+
+    .el-table__expanded-cell {
+      padding: 0 !important;
+    }
+  }
+}
+
 @media print {
   .app-container {
     display: none;

--
Gitblit v1.9.3