From be85a121031530d69865fd30d0dfb2fe0998a6a3 Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期四, 21 五月 2026 15:21:40 +0800
Subject: [PATCH] 优化查询条件分类

---
 src/views/officeProcessAutomation/ReimburseManage/travel-reimburse/index.vue |  665 ++++++++-----------------------------------------------
 1 files changed, 101 insertions(+), 564 deletions(-)

diff --git a/src/views/officeProcessAutomation/ReimburseManage/travel-reimburse/index.vue b/src/views/officeProcessAutomation/ReimburseManage/travel-reimburse/index.vue
index 2e81e18..89b6d25 100644
--- a/src/views/officeProcessAutomation/ReimburseManage/travel-reimburse/index.vue
+++ b/src/views/officeProcessAutomation/ReimburseManage/travel-reimburse/index.vue
@@ -1,4 +1,4 @@
-<!--OA妯″潡锛氬樊鏃呮姤閿�-->
+<!--OA妯″潡锛氬樊鏃呮姤閿�锛堝鎵瑰疄渚� listPage锛宐usinessType=16锛�-->
 <template>
   <div class="app-container">
     <div class="search_form mb20">
@@ -10,40 +10,15 @@
           placeholder="濮撳悕鎴栫紪鍙�"
           clearable
           :prefix-icon="Search"
-          @keyup.enter="handleQuery"
+          @keyup.enter="onSearch"
         />
-        <span class="search_title" style="margin-left: 12px">鍑哄樊寮�濮嬶細</span>
-        <el-date-picker
-          v-model="searchForm.travelStartFrom"
-          type="date"
-          placeholder="寮�濮嬫棩鏈�"
-          format="YYYY-MM-DD"
-          value-format="YYYY-MM-DD"
-          style="width: 150px"
-          clearable
-        />
-        <span class="search_title" style="margin-left: 8px">缁撴潫锛�</span>
-        <el-date-picker
-          v-model="searchForm.travelEndTo"
-          type="date"
-          placeholder="缁撴潫鏃ユ湡"
-          format="YYYY-MM-DD"
-          value-format="YYYY-MM-DD"
-          style="width: 150px"
-          clearable
-        />
-        <el-button type="primary" style="margin-left: 10px" @click="handleQuery">鎼滅储</el-button>
+        <el-button type="primary" style="margin-left: 10px" @click="onSearch">鎼滅储</el-button>
         <el-button @click="resetSearch">閲嶇疆</el-button>
       </div>
-      <div class="search_actions">
-        <el-button type="success" plain @click="handleImportClick">瀵煎叆</el-button>
-        <el-button type="warning" plain @click="handleExport">瀵煎嚭</el-button>
-        <el-button type="primary" @click="openFormDialog('add')">鏂板宸梾鎶ラ攢</el-button>
+      <div>
+        <el-button type="primary" @click="openAddWithTemplate">鏂板宸梾鎶ラ攢</el-button>
       </div>
     </div>
-
-    <input ref="importInputRef" type="file" accept="application/json,.json" class="sr-only-input" @change="onImportFile" />
-
     <div class="table_list">
       <PIMTable
         rowKey="id"
@@ -53,462 +28,123 @@
         :isSelection="false"
         :tableLoading="tableLoading"
         :total="page.total"
-        @pagination="pagination"
+        @pagination="onPagination"
       />
     </div>
 
-    <!-- 鏂板 / 缂栬緫 -->
-    <el-dialog
-      v-model="formDialog.visible"
-      :title="formDialog.title"
-      width="1120px"
-      append-to-body
-      destroy-on-close
-      class="travel-reimburse-form-dialog"
-      @closed="onFormClosed"
-    >
-      <el-alert
-        v-if="budgetHint.visible"
-        :title="budgetHint.title"
-        :type="budgetHint.type"
-        :description="budgetHint.description"
-        show-icon
-        :closable="false"
-        class="mb16"
-      />
-      <el-alert v-if="overBudgetWarnings.length" type="warning" show-icon :closable="false" class="mb16">
-        <template #title>宸梾鏍囧噯瓒呮敮鎻愰啋锛堥渶鐗规壒锛�</template>
-        <ul class="warn-list">
-          <li v-for="(w, i) in overBudgetWarnings" :key="i">{{ w }}</li>
-        </ul>
-      </el-alert>
+    <ApprovalInstanceSubmitDialog
+      v-model="submitDialog.visible"
+      :title="submitDialogTitle"
+      :form="submitForm"
+      :rules="submitFormRules"
+      :fields="submitFormFields"
+      :active-template="activeTemplate"
+      :user-options="flowUserOptions"
+      :is-edit="isSubmitEdit"
+      :saving="submitSaving"
+      :form-ref="submitFormRef"
+      flow-attachments-only
+      @submit="onSubmit"
+    />
 
-      <el-form
-        ref="formRef"
-        :model="form"
-        :rules="formRules"
-        label-width="120px"
-        class="travel-reimburse-form"
-        :disabled="formDialog.readonly"
-      >
-        <el-card class="form-section" shadow="never">
-          <template #header><span class="card-header-title">鍩烘湰淇℃伅</span></template>
-          <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="鍛樺伐缂栧彿">
-              <el-input v-model="form.employeeNo" readonly placeholder="閫夋嫨鍛樺伐鍚庤嚜鍔ㄥ甫鍑�" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍛樺伐濮撳悕" prop="applicantId">
-              <el-select
-                v-model="form.applicantId"
-                filterable
-                remote
-                clearable
-                reserve-keyword
-                placeholder="璇烽�夋嫨鎴栨悳绱㈠憳宸�"
-                style="width: 100%"
-                :remote-method="remoteSearchApplicantForm"
-                :loading="applicantFormSearchLoading"
-                @change="onApplicantChange"
-              >
-                <el-option
-                  v-for="u in applicantFormOptions"
-                  :key="u.userId"
-                  :label="userSelectLabel(u)"
-                  :value="u.userId"
-                />
-              </el-select>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="24">
-            <el-form-item label="鎶ラ攢鍘熷洜" prop="reimburseReason">
-              <el-input
-                v-model="form.reimburseReason"
-                type="textarea"
-                :rows="3"
-                placeholder="璇峰~鍐欏嚭宸強鎶ラ攢鍘熷洜"
-                maxlength="2000"
-                show-word-limit
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="鍑哄樊寮�濮�" prop="travelStartTime">
-              <el-date-picker
-                v-model="form.travelStartTime"
-                type="datetime"
-                placeholder="寮�濮嬫椂闂�"
-                format="YYYY-MM-DD HH:mm:ss"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                style="width: 100%"
-                @change="onTravelRangeChange"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鍑哄樊缁撴潫" prop="travelEndTime">
-              <el-date-picker
-                v-model="form.travelEndTime"
-                type="datetime"
-                placeholder="缁撴潫鏃堕棿"
-                format="YYYY-MM-DD HH:mm:ss"
-                value-format="YYYY-MM-DD HH:mm:ss"
-                style="width: 100%"
-                @change="onTravelRangeChange"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :span="8">
-            <el-form-item label="鍑哄樊澶╂暟">
-              <el-input :model-value="travelDaysDisplay" readonly>
-                <template #append>澶�</template>
-              </el-input>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鍑哄樊鍦�" prop="departurePlace">
-              <el-input v-model="form.departurePlace" placeholder="鍑哄彂鍩庡競" @blur="recalcTravelStandards" />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鐩殑鍦�" prop="destination">
-              <el-input v-model="form.destination" placeholder="鐩殑鍩庡競" @blur="recalcTravelStandards" />
-            </el-form-item>
-          </el-col>
-          </el-row>
-        </el-card>
+    <ApprovalTemplateBindDialog
+      v-model:visible="templateBindVisible"
+      :module-key="APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE"
+      skip-form-confirm
+      @confirm="onTemplateBound"
+      @closed="onTemplateBindClosed"
+    />
 
-        <el-card class="form-section" shadow="never">
-          <template #header>
-            <div class="card-header-row">
-              <span class="card-header-title">宸梾鏍囧噯</span>
-              <el-text type="info" size="small">{{ travelTierLabel }} 路 鐢熸椿琛ヨ创寤鸿 {{ suggestedLivingSubsidy }} 鍏�</el-text>
-            </div>
-          </template>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="閰掑簵鏍囧噯">
-              <el-input-number
-                v-model="form.hotelStandard"
-                :min="0"
-                :precision="2"
-                controls-position="right"
-                style="width: 100%"
-                @change="recalcTravelStandards"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="浣忓澶╂暟">
-              <el-input-number
-                v-model="form.hotelDays"
-                :min="0"
-                :max="365"
-                :precision="0"
-                controls-position="right"
-                style="width: 100%"
-                @change="recalcTravelStandards"
-              />
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-form-item label="鐢熸椿琛ヨ创">
-              <el-input-number
-                v-model="form.livingSubsidy"
-                :min="0"
-                :precision="2"
-                controls-position="right"
-                style="width: 100%"
-                @change="recalcTravelStandards"
-              />
-            </el-form-item>
-          </el-col>
-        </el-row>
-          <el-row :gutter="20">
-            <el-col :span="8">
-              <el-form-item label="浜ら�氳ˉ璐�">
-                <el-input :model-value="String(suggestedTransportSubsidy)" readonly><template #append>鍏�</template></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="浣忓闄愰">
-                <el-input :model-value="String(suggestedHotelLimit)" readonly><template #append>鍏�</template></el-input>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
-              <el-form-item label="鐗规壒鏍囪">
-                <el-tag :type="form.needSpecialApproval ? 'danger' : 'success'" effect="plain">
-                  {{ form.needSpecialApproval ? "瓒呮敮闇�鐗规壒" : "鍦ㄦ爣鍑嗚寖鍥村唴" }}
-                </el-tag>
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </el-card>
-
-        <el-card class="form-section" shadow="never">
-          <template #header><span class="card-header-title">閲戦涓庢敹娆�</span></template>
-          <el-row :gutter="20">
-            <el-col :span="12">
-              <el-form-item label="鐢宠閲戦" prop="applyAmount">
-                <div class="amount-row">
-                  <el-input-number v-model="form.applyAmount" :min="0" :precision="2" controls-position="right" class="amount-input" />
-                  <el-button v-if="!formDialog.readonly" type="primary" link @click="syncApplyAmountFromDetails">
-                    鎸夋槑缁嗘眹鎬� {{ detailTotalAmount }} 鍏�
-                  </el-button>
-                </div>
-              </el-form-item>
-            </el-col>
-            <el-col :span="12">
-              <el-form-item label="鏀舵浜�" prop="payee">
-                <el-input v-model="form.payee" placeholder="璇疯緭鍏ユ敹娆句汉" maxlength="50" />
-              </el-form-item>
-            </el-col>
-          </el-row>
-        </el-card>
-
-        <el-card class="form-section" shadow="never">
-          <template #header>
-            <div class="card-header-row">
-              <span class="card-header-title">鎶ラ攢鏄庣粏</span>
-              <el-button v-if="!formDialog.readonly" type="primary" plain size="small" @click="addExpenseDetail">鏂板鏄庣粏</el-button>
-            </div>
-          </template>
-
-        <el-table :data="form.expenseDetails" border size="small" class="detail-table">
-          <el-table-column type="index" label="搴忓彿" width="55" align="center" />
-          <el-table-column label="鍙戠エ鏃ユ湡" width="150">
-            <template #default="{ row }">
-              <el-date-picker
-                v-if="!formDialog.readonly"
-                v-model="row.invoiceDate"
-                type="date"
-                value-format="YYYY-MM-DD"
-                size="small"
-                style="width: 100%"
-              />
-              <span v-else>{{ row.invoiceDate || "鈥�" }}</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="璐圭敤绉戠洰" width="130">
-            <template #default="{ row }">
-              <el-select
-                v-if="!formDialog.readonly"
-                v-model="row.expenseSubject"
-                size="small"
-                style="width: 100%"
-                @change="recalcTravelStandards"
-              >
-                <el-option
-                  v-for="opt in EXPENSE_SUBJECT_OPTIONS"
-                  :key="opt.value"
-                  :label="opt.label"
-                  :value="opt.value"
-                />
-              </el-select>
-              <span v-else>{{ expenseSubjectLabel(row.expenseSubject) }}</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="閲戦" width="120">
-            <template #default="{ row }">
-              <el-input-number
-                v-if="!formDialog.readonly"
-                v-model="row.amount"
-                :min="0"
-                :precision="2"
-                size="small"
-                controls-position="right"
-                style="width: 100%"
-                @change="onDetailAmountChange"
-              />
-              <span v-else>{{ row.amount ?? "鈥�" }}</span>
-            </template>
-          </el-table-column>
-          <el-table-column label="鎻忚堪" min-width="140">
-            <template #default="{ row }">
-              <el-input v-if="!formDialog.readonly" v-model="row.description" size="small" placeholder="璇存槑" />
-              <span v-else>{{ row.description || "鈥�" }}</span>
-            </template>
-          </el-table-column>
-          <el-table-column v-if="!formDialog.readonly" label="鎿嶄綔" width="70" align="center">
-            <template #default="{ $index }">
-              <el-button type="danger" link size="small" @click="removeExpenseDetail($index)">鍒犻櫎</el-button>
-            </template>
-          </el-table-column>
-        </el-table>
-        </el-card>
-
-        <el-card class="form-section" shadow="never">
-          <template #header><span class="card-header-title">闄勪欢锛堝彂绁級</span></template>
-          <el-form-item label-width="0" class="attachment-form-item">
-            <div class="upload-block">
-              <FileUpload v-model:file-list="form.attachmentList" :limit="20" button-text="鐐瑰嚮閫夋嫨鏂囦欢" />
-            </div>
-          </el-form-item>
-        </el-card>
-
-        <el-card class="form-section" shadow="never">
-          <template #header><span class="card-header-title">瀹℃壒娴佺▼</span></template>
-          <el-form-item prop="approvalFlowNodes" label-width="0">
-          <ApprovalFlowEditor
-            v-if="!formDialog.readonly"
-            v-model="form.approvalFlowNodes"
-            :user-options="flowUserOptions"
-            @update:model-value="onApprovalFlowChange"
-          />
-          <ApprovalFlowProgress v-else :nodes="form.approvalFlowNodes" :current-index="form.currentNodeIndex" />
-          <p v-if="!formDialog.readonly" class="flow-tip">鑷冲皯淇濈暀涓�涓妭鐐癸紱瀹℃牳涓�佸凡閫氳繃鐨勫崟鎹笉鍙紪杈戙��</p>
-        </el-form-item>
-        </el-card>
-      </el-form>
-      <template #footer>
-        <el-button v-if="!formDialog.readonly" type="primary" @click="submitForm">鎻� 浜�</el-button>
-        <el-button @click="formDialog.visible = false">{{ formDialog.readonly ? "鍏� 闂�" : "鍙� 娑�" }}</el-button>
-      </template>
-    </el-dialog>
-
-    <!-- 璇︽儏 -->
-    <el-dialog v-model="detailDialog.visible" title="宸梾鎶ラ攢璇︽儏" width="900px" append-to-body destroy-on-close>
-      <DetailPanel :row="detailRow" />
-      <ApprovalFlowProgress
-        class="mt16"
-        :nodes="detailRow.approvalFlowNodes"
-        :current-index="detailRow.currentNodeIndex ?? 0"
-      />
-      <el-divider content-position="left">瀹℃壒璁板綍锛堝叏娴佺▼鐣欑棔锛�</el-divider>
-      <el-timeline v-if="detailRow.approvalRecords?.length">
-        <el-timeline-item
-          v-for="(rec, i) in detailRow.approvalRecords"
-          :key="i"
-          :type="rec.result === 'approved' ? 'success' : rec.result === 'rejected' ? 'danger' : 'primary'"
-          :timestamp="rec.time"
-        >
-          {{ rec.operatorName }} 鈥� {{ approvalActionLabel(rec.result) }}锛歿{ rec.opinion || "鏃犳剰瑙�" }}
-        </el-timeline-item>
-      </el-timeline>
-      <el-empty v-else description="鏆傛棤瀹℃壒璁板綍" :image-size="60" />
-      <template #footer>
-        <el-button type="primary" @click="detailDialog.visible = false">鍏� 闂�</el-button>
-      </template>
-    </el-dialog>
-
-    <!-- 瀹℃壒 -->
-    <el-dialog
-      v-model="approveDialog.visible"
-      title="宸梾鎶ラ攢瀹℃壒"
-      width="1000px"
-      append-to-body
-      destroy-on-close
-      @closed="approveOpinion = ''"
-    >
-      <DetailPanel :row="approveDialog.row" />
-      <el-divider content-position="left">娴佺▼杩涘害</el-divider>
-      <ApprovalFlowProgress
-        :nodes="approveDialog.row?.approvalFlowNodes"
-        :current-index="approveDialog.row?.currentNodeIndex ?? 0"
-      />
-      <el-form label-width="100px" class="mt16">
-        <el-form-item label="瀹℃壒鎰忚">
-          <el-input
-            v-model="approveOpinion"
-            type="textarea"
-            :rows="3"
-            maxlength="500"
-            show-word-limit
-            placeholder="閫氳繃鍙暀绌猴紱椹冲洖璇峰~鍐欏師鍥�"
-          />
-        </el-form-item>
-      </el-form>
-      <template #footer>
-        <el-button type="success" @click="submitApprove('approved')">閫� 杩�</el-button>
-        <el-button type="danger" @click="submitApprove('rejected')">椹� 鍥�</el-button>
-        <el-button @click="approveDialog.visible = false">鍙� 娑�</el-button>
-      </template>
-    </el-dialog>
+    <ApprovalInstanceDetailDialog
+      v-model="detailDialog.visible"
+      title="宸梾鎶ラ攢璇︽儏"
+      :row="detailRow"
+      @edit="openEditFromDetail"
+    />
   </div>
 </template>
 
 <script setup>
-import FileUpload from "@/components/AttachmentUpload/file/index.vue";
-import ApprovalFlowEditor from "@/views/officeProcessAutomation/AttendManage/overtime-apply/components/ApprovalFlowEditor.vue";
-import ApprovalFlowProgress from "./components/ApprovalFlowProgress.vue";
-import DetailPanel from "./components/DetailPanel.vue";
-import { useTravelReimburse } from "./useTravelReimburse.js";
+import { Search } from "@element-plus/icons-vue";
+import { ElMessage } from "element-plus";
+import { onMounted, reactive } from "vue";
+import ApprovalInstanceDetailDialog from "../../ApproveManage/approve-shared/components/ApprovalInstanceDetailDialog.vue";
+import ApprovalInstanceSubmitDialog from "../../ApproveManage/approve-shared/components/ApprovalInstanceSubmitDialog.vue";
+import ApprovalTemplateBindDialog from "../../ApproveManage/approve-shared/components/ApprovalTemplateBindDialog.vue";
+import { buildInstanceTableColumns } from "../../ApproveManage/approve-shared/approvalInstanceFormConfigTable.js";
+import { APPROVAL_MODULE_KEYS } from "../../ApproveManage/approve-shared/approvalModuleRegistry.js";
+import { useApprovalInstanceModule } from "../../ApproveManage/approve-shared/useApprovalInstanceModule.js";
+import { useFlowUserOptions } from "../../ApproveManage/approve-shared/useFlowUserOptions.js";
 
-const tr = useTravelReimburse();
+const searchForm = reactive({ applicantKeyword: "" });
+
+const mod = useApprovalInstanceModule({
+  moduleKey: APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE,
+  buildExtraListParams(sf) {
+    const extra = {};
+    const kw = (sf?.applicantKeyword || "").trim();
+    if (kw && /[\u4e00-\u9fa5]/.test(kw)) extra.applicantName = kw;
+    return extra;
+  },
+});
+
 const {
-  Search,
-  EXPENSE_SUBJECT_OPTIONS,
-  expenseSubjectLabel,
-  searchForm,
+  tableData,
   tableLoading,
   page,
-  tableData,
-  tableColumn,
-  importInputRef,
-  formRef,
-  form,
-  formDialog,
-  formRules,
   detailDialog,
   detailRow,
-  approveDialog,
-  approveOpinion,
-  applicantFormSearchLoading,
-  applicantFormOptions,
-  flowUserOptions,
-  travelDaysDisplay,
-  travelTierLabel,
-  suggestedLivingSubsidy,
-  suggestedTransportSubsidy,
-  suggestedHotelLimit,
-  detailTotalAmount,
-  overBudgetWarnings,
-  budgetHint,
-  handleQuery,
-  resetSearch,
-  pagination,
-  remoteSearchApplicantForm,
-  userSelectLabel,
-  onApplicantChange,
-  recalcTravelStandards,
-  onTravelRangeChange,
-  onDetailAmountChange,
-  onApprovalFlowChange,
-  addExpenseDetail,
-  removeExpenseDetail,
-  syncApplyAmountFromDetails,
-  openFormDialog,
-  onFormClosed,
+  submitDialog,
   submitForm,
-  openDetail,
-  approvalActionLabel,
-  submitApprove,
-  handleExport,
-  handleImportClick,
-  onImportFile,
-} = tr;
+  submitFormRef,
+  submitSaving,
+  isSubmitEdit,
+  activeTemplate,
+  submitFormFields,
+  submitFormRules,
+  submitDialogTitle,
+  templateBindVisible,
+  handleQuery,
+  initModuleList,
+  pagination,
+  openAddWithTemplate,
+  onTemplateBound,
+  onTemplateBindClosed,
+  openEditFromDetail,
+  submitInstanceForm,
+  buildTableActions,
+} = mod;
+
+const { flowUserOptions, loadFlowUsers } = useFlowUserOptions();
+const tableColumn = buildInstanceTableColumns(tableData, buildTableActions);
+
+function onSearch() {
+  handleQuery(searchForm);
+}
+
+function resetSearch() {
+  searchForm.applicantKeyword = "";
+  onSearch();
+}
+
+function onPagination(obj) {
+  pagination(obj, searchForm);
+}
+
+async function onSubmit() {
+  const ok = await submitInstanceForm({ skipValidate: true });
+  if (ok) ElMessage.success(isSubmitEdit.value ? "淇敼鎴愬姛" : "鎻愪氦鎴愬姛");
+}
+
+onMounted(async () => {
+  loadFlowUsers();
+  await initModuleList(searchForm);
+});
 </script>
 
 <style scoped>
 .mb20 {
   margin-bottom: 20px;
-}
-.mb16 {
-  margin-bottom: 16px;
-}
-.mb8 {
-  margin-bottom: 8px;
-}
-.mt16 {
-  margin-top: 16px;
 }
 .search_form {
   display: flex;
@@ -517,107 +153,8 @@
   justify-content: space-between;
   gap: 12px;
 }
-.search_actions {
-  display: flex;
-  flex-wrap: wrap;
-  gap: 8px;
-}
 .search_title {
   font-size: 14px;
   color: var(--el-text-color-regular);
-}
-.sr-only-input {
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  margin: -1px;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  white-space: nowrap;
-  border: 0;
-}
-.form-section {
-  margin-bottom: 16px;
-  border: 1px solid var(--el-border-color-lighter);
-}
-.form-section :deep(.el-card__header) {
-  padding: 12px 16px;
-  background: var(--el-fill-color-lighter);
-}
-.form-section :deep(.el-card__body) {
-  padding: 16px 16px 4px;
-}
-.card-header-title {
-  font-size: 15px;
-  font-weight: 600;
-}
-.card-header-row {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  gap: 12px;
-}
-.amount-row {
-  display: flex;
-  align-items: center;
-  gap: 12px;
-  width: 100%;
-}
-.amount-input {
-  flex: 1;
-  min-width: 160px;
-}
-.w-full {
-  width: 100%;
-}
-.attachment-form-item {
-  margin-bottom: 0;
-}
-.detail-table {
-  margin-bottom: 0;
-}
-.section-title {
-  font-size: 15px;
-  font-weight: 600;
-  margin: 8px 0 12px;
-  color: var(--el-text-color-primary);
-  border-left: 3px solid var(--el-color-primary);
-  padding-left: 8px;
-}
-.field-tip {
-  font-size: 12px;
-  color: var(--el-text-color-secondary);
-  margin-top: 4px;
-}
-.warn-list {
-  margin: 0;
-  padding-left: 18px;
-}
-.detail-toolbar {
-  margin-bottom: 8px;
-}
-.upload-block {
-  width: 100%;
-}
-.flow-tip {
-  font-size: 12px;
-  color: var(--el-text-color-secondary);
-  margin-top: 8px;
-}
-.sync-btn {
-  margin-top: 4px;
-}
-.travel-reimburse-form-dialog :deep(.el-dialog__body) {
-  padding-top: 12px;
-}
-.travel-reimburse-form :deep(.el-form-item) {
-  margin-bottom: 18px;
-}
-.travel-reimburse-form :deep(.el-input-number) {
-  width: 100%;
-}
-.travel-reimburse-form :deep(.el-row) {
-  margin-bottom: 0;
 }
 </style>

--
Gitblit v1.9.3