From bbaf8175e73c8579ef14a6b4a678bcb98177834b Mon Sep 17 00:00:00 2001
From: 张诺 <zhang_12370@163.com>
Date: 星期一, 27 四月 2026 14:00:05 +0800
Subject: [PATCH] feat(生产报工): 合并开始与结束报工为单一报工流程

---
 src/pages/productionManagement/productionReport/index.vue |  495 ++++++++++++++++++++++++++++++++++++++++++++++++------
 1 files changed, 436 insertions(+), 59 deletions(-)

diff --git a/src/pages/productionManagement/productionReport/index.vue b/src/pages/productionManagement/productionReport/index.vue
index e8b3967..0bbce64 100644
--- a/src/pages/productionManagement/productionReport/index.vue
+++ b/src/pages/productionManagement/productionReport/index.vue
@@ -30,7 +30,7 @@
       lower-threshold="80"
       @scrolltolower="loadMore"
     >
-      <view v-for="(item, index) in tableData" :key="item.id || index" class="ledger-item">
+      <view v-for="(item, index) in tableData" :key="item.id || index" class="ledger-item" @click="showTransferCard(item)">
         <view class="item-header">
           <view class="item-left">
             <view class="document-icon">
@@ -55,10 +55,6 @@
             <text class="detail-value">{{ item.model || '鏃�' }}</text>
           </view>
           <view class="detail-row">
-            <text class="detail-label">鏈哄彴鍚嶇О</text>
-            <text class="detail-value">{{ item.deviceName || '鏃�' }}</text>
-          </view>
-          <view class="detail-row">
             <text class="detail-label">宸ュ簭鍚嶇О / 璁¢噺鍗曚綅</text>
             <text class="detail-value">{{ item.processName || '鏃�' }} / {{ item.unit || '鏃�' }}</text>
           </view>
@@ -77,30 +73,15 @@
               ></up-line-progress>
             </view>
           </view>
-          <view class="detail-row">
-            <text class="detail-label">瀹為檯寮�濮�</text>
-            <text class="detail-value">{{ item.startProductTime || '-' }}</text>
-          </view>
-          <view class="detail-row">
-            <text class="detail-label">瀹為檯缁撴潫</text>
-            <text class="detail-value">{{ item.endProductTime || '-' }}</text>
-          </view>
         </view>
 
-        <view class="item-actions" v-if="!item.endProductTime">
+        <view class="item-actions" v-if="!isEnded(item)">
           <up-button
-            text="寮�濮嬫姤宸�"
-            size="mini"
-            type="primary"
-            :disabled="!canStartProduction(item) || startSubmittingId === item.id"
-            @click="handleStartProduction(item)"
-          />
-          <up-button
-            text="缁撴潫鎶ュ伐"
+            text="鎶ュ伐"
             size="mini"
             type="success"
             :disabled="!canEndProduction(item)"
-            @click="openEndReport(item)"
+            @click.stop="openEndReport(item)"
           />
         </view>
       </view>
@@ -114,20 +95,69 @@
     <!-- 娴佽浆鍗″脊绐� -->
     <up-popup :show="transferCardVisible" mode="center" @close="transferCardVisible = false" round="10">
       <view class="qr-popup">
-        <text class="qr-title">宸ュ崟娴佽浆鍗′簩缁寸爜</text>
-        <view class="qr-box">
-          <geek-qrcode
-            v-if="transferCardRowData"
-            :val="String(transferCardRowData.id)"
-            :size="200"
-          />
+        <text class="qr-info" v-if="transferCardRowData">{{ transferCardRowData.workOrderNo || '-' }}</text>
+        <view class="transfer-records">
+          <view class="transfer-records-header">
+            <text class="transfer-records-title">鎶ュ伐瀹℃牳璁板綍</text>
+            <text class="transfer-records-count">鍏� {{ transferCardRecords.length }} 鏉�</text>
+          </view>
+          <view v-if="transferCardLoading" class="transfer-records-loading">鍔犺浇涓�...</view>
+          <view v-else-if="transferCardRecords.length > 0" class="transfer-records-list">
+            <view
+              v-for="(record, index) in transferCardRecords"
+              :key="record.id || index"
+              class="transfer-record-item"
+            >
+              <view class="transfer-record-top">
+                <view class="transfer-record-top-main">
+                  <text class="transfer-record-no">{{ record.productNo || `鎶ュ伐璁板綍${index + 1}` }}</text>
+                  <text class="transfer-record-sub">
+                    {{ record.process || '-' }} / {{ record.deviceName || '-' }}
+                  </text>
+                </view>
+                <text class="audit-status-tag" :class="`audit-status-${getAuditStatusType(record.auditStatus)}`">
+                  {{ getAuditStatusLabel(record.auditStatus) }}
+                </text>
+              </view>
+              <view class="transfer-record-grid">
+                <view
+                  v-for="field in transferRecordFields"
+                  :key="field.prop"
+                  class="transfer-record-cell"
+                  :class="{ 'is-wide': field.wide }"
+                >
+                  <text class="transfer-record-label">{{ field.label }}</text>
+                  <view v-if="field.prop === 'teamNames'" class="transfer-record-content">
+                    <view v-if="getTeamNameList(record.teamNames).length > 0" class="transfer-tag-list">
+                      <text
+                        v-for="name in getTeamNameList(record.teamNames)"
+                        :key="name"
+                        class="transfer-name-tag"
+                      >
+                        {{ name }}
+                      </text>
+                    </view>
+                    <text v-else class="transfer-record-value">-</text>
+                  </view>
+                  <view v-else-if="field.prop === 'auditStatus'" class="transfer-record-content">
+                    <text class="audit-status-tag" :class="`audit-status-${getAuditStatusType(record.auditStatus)}`">
+                      {{ getAuditStatusLabel(record.auditStatus) }}
+                    </text>
+                  </view>
+                  <text v-else class="transfer-record-value">
+                    {{ formatTransferRecordValue(record, field.prop) }}
+                  </text>
+                </view>
+              </view>
+            </view>
+          </view>
+          <view v-else class="transfer-records-empty">鏆傛棤鎶ュ伐瀹℃牳璁板綍</view>
         </view>
-        <text class="qr-info" v-if="transferCardRowData">{{ transferCardRowData.workOrderNo }}</text>
         <up-button text="鍏抽棴" @click="transferCardVisible = false" style="margin-top: 20px;"></up-button>
       </view>
     </up-popup>
 
-    <!-- 缁撴潫鎶ュ伐寮圭獥 -->
+    <!-- 鎶ュ伐寮圭獥 -->
     <up-popup
       v-model:show="endReportVisible"
       mode="bottom"
@@ -138,7 +168,7 @@
       <view class="report-modal">
         <view class="modal-header">
           <view class="modal-header-left">
-            <text class="modal-title">缁撴潫鎶ュ伐</text>
+            <text class="modal-title">鎶ュ伐</text>
             <text class="modal-subtitle" v-if="endReportRow">
               {{ endReportRow.workOrderNo || '-' }} 路 {{ endReportRow.deviceName || '-' }}
             </text>
@@ -149,7 +179,7 @@
         </view>
 
         <scroll-view class="modal-content" scroll-y>
-          <view class="report-summary" v-if="endReportRow">
+          <!-- <view class="report-summary" v-if="endReportRow">
             <view class="summary-left">
               <text class="summary-title">{{ endReportRow.productName || '-' }}</text>
               <text class="summary-sub">{{ endReportRow.processName || '-' }} 路 {{ endReportRow.model || '-' }}</text>
@@ -158,7 +188,7 @@
               <text class="summary-num">{{ endReportForm.planQuantity || '0' }}</text>
               <text class="summary-label">寰呯敓浜�</text>
             </view>
-          </view>
+          </view> -->
 
           <up-form :model="endReportForm" labelWidth="120">
             <view class="form-section">
@@ -167,7 +197,7 @@
                 <up-input v-model="endReportForm.planQuantity" disabled />
               </up-form-item>
               <up-form-item label="鏈鐢熶骇鏁伴噺" required>
-                <up-input v-model="endReportForm.quantity" disabled />
+                <up-input v-model="endReportForm.quantity" />
               </up-form-item>
               <up-form-item label="琛ヤ骇鏁伴噺">
                 <up-input v-model="endReportForm.replenishQty" type="number" placeholder="璇疯緭鍏�" />
@@ -175,9 +205,35 @@
               <up-form-item label="鎶ュ簾鏁伴噺">
                 <up-input v-model="endReportForm.scrapQty" type="number" placeholder="璇疯緭鍏�" />
               </up-form-item>
+              <up-form-item label="寮�濮嬫椂闂�" required>
+  <up-input
+    v-model="endReportForm.startTime"
+    readonly
+    placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
+    @click="startTimePickerVisible = true"
+  />
+</up-form-item>
+
+<up-form-item label="缁撴潫鏃堕棿" required>
+  <up-input
+    v-model="endReportForm.endTime"
+    readonly
+    placeholder="璇烽�夋嫨缁撴潫鏃堕棿"
+    @click="endTimePickerVisible = true"
+  />
+</up-form-item>
             </view>
 
             <view class="form-section">
+              <up-form-item label="鏈哄彴" required>
+                <up-input
+                  v-model="endReportForm.deviceName"
+                  readonly
+                  placeholder="璇烽�夋嫨"
+                  @click="openDevicePicker"
+                  suffixIcon="arrow-down"
+                />
+              </up-form-item>
               <up-form-item label="鐝粍浜哄憳">
                 <up-input
                   v-model="teamDisplayText"
@@ -249,6 +305,13 @@
       @select="onAuditSelect"
       @close="auditPickerVisible = false"
     />
+    <up-action-sheet
+      :show="devicePickerVisible"
+      :actions="deviceActions"
+      title="閫夋嫨鏈哄彴"
+      @select="onDeviceSelect"
+      @close="devicePickerVisible = false"
+    />
 
     <!-- 鏃堕棿閫夋嫨鍣� -->
     <up-datetime-picker
@@ -274,7 +337,8 @@
 <script setup>
 import { ref, reactive, toRefs, computed, getCurrentInstance } from "vue";
 import { onShow, onLoad, onReachBottom } from "@dcloudio/uni-app";
-import { productWorkOrderPage, addProductMain, startProduction, getProductWorkOrderById } from "@/api/productionManagement/productionReporting.js";
+import { productWorkOrderPage, addProductMain, startProduction, getProductWorkOrderById,getProductionProductMain } from "@/api/productionManagement/productionReporting.js";
+import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
 import { userListNoPageByTenantId } from "@/api/system/user.js";
 import PageHeader from "@/components/PageHeader.vue";
 import FilesDia from "./components/filesDia.vue";
@@ -287,6 +351,28 @@
 const loadStatus = ref('loadmore');
 const transferCardVisible = ref(false);
 const transferCardRowData = ref(null);
+const transferCardLoading = ref(false);
+const transferCardRecords = ref([]);
+const auditStatusOptions = ref([
+  { label: "鏈鏍�", value: 0 },
+  { label: "閫氳繃", value: 1 },
+  { label: "涓嶉�氳繃", value: 2 },
+]);
+const transferRecordFields = [
+  { label: "鎶ュ伐浜哄憳", prop: "teamNames", wide: true },
+  { label: "瀹℃牳浜�", prop: "auditUserName" },
+  { label: "鏈�缁堝鏍镐汉", prop: "sureAuditUserName" },
+  { label: "宸ュ崟缂栧彿", prop: "workOrderNo" },
+  { label: "璁㈠崟缂栧彿", prop: "salesContractNo" },
+  { label: "浜у搧鍚嶇О", prop: "productName" },
+  { label: "浜у搧瑙勬牸鍨嬪彿", prop: "productModelName" },
+  { label: "浜у嚭鏁伴噺", prop: "quantity" },
+  { label: "鎶ュ簾鏁伴噺", prop: "scrapQty" },
+  { label: "鍗曚綅", prop: "unit" },
+  { label: "瀹℃牳鐘舵��", prop: "auditStatus" },
+  { label: "澶囨敞淇℃伅", prop: "auditOpinion", wide: true },
+  { label: "鍒涘缓鏃堕棿", prop: "createTime", wide: true },
+];
 const workOrderFilesRef = ref(null);
 const startSubmittingId = ref(null);
 
@@ -297,6 +383,8 @@
   quantity: "",
   replenishQty: "0",
   scrapQty: "0",
+  deviceLedgerId: "",
+  deviceName: "",
   teamList: [],
   startTime: "",
   endTime: "",
@@ -313,6 +401,10 @@
 const userOptions = ref([]);
 const auditPickerVisible = ref(false);
 const auditActions = computed(() => userOptions.value.map(u => ({ name: u.name, value: u.value })));
+
+const deviceOptions = ref([]);
+const devicePickerVisible = ref(false);
+const deviceActions = computed(() => deviceOptions.value.map(d => ({ name: d?.deviceName || "", value: d?.id })));
 
 const teamPickerVisible = ref(false);
 const teamCheckedIds = ref([]);
@@ -339,7 +431,7 @@
 
 const data = reactive({
   searchForm: {
-    workOrderNo: "",
+    workOrderId: "",
   },
 });
 const { searchForm } = toRefs(data);
@@ -385,8 +477,17 @@
   }
 };
 
+const ensureDeviceOptions = async () => {
+  if (deviceOptions.value.length > 0) return;
+  try {
+    const res = await getDeviceLedger();
+    deviceOptions.value = res?.data || [];
+  } catch {
+    deviceOptions.value = [];
+  }
+};
+
 const getList = () => {
-  console.log(searchForm.value);
   if (loading.value) return;
   loading.value = true;
   
@@ -450,36 +551,93 @@
   return Math.round(n);
 };
 
-const showTransferCard = (row) => {
-  transferCardRowData.value = row;
-  transferCardVisible.value = true;
+const getAuditStatusLabel = (val) => {
+  const target = auditStatusOptions.value.find(item => Number(item.value) === Number(val));
+  return target?.label || "鏈煡";
 };
 
-const openWorkOrderFiles = (row) => {
-  workOrderFilesRef.value?.openDialog(row);
+const getAuditStatusType = (val) => {
+  const typeMap = { 0: "info", 1: "success", 2: "danger" };
+  return typeMap[Number(val)] || "default";
+};
+
+const getTeamNameList = (val) => {
+  if (!val) return [];
+  return String(val)
+    .split(",")
+    .map(item => item.trim())
+    .filter(Boolean);
+};
+
+const formatTransferRecordValue = (record, prop) => {
+  if (prop === "auditStatus") {
+    return getAuditStatusLabel(record?.[prop]);
+  }
+
+  const value = record?.[prop];
+  if (value === null || value === undefined || value === "") {
+    return "-";
+  }
+
+  return String(value);
+};
+
+const getTransferCardParams = (row) => {
+  const params = {
+    current: 1,
+    size: 100,
+  };
+
+  if (row?.id != null) {
+    params.workOrderId = row.id;
+  }
+  if (row?.workOrderNo) {
+    params.workOrderNo = row.workOrderNo;
+  }
+  if (row?.productMainId != null) {
+    params.productMainId = row.productMainId;
+  }
+
+  return params;
+};
+
+const showTransferCard = async (row) => {
+  transferCardRowData.value = row;
+  transferCardVisible.value = true;
+  transferCardRecords.value = [];
+  transferCardLoading.value = true;
+
+  try {
+    const res = await getProductionProductMain(getTransferCardParams(row));
+    transferCardRecords.value = res?.data?.records || res?.records || [];
+  } catch {
+    transferCardRecords.value = [];
+    showToast("鍔犺浇鎶ュ伐瀹℃牳璁板綍澶辫触");
+  } finally {
+    transferCardLoading.value = false;
+  }
 };
 
 const getPendingQty = (row) => {
   const plan = Number(row?.planQuantity) || 0;
   const complete = Number(row?.completeQuantity) || 0;
-  return plan - complete;
+  return Math.max(plan - complete, 0);
 };
 
 const isStarted = (row) => {
-  if (row?.startProductTime && !row?.endProductTime) return true;
-  if (String(row?.reportWork) === "1" && !row?.endProductTime) return true;
-  return false;
+  if (!row?.id) return false;
+  if (Number(row?.completeQuantity) > 0) return true;
+  if (row?.startProductTime) return true;
+  return String(row?.reportWork) === "1";
 };
 
 const isEnded = (row) => {
-  return Boolean(row?.endProductTime);
+  return getPendingQty(row) <= 0;
 };
 
 const canEndProduction = (row) => {
   if (!row?.id) return false;
-  if (getPendingQty(row) <= 0) return false;
   if (isEnded(row)) return false;
-  if (!isStarted(row)) return false;
   return true;
 };
 
@@ -489,14 +647,16 @@
   if (getPendingQty(row) <= 0) return false;
   if (isEnded(row)) return false;
   if (isStarted(row)) return false;
-  if (!canStartProductionByUserIds(userStore.id, row)) return false;
-  return true;
+  return canStartProductionByUserIds(userStore.id, row);
+
 };
 
 // 鏍规嵁userIds鍒ゆ柇鏄惁鏈夌敤鎴峰彲浠ユ姤宸�
 const canStartProductionByUserIds = (userId, row) => {
   const team = row?.userIds || "";
-  return team.includes(userId);
+  if (!userId) return true;
+  if (!team) return true;
+  return String(team).includes(String(userId));
 };
 
 const handleStartProduction = (row) => {
@@ -547,11 +707,14 @@
   endReportRow.value = row;
   await ensureUserInfo();
   await ensureUserOptions();
+  await ensureDeviceOptions();
 
   endReportForm.planQuantity = String(getPendingQty(row));
   endReportForm.quantity = String(getPendingQty(row));
   endReportForm.replenishQty = "0";
   endReportForm.scrapQty = "0";
+  endReportForm.deviceLedgerId = "";
+  endReportForm.deviceName = "";
   endReportForm.teamList = [];
   teamCheckedIds.value = [];
 
@@ -574,6 +737,14 @@
   endTimeValue.value = Date.now();
   endReportForm.endTime = formatDateTime(endTimeValue.value);
 
+  if (row?.deviceName) {
+    const matched = deviceOptions.value.find(d => String(d?.deviceName || "") === String(row.deviceName));
+    if (matched) {
+      endReportForm.deviceLedgerId = String(matched.id ?? "");
+      endReportForm.deviceName = String(matched.deviceName ?? "");
+    }
+  }
+
   endReportVisible.value = true;
 };
 
@@ -591,6 +762,17 @@
   endReportForm.auditUserId = String(e?.value ?? "");
   endReportForm.auditUserName = String(e?.name ?? "");
   auditPickerVisible.value = false;
+};
+
+const openDevicePicker = async () => {
+  await ensureDeviceOptions();
+  devicePickerVisible.value = true;
+};
+
+const onDeviceSelect = (e) => {
+  endReportForm.deviceLedgerId = String(e?.value ?? "");
+  endReportForm.deviceName = String(e?.name ?? "");
+  devicePickerVisible.value = false;
 };
 
 const openTeamPicker = async () => {
@@ -611,12 +793,25 @@
 };
 
 const onStartTimeConfirm = (e) => {
-  endReportForm.startTime = formatDateTime(e.value);
+  const start = e.value;
+  endReportForm.startTime = formatDateTime(start);
   startTimePickerVisible.value = false;
+
+  // 馃憠 鑷姩缁欑粨鏉熸椂闂� +1灏忔椂
+  const end = start + 60 * 60 * 1000;
+  endTimeValue.value = end;
+  endReportForm.endTime = formatDateTime(end);
 };
 
 const onEndTimeConfirm = (e) => {
-  endReportForm.endTime = formatDateTime(e.value);
+  const end = e.value;
+
+  if (end <= startTimeValue.value) {
+    showToast("缁撴潫鏃堕棿蹇呴』澶т簬寮�濮嬫椂闂�");
+    return;
+  }
+
+  endReportForm.endTime = formatDateTime(end);
   endTimePickerVisible.value = false;
 };
 
@@ -650,9 +845,31 @@
     showToast("鎶ュ簾鏁伴噺蹇呴』涓哄ぇ浜庣瓑浜�0鐨勬暣鏁�");
     return;
   }
+  if (!endReportForm.startTime) {
+  showToast("璇烽�夋嫨寮�濮嬫椂闂�");
+  return;
+}
+
+if (!endReportForm.endTime) {
+  showToast("璇烽�夋嫨缁撴潫鏃堕棿");
+  return;
+}
+
+const start = new Date(endReportForm.startTime).getTime();
+const end = new Date(endReportForm.endTime).getTime();
+
+if (end <= start) {
+  showToast("缁撴潫鏃堕棿蹇呴』澶т簬寮�濮嬫椂闂�");
+  return;
+}
 
   if (!endReportForm.auditUserId) {
     showToast("璇烽�夋嫨瀹℃牳浜�");
+    return;
+  }
+
+  if (!endReportForm.deviceLedgerId) {
+    showToast("璇烽�夋嫨鏈哄彴");
     return;
   }
 
@@ -669,17 +886,19 @@
       userName: endReportForm.userName || userStore.nickName,
       auditUserId: endReportForm.auditUserId,
       auditUserName: endReportForm.auditUserName,
+      deviceLedgerId: endReportForm.deviceLedgerId,
+      deviceName: endReportForm.deviceName,
     };
     const res = await addProductMain(submitData);
     if (res?.code === 200) {
-      showToast("缁撴潫鎶ュ伐鎴愬姛");
+      showToast("鎶ュ伐鎴愬姛");
       closeEndReport();
       handleQuery();
     } else {
-      showToast(res?.msg || "缁撴潫鎶ュ伐澶辫触");
+      showToast(res?.msg || "鎶ュ伐澶辫触");
     }
   } catch {
-    showToast("缁撴潫鎶ュ伐澶辫触");
+    showToast("鎶ュ伐澶辫触");
   } finally {
     uni.hideLoading();
   }
@@ -747,6 +966,164 @@
   }
 }
 
+.qr-popup {
+  width: 90vw;
+  max-width: 900rpx;
+  max-height: 85vh;   // 鍘熸潵 80 鈫� 鍔犲ぇ
+  padding: 32rpx 28rpx;
+  background: #fff;
+  border-radius: 20rpx;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  box-sizing: border-box;
+}
+.qr-title {
+  font-size: 30rpx;
+  font-weight: 600;
+  color: #222;
+}
+.qr-box {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  margin-top: 24rpx;
+}
+.qr-info {
+  margin-top: 16rpx;
+  font-size: 26rpx;
+  color: #666;
+}
+.transfer-records {
+  width: 100%;
+  margin-top: 28rpx;
+}
+.transfer-records-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  gap: 16rpx;
+  margin-bottom: 16rpx;
+}
+.transfer-records-title {
+  font-size: 26rpx;
+  font-weight: 600;
+  color: #222;
+}
+.transfer-records-count {
+  font-size: 22rpx;
+  color: #8a8a8a;
+}
+.transfer-records-loading,
+.transfer-records-empty {
+  padding: 28rpx 0;
+  font-size: 24rpx;
+  color: #8a8a8a;
+  text-align: center;
+}
+.transfer-records-list {
+  max-height: 500rpx;
+  overflow: auto;
+}
+.transfer-record-item {
+  padding: 20rpx 22rpx;
+  border-radius: 16rpx;
+  background: #f7f8fa;
+}
+
+.transfer-record-item + .transfer-record-item {
+  margin-top: 16rpx;
+}
+.transfer-record-top {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  gap: 24rpx;
+}
+.transfer-record-top-main {
+  display: flex;
+  flex-direction: column;
+  gap: 8rpx;
+  min-width: 0;
+}
+.transfer-record-no {
+  font-size: 28rpx;
+  font-weight: 600;
+  color: #222;
+  word-break: break-all;
+}
+.transfer-record-sub {
+  font-size: 22rpx;
+  color: #8a8a8a;
+  word-break: break-all;
+}
+.transfer-record-grid {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 16rpx;
+  margin-top: 18rpx;
+}
+.transfer-record-cell {
+  width: 100%;   // 鍘熸潵涓�琛屼袱涓� 鈫� 鏀规垚涓�琛屼竴涓�
+}
+.transfer-record-cell.is-wide {
+  width: 100%;
+}
+.transfer-record-label {
+  display: block;
+  margin-bottom: 8rpx;
+  font-size: 22rpx;
+  color: #8a8a8a;
+}
+.transfer-record-content {
+  min-height: 36rpx;
+}
+.transfer-record-value {
+  display: block;
+  font-size: 24rpx;
+  color: #222;
+  word-break: break-all;
+}
+.transfer-tag-list {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10rpx;
+}
+.transfer-name-tag {
+  padding: 6rpx 14rpx;
+  border-radius: 999rpx;
+  background: #e9f2ff;
+  color: #2f6bff;
+  font-size: 22rpx;
+}
+.audit-status-tag {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  min-height: 40rpx;
+  padding: 0 16rpx;
+  border-radius: 999rpx;
+  font-size: 22rpx;
+  box-sizing: border-box;
+}
+.audit-status-info {
+  background: #edf1f5;
+  color: #6b7280;
+}
+.audit-status-success {
+  background: #e9f9ef;
+  color: #16a34a;
+}
+.audit-status-danger {
+  background: #feeeee;
+  color: #dc2626;
+}
+.audit-status-default {
+  background: #f4f4f5;
+  color: #606266;
+}
+
 .report-modal {
   background: #fff;
   max-height: 85vh;

--
Gitblit v1.9.3