Przeglądaj źródła

feat(web-admin): add bank receipt upload on OA done center

Show permission-gated upload action and wire the receipt dialog.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 2 tygodni temu
rodzic
commit
3a148b2985
1 zmienionych plików z 85 dodań i 4 usunięć
  1. 85 4
      web-admin/src/views/oa-approval/done/index.vue

+ 85 - 4
web-admin/src/views/oa-approval/done/index.vue

@@ -116,12 +116,28 @@
               </el-tag>
             </template>
           </el-table-column>
-          <el-table-column label="操作" min-width="260" fixed="right" align="center">
+          <el-table-column label="操作" min-width="400" fixed="right" align="center">
             <template #default="{ row }">
               <el-button class="btn-op-item primary" @click="openDetail(row)">
                 <el-icon><View /></el-icon>
                 查看
               </el-button>
+              <el-button
+                class="btn-op-item"
+                :loading="printingId === (row.instanceId || row.id)"
+                @click="printRow(row)"
+              >
+                <el-icon><Printer /></el-icon>
+                打印
+              </el-button>
+              <el-button
+                v-if="canUploadBankReceipt"
+                class="btn-op-item"
+                @click="openBankReceipt(row)"
+              >
+                <el-icon><Upload /></el-icon>
+                上传回执
+              </el-button>
             </template>
           </el-table-column>
         </el-table>
@@ -140,24 +156,48 @@
         </div>
       </div>
     </section>
+
+    <OaBankReceiptDialog
+      v-model="bankReceiptVisible"
+      :instance-id="bankReceiptInstanceId"
+      :meta="bankReceiptMeta"
+    />
   </div>
 </template>
 
 <script setup lang="ts">
-  import { onActivated, onMounted, reactive, ref } from 'vue'
+  import { computed, onActivated, onMounted, reactive, ref } from 'vue'
   import { useRouter } from 'vue-router'
-  import { RefreshLeft, Search, View } from '@element-plus/icons-vue'
-  import { fetchOaTasks } from '@/api/oaApproval'
+  import { ElMessage } from 'element-plus'
+  import { Printer, RefreshLeft, Search, Upload, View } from '@element-plus/icons-vue'
+  import { fetchOaInstanceDetail, fetchOaTasks } from '@/api/oaApproval'
+  import OaBankReceiptDialog from '@/components/oa-approval/OaBankReceiptDialog.vue'
+  import { useMenuPerm } from '@/hooks/core/useMenuPerm'
+  import { useUserStore } from '@/store/modules/user'
+  import { exportOaApprovalPdf } from '@/utils/oa-approval-print'
 
   defineOptions({ name: 'OaApprovalDone' })
 
+  const OA_DONE_BANK_RECEIPT = 'oa:done:bank-receipt'
+  const { hasMenuPerm } = useMenuPerm()
+  const canUploadBankReceipt = computed(() => hasMenuPerm(OA_DONE_BANK_RECEIPT))
+
   const router = useRouter()
+  const userStore = useUserStore()
   const loading = ref(false)
+  const printingId = ref('')
   const rows = ref<any[]>([])
   const page = ref(1)
   const pageSize = ref(20)
   const total = ref(0)
   const applyTimeRange = ref<string[] | null>(null)
+  const bankReceiptVisible = ref(false)
+  const bankReceiptInstanceId = ref('')
+  const bankReceiptMeta = ref<{
+    appName?: string
+    initiatorUserName?: string
+    applyTime?: string
+  }>({})
   const searchForm = reactive({
     appName: '',
     initiatorName: '',
@@ -168,6 +208,13 @@
     return (page.value - 1) * pageSize.value + index + 1
   }
 
+  function currentPrinterName() {
+    const info: any = userStore.info || userStore.getUserInfo || {}
+    return String(
+      info.realName || info.nickName || info.userName || info.username || ''
+    ).trim()
+  }
+
   function statusType(s: string) {
     if (s === 'pending' || s === 'running') return 'warning'
     if (s === 'approved' || s === 'completed' || s === 'done') return 'success'
@@ -197,6 +244,40 @@
     router.push({ path: `/system-manage/oa-approval/instances/${id}` })
   }
 
+  function openBankReceipt(row: any) {
+    const id = String(row?.instanceId || row?.id || '').trim()
+    if (!id) return
+    bankReceiptInstanceId.value = id
+    bankReceiptMeta.value = {
+      appName: row.appName || row.title || '',
+      initiatorUserName: row.initiatorUserName || '',
+      applyTime: row.applyTime || ''
+    }
+    bankReceiptVisible.value = true
+  }
+
+  async function printRow(row: any) {
+    const id = String(row?.instanceId || row?.id || '').trim()
+    if (!id || printingId.value) return
+    printingId.value = id
+    let detail: any
+    try {
+      detail = await fetchOaInstanceDetail(id)
+    } catch {
+      printingId.value = ''
+      ElMessage.error('加载审批单失败')
+      return
+    }
+    try {
+      await exportOaApprovalPdf(detail, { printerName: currentPrinterName() })
+      ElMessage.success('PDF 已下载')
+    } catch {
+      ElMessage.error('导出 PDF 失败')
+    } finally {
+      printingId.value = ''
+    }
+  }
+
   function buildFilterParams() {
     const range = applyTimeRange.value
     return {