浏览代码

feat(web-admin): outbound release pending/reviewed tabs and ready checkbox

Match storage-release review UX for pilot/basic-experiment outbound release lists.

Co-authored-by: Cursor <cursoragent@cursor.com>
zlwu 3 月之前
父节点
当前提交
5e9e81d28e

+ 2 - 0
web-admin/src/api/outbound-release-review.ts

@@ -172,6 +172,8 @@ export function fetchOutboundReleaseReviewList(params?: {
   bizType?: string
   infusionTimeStart?: string
   infusionTimeEnd?: string
+  reviewPhase?: 'pending' | 'reviewed'
+  readyForReviewOnly?: boolean
 }) {
   return request.get<PageList<OutboundReleaseReview>>({
     url: '/web/admin/pilot-release-reviews',

+ 97 - 3
web-admin/src/views/pilot-service/outbound-release-review/index.vue

@@ -7,6 +7,23 @@
         <h2>审核列表</h2>
       </div>
 
+      <div class="panel-pill-tabs panel-pill-tabs--lg">
+        <div class="panel-pill-tabs__track" role="tablist">
+          <button
+            v-for="tab in STATUS_TABS"
+            :key="tab.name"
+            type="button"
+            role="tab"
+            class="panel-pill-tabs__btn"
+            :class="{ 'is-active': activeTab === tab.name }"
+            :aria-selected="activeTab === tab.name"
+            @click="handleTabChange(tab.name)"
+          >
+            {{ tab.label }}
+          </button>
+        </div>
+      </div>
+
       <div class="filter-block">
         <el-form :model="searchForm" class="filter-form" @submit.prevent>
           <div class="filter-grid">
@@ -20,7 +37,6 @@
                 placeholder="全部"
                 style="width: 100%"
               >
-                <el-option label="待审核" value="" />
                 <el-option
                   v-for="item in reviewConclusionOptions"
                   :key="item.value"
@@ -42,6 +58,18 @@
             </el-form-item>
           </div>
           <div class="filter-actions-row">
+            <label
+              v-if="activeTab === 'pending'"
+              class="storage-release-ready-check"
+            >
+              <el-checkbox v-model="searchForm.showAllPending" />
+              <span class="storage-release-ready-check__copy">
+                <span class="storage-release-ready-check__title">展示全部待审核</span>
+                <span class="storage-release-ready-check__hint">
+                  默认不勾选:仅展示质检与生产工单均为完成的记录;勾选后展示全部。
+                </span>
+              </span>
+            </label>
             <div class="filter-actions-end">
               <el-button class="btn-ghost" @click="handleReset">
                 <el-icon><RefreshLeft /></el-icon>重置
@@ -129,6 +157,15 @@
 
   defineOptions({ name: 'PilotServiceOutboundReleaseReview' })
 
+  type ReviewTab = 'pending' | 'reviewed'
+
+  const STATUS_TABS = [
+    { name: 'pending' as const, label: '待审核' },
+    { name: 'reviewed' as const, label: '已审核' }
+  ]
+
+  const activeTab = ref<ReviewTab>('pending')
+
   const props = defineProps<{
     /** 路由传入:仅列出对应业务线的申请单关联输注计划 */
     bizType?: string
@@ -149,7 +186,8 @@
   const searchForm = reactive({
     reviewConclusion: '',
     keyword: '',
-    infusionTimeRange: null as [string, string] | null
+    infusionTimeRange: null as [string, string] | null,
+    showAllPending: false
   })
   const tableData = ref<OutboundReleaseReview[]>([])
   const selectedRows = ref<OutboundReleaseReview[]>([])
@@ -180,6 +218,8 @@
   async function loadData() {
     loading.value = true
     try {
+      const readyOnly =
+        activeTab.value === 'pending' && !searchForm.showAllPending ? true : undefined
       const res = await fetchOutboundReleaseReviewList({
         page: pagination.page,
         pageSize: pagination.pageSize,
@@ -187,7 +227,9 @@
         keyword: searchForm.keyword || undefined,
         bizType: effectiveBizType.value,
         infusionTimeStart: searchForm.infusionTimeRange?.[0] || undefined,
-        infusionTimeEnd: searchForm.infusionTimeRange?.[1] || undefined
+        infusionTimeEnd: searchForm.infusionTimeRange?.[1] || undefined,
+        reviewPhase: activeTab.value,
+        readyForReviewOnly: readyOnly
       })
       tableData.value = res.list || []
       pagination.total = res.total ?? 0
@@ -196,6 +238,17 @@
     }
   }
 
+  function handleTabChange(name: ReviewTab) {
+    if (activeTab.value === name) return
+    activeTab.value = name
+    pagination.page = 1
+    selectedRows.value = []
+    if (name === 'pending') {
+      searchForm.showAllPending = false
+    }
+    loadData()
+  }
+
   function handleSearch() {
     pagination.page = 1
     loadData()
@@ -205,6 +258,7 @@
     searchForm.reviewConclusion = ''
     searchForm.keyword = ''
     searchForm.infusionTimeRange = null
+    searchForm.showAllPending = false
     pagination.page = 1
     loadData()
   }
@@ -273,3 +327,43 @@
     loadData()
   })
 </script>
+
+<style scoped lang="scss">
+  .filter-form :deep(.el-form-item) {
+    margin-bottom: 0;
+    min-width: 0;
+  }
+
+  .storage-release-ready-check {
+    display: inline-flex;
+    align-items: flex-start;
+    gap: 10px;
+    margin-right: auto;
+    max-width: 520px;
+    padding: 10px 12px;
+    border: 1px dashed #a7f3d0;
+    border-radius: 8px;
+    background: var(--primary-bg, #ecfdf5);
+    cursor: pointer;
+    user-select: none;
+  }
+
+  .storage-release-ready-check__copy {
+    display: flex;
+    flex-direction: column;
+    gap: 2px;
+  }
+
+  .storage-release-ready-check__title {
+    font-size: 13px;
+    font-weight: 600;
+    color: var(--text, #1e293b);
+    line-height: 1.4;
+  }
+
+  .storage-release-ready-check__hint {
+    font-size: 12px;
+    color: var(--text-muted, #64748b);
+    line-height: 1.45;
+  }
+</style>