import dayjs from 'dayjs'
import { request } from '@/core/request'
import { useAppStore } from '@/stores/app'
import { useUserStore } from '@/stores/user'
export type TamAppHead = {
fileName: string
opType: string
ip: string
}
export type TamHead = {
adminUserId: string
apprUserId: string
areaCode: string
branchId: string
consumerId: string
consumerSeqNo: string
digitalSign: string
fileFlag: string
filePath: string
isBatch: boolean
pageIndex: number
pageSize: number
spanId: string
traceId: string
tranCode: string
tranDate: string
tranTimestamp: string
userId: string
verifyUserId: string
versionId: string
}
export type TamRequestPayload
= {
appHead: TamAppHead
head: TamHead
body: TBody
}
export type TamResponseHead = Omit & {
ctrlBits?: string
extra?: Record
pageIndex: number | string
pageSize: number | string
retCode: string
retMsg: string
retStatus: string
}
export type TamResponse = {
head: TamResponseHead
body: TBody
}
type BuildTamPayloadOptions = {
tranCode: string
body: TBody
pageIndex?: number
pageSize?: number
appHead?: Partial
head?: Partial
}
let consumerSeqSeed = Math.floor(Math.random() * 100000000)
export function buildTamRequestPayload({
tranCode,
body,
pageIndex = 1,
pageSize = 10,
appHead,
head,
}: BuildTamPayloadOptions): TamRequestPayload {
const now = dayjs()
const appStore = useAppStore()
const loginContext = getTamLoginContext()
const tranDate = appStore.systemWorkDateCompact
return {
appHead: {
fileName: '',
opType: '',
ip: loginContext.ip,
...appHead,
},
head: {
adminUserId: '',
apprUserId: '',
areaCode: '0000',
branchId: loginContext.branchId,
consumerId: 'TAM001',
// 规则:当前登录用户 ID + 日期 + 8 位运行期递增序列。
consumerSeqNo: `${loginContext.userId}${tranDate}${createConsumerSeq()}`,
digitalSign: '',
fileFlag: 'N',
filePath: '',
isBatch: false,
pageIndex,
pageSize,
spanId: '',
traceId: '',
tranCode,
tranDate,
tranTimestamp: now.format('HHmmss'),
userId: loginContext.userId,
verifyUserId: '',
versionId: '0001',
...head,
},
body,
}
}
export async function tamRequest(
payload: TamRequestPayload,
): Promise> {
const response = await request, TamRequestPayload>({
url: payload.head.tranCode,
method: 'POST',
data: payload,
})
const result = response as unknown as TamResponse
if (result.head?.retStatus && result.head.retStatus !== 'S') {
throw new Error(result.head.retMsg || '交易失败')
}
return result
}
function getTamLoginContext() {
const userStore = useUserStore()
const principal = userStore.authPayload?.principal
return {
// TAM 用户号优先取登录返回的 userId,兼容只返回 username 的场景。
userId: firstText(principal?.userId, principal?.username, userStore.username),
// 当前登录机构来自 /uaa/user/getOrgByUserName 的第一条记录。
branchId: firstText(
userStore.loginOrg?.orgNo,
userStore.loginOrg?.orgId,
principal?.branchId,
principal?.orgId,
principal?.currentOrgId,
getLastText(principal?.orgIds),
),
// appHead.ip 使用登录返回的请求 IP。
ip: firstText(principal?.reqIpAddr, principal?.ip, principal?.loginIp),
}
}
function createConsumerSeq() {
consumerSeqSeed = (consumerSeqSeed + 1) % 100000000
return String(consumerSeqSeed).padStart(8, '0')
}
function getLastText(value: unknown) {
if (!Array.isArray(value)) return undefined
return [...value].reverse().find((item) => typeof item === 'string' && item.trim())
}
function firstText(...values: unknown[]) {
for (const value of values) {
if (typeof value !== 'string') continue
const text = value.trim()
if (text) return text
}
return ''
}