feat(hjc-web): 新建订单详情页,订单列表与详情支持下载已支付订单的标书

此前 PC 没有订单详情页,标书下载只有两句文案(`.scratch/hjc-web-order-detail/01`)。

- 新增 `app/pages/tender/orders/[id].vue`:订单状态、标书附件、待支付操作区、
  标书/支付/购买人信息;取数走 `useRequestFetch()`(裸 `$fetch` 在 SSR 不转发 Cookie,
  会把用户登出)
- `app/pages/tender/orders.vue` → `orders/index.vue`:Nuxt 里同名 file+目录会生成父子路由,
  详情页会被父页吞掉,必须让列表页是 `index.vue`
- 列表页每张卡片加「标书附件」(仅已支付)与「查看详情」,不整卡可点(卡内已有按钮与链接)
- 新增 `app/components/HjcTenderFiles.vue` 与代理 `server/api/tender/order-detail.get.ts`
- 附件地址来自后端按 `payStatus=1` 下发的 `tenderFiles`,前端不做权限判断、不自己拼地址

规格与验收:`.scratch/hjc-tender-download/`
This commit is contained in:
2026-09-17 18:09:27 +08:00
parent 9299485899
commit 2e847b5e09
8 changed files with 490 additions and 17 deletions
+42
View File
@@ -0,0 +1,42 @@
import { $fetch } from 'ofetch'
import { createError, defineEventHandler, getHeader, getCookie, getQuery } from 'h3'
import { useRuntimeConfig } from '#imports'
import { getTenantFromContext } from '../../utils/tenant'
/**
* 订单详情(含已支付订单的标书附件)
* GET /api/tender/order-detail?id=16
* 代理到 mp-api /api/hjc/order/{id};需登录态 + 订单归属(后端按 401/403 区分)。
*
* 为什么要这个代理:`/hjc/order/{id}` 会带上 `project`,且对**已支付**订单附带
* `tenderFiles`(后端解析好的标书附件列表)——标书下载就靠它。未支付订单两张表都不给,
* 所以页面上「没有附件」不是前端藏起来的,而是后端压根没下发地址。
*
* 约定:原样透传 ApiResult{code,message,data}。HTTP 状态码恒为 200
* 「未登录/token 失效」是 code=401、「无权查看该订单」是 code=403,前端必须按 code 判定;
* 故这里**不能**只取 data,否则登录态失败会被当成「订单不存在」。
*/
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig()
const ctx = getTenantFromContext(event, config)
const { id } = getQuery(event)
const cookieToken = getCookie(event, 'hjc_token')
const auth = getHeader(event, 'authorization') || (cookieToken ? `Bearer ${cookieToken}` : null)
try {
return await $fetch(`/hjc/order/${encodeURIComponent(String(id ?? ''))}`, {
baseURL: config.public.modulesApiBase,
method: 'GET',
headers: {
TenantId: ctx.tenantId,
...(auth ? { Authorization: auth } : {})
},
query: { TenantId: ctx.tenantId }
})
} catch (error: any) {
throw createError({
statusCode: error?.statusCode || error?.response?.status || 502,
statusMessage: error?.statusMessage || 'Failed to fetch order detail'
})
}
})