|
|
@@ -39,6 +39,16 @@ function delay<T>(data: T, ms = 200): Promise<T> {
|
|
|
return new Promise((resolve) => setTimeout(() => resolve(data), ms))
|
|
|
}
|
|
|
|
|
|
+function mockPaged<T>(list: T[], pageNum = 1, pageSize = 10) {
|
|
|
+ const start = (pageNum - 1) * pageSize
|
|
|
+ return delay({
|
|
|
+ list: list.slice(start, start + pageSize),
|
|
|
+ total: list.length,
|
|
|
+ pageNum,
|
|
|
+ pageSize,
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
/* ========== 工作台 ========== */
|
|
|
export function fetchDashboard(params: {
|
|
|
roleKey: string
|
|
|
@@ -68,9 +78,19 @@ export function fetchVillageBatches() {
|
|
|
export function submitRetireQualify(
|
|
|
personnelId: string,
|
|
|
payload?: { opinion?: string; fileUrls?: string },
|
|
|
+ config?: { silent?: boolean },
|
|
|
) {
|
|
|
if (useMock()) return delay({ ok: true })
|
|
|
- return real.submitRetireQualify(personnelId, payload)
|
|
|
+ return real.submitRetireQualify(personnelId, payload, config)
|
|
|
+}
|
|
|
+
|
|
|
+export function submitRetireQualifyBatch(payload: {
|
|
|
+ personnelIds: string[]
|
|
|
+ opinion?: string
|
|
|
+ fileUrls?: string
|
|
|
+}) {
|
|
|
+ if (useMock()) return delay({ ok: true, successCount: payload.personnelIds.length, pendingCount: 0, failCount: 0, message: '' })
|
|
|
+ return real.submitRetireQualifyBatch(payload)
|
|
|
}
|
|
|
|
|
|
export function generateDistrictMonthBatch(
|
|
|
@@ -124,6 +144,23 @@ export function fetchPeoplePage(params?: real.PeoplePageParams) {
|
|
|
(code === 'FUNERAL' && String(p.status).includes('死亡')),
|
|
|
)
|
|
|
}
|
|
|
+ if (params?.insuranceMatchResult) {
|
|
|
+ const code = String(params.insuranceMatchResult).toUpperCase()
|
|
|
+ list = list.filter(
|
|
|
+ (p) => String((p as Person).insuranceMatchResult || '').toUpperCase() === code,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ if (params?.retireQualifyType) {
|
|
|
+ const code = String(params.retireQualifyType).toUpperCase()
|
|
|
+ list = list.filter((p) => {
|
|
|
+ const t = String((p as Person).retireQualifyType || '').toUpperCase()
|
|
|
+ if (code === 'UNSET') return !t || t === 'UNSET' || t === 'NONE' || t === 'CLEARED'
|
|
|
+ if (code === 'WITH_LAND') return t === 'WITH_LAND' || (p as Person).retireQualifyType === '有土地退养'
|
|
|
+ if (code === 'WITHOUT_LAND') return t === 'WITHOUT_LAND' || (p as Person).retireQualifyType === '无土地有资格'
|
|
|
+ if (code === 'INELIGIBLE') return t === 'INELIGIBLE' || (p as Person).retireQualifyType === '无资格'
|
|
|
+ return t === code
|
|
|
+ })
|
|
|
+ }
|
|
|
const pageNum = params?.pageNum || 1
|
|
|
const pageSize = params?.pageSize || 10
|
|
|
const start = (pageNum - 1) * pageSize
|
|
|
@@ -295,7 +332,7 @@ export function fetchBatchMemberIds(batchId: string) {
|
|
|
}
|
|
|
|
|
|
/** 本批次人员明细(按发放明细,非全村人员库) */
|
|
|
-export function fetchBatchMemberPeople(
|
|
|
+export function fetchBatchMemberPeoplePage(
|
|
|
batchId: string,
|
|
|
opts?: {
|
|
|
batchNo?: string
|
|
|
@@ -303,11 +340,13 @@ export function fetchBatchMemberPeople(
|
|
|
village?: string
|
|
|
pruneDefaults?: boolean
|
|
|
parentBatchId?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
},
|
|
|
) {
|
|
|
if (useMock()) {
|
|
|
const batch = mockVillageBatches.find((b) => b.id === batchId)
|
|
|
- if (!batch) return delay([] as BatchMemberPerson[])
|
|
|
+ if (!batch) return delay({ list: [] as BatchMemberPerson[], total: 0, pageNum: 1, pageSize: 10 })
|
|
|
const list = mockPeople
|
|
|
.filter(
|
|
|
(p) =>
|
|
|
@@ -317,7 +356,25 @@ export function fetchBatchMemberPeople(
|
|
|
!['暂停', '停止', '死亡丧葬', '已归档'].includes(p.status),
|
|
|
)
|
|
|
.map((p) => mockAsBatchMember(p))
|
|
|
- return delay(list)
|
|
|
+ return mockPaged(list, opts?.pageNum, opts?.pageSize)
|
|
|
+ }
|
|
|
+ return real.fetchBatchMemberPeoplePage(batchId, opts)
|
|
|
+}
|
|
|
+
|
|
|
+export function fetchBatchMemberPeople(
|
|
|
+ batchId: string,
|
|
|
+ opts?: {
|
|
|
+ batchNo?: string
|
|
|
+ town?: string
|
|
|
+ village?: string
|
|
|
+ pruneDefaults?: boolean
|
|
|
+ parentBatchId?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
+ },
|
|
|
+) {
|
|
|
+ if (useMock()) {
|
|
|
+ return fetchBatchMemberPeoplePage(batchId, opts).then((p) => p.list)
|
|
|
}
|
|
|
return real.fetchBatchMemberPeople(batchId, opts)
|
|
|
}
|
|
|
@@ -532,7 +589,13 @@ export function addBatchProcessNote(payload: {
|
|
|
}
|
|
|
|
|
|
/* ========== 居保匹配 ========== */
|
|
|
-export function fetchInsuranceBatches(params?: { tab?: 'todo' | 'history' }) {
|
|
|
+export function fetchInsuranceBatchesPage(params?: {
|
|
|
+ tab?: 'todo' | 'history'
|
|
|
+ batchNo?: string
|
|
|
+ stage?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
+}) {
|
|
|
if (useMock()) {
|
|
|
const todo = new Set(['居保状态匹配', '比对结果已生成'])
|
|
|
const history = new Set([
|
|
|
@@ -543,24 +606,50 @@ export function fetchInsuranceBatches(params?: { tab?: 'todo' | 'history' }) {
|
|
|
'已归档',
|
|
|
])
|
|
|
const stages = params?.tab === 'history' ? history : todo
|
|
|
- return delay(mockVillageBatches.filter((b) => stages.has(b.stage)))
|
|
|
+ let list = mockVillageBatches.filter((b) => stages.has(b.stage))
|
|
|
+ if (params?.batchNo) list = list.filter((b) => b.batchNo.includes(params.batchNo!))
|
|
|
+ if (params?.stage) list = list.filter((b) => b.stage === params.stage)
|
|
|
+ return mockPaged(list, params?.pageNum, params?.pageSize)
|
|
|
+ }
|
|
|
+ return real.fetchInsuranceBatchesPage(params)
|
|
|
+}
|
|
|
+
|
|
|
+export function fetchInsuranceBatches(params?: { tab?: 'todo' | 'history' }) {
|
|
|
+ if (useMock()) {
|
|
|
+ return fetchInsuranceBatchesPage(params).then((p) => p.list)
|
|
|
}
|
|
|
return real.fetchInsuranceBatches(params)
|
|
|
}
|
|
|
|
|
|
/** 查询居保匹配结果;可按批次号 / 街镇 / 村居过滤 */
|
|
|
-export function fetchInsuranceResults(params?: {
|
|
|
+export function fetchInsuranceResultsPage(params?: {
|
|
|
batchId?: string
|
|
|
batchNo?: string
|
|
|
town?: string
|
|
|
village?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
}) {
|
|
|
if (useMock()) {
|
|
|
let list = [...mockPeople]
|
|
|
if (params?.batchNo) list = list.filter((p) => p.batchNo === params.batchNo)
|
|
|
if (params?.town) list = list.filter((p) => p.town === params.town)
|
|
|
if (params?.village) list = list.filter((p) => p.village === params.village)
|
|
|
- return delay(list)
|
|
|
+ return mockPaged(list, params?.pageNum, params?.pageSize)
|
|
|
+ }
|
|
|
+ return real.fetchInsuranceResultsPage(params)
|
|
|
+}
|
|
|
+
|
|
|
+export function fetchInsuranceResults(params?: {
|
|
|
+ batchId?: string
|
|
|
+ batchNo?: string
|
|
|
+ town?: string
|
|
|
+ village?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
+}) {
|
|
|
+ if (useMock()) {
|
|
|
+ return fetchInsuranceResultsPage(params).then((p) => p.list)
|
|
|
}
|
|
|
return real.fetchInsuranceResults(params)
|
|
|
}
|
|
|
@@ -684,10 +773,14 @@ export function fetchApprovals(params?: {
|
|
|
node?: string
|
|
|
/** 街镇(镇经发 / 分管领导仅看本镇) */
|
|
|
town?: string
|
|
|
+ village?: string
|
|
|
/** 统一批次号,如 202608 */
|
|
|
batchNo?: string
|
|
|
/** 业务类型包含关键字,如「月度批次」 */
|
|
|
bizTypeIncludes?: string
|
|
|
+ status?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
}) {
|
|
|
if (useMock()) {
|
|
|
let list = [...mockApprovals]
|
|
|
@@ -697,11 +790,13 @@ export function fetchApprovals(params?: {
|
|
|
}
|
|
|
if (params?.node) list = list.filter((a) => a.node === params.node)
|
|
|
if (params?.town) list = list.filter((a) => a.town === params.town)
|
|
|
+ if (params?.village) list = list.filter((a) => a.village === params.village)
|
|
|
if (params?.batchNo) list = list.filter((a) => a.batchNo === params.batchNo)
|
|
|
+ if (params?.status) list = list.filter((a) => a.status === params.status)
|
|
|
if (params?.bizTypeIncludes) {
|
|
|
list = list.filter((a) => a.bizType.includes(params.bizTypeIncludes!))
|
|
|
}
|
|
|
- return delay(list)
|
|
|
+ return mockPaged(list, params?.pageNum, params?.pageSize)
|
|
|
}
|
|
|
return real.fetchApprovals(params)
|
|
|
}
|
|
|
@@ -784,6 +879,21 @@ export function decideApproval(payload: {
|
|
|
return real.decideApproval(payload)
|
|
|
}
|
|
|
|
|
|
+export function decideApprovals(payload: {
|
|
|
+ ids: string[]
|
|
|
+ pass: boolean
|
|
|
+ opinion?: string
|
|
|
+ fileUrls?: string
|
|
|
+ retireQualifyType?: '有土地退养' | '无土地有资格' | '无资格'
|
|
|
+}) {
|
|
|
+ if (useMock()) {
|
|
|
+ return Promise.all(payload.ids.map((id) => decideApproval({ ...payload, id }))).then(() => ({
|
|
|
+ ok: true,
|
|
|
+ }))
|
|
|
+ }
|
|
|
+ return real.decideApprovals(payload)
|
|
|
+}
|
|
|
+
|
|
|
/* ========== 人员状态维护 ========== */
|
|
|
export function fetchStatusBatches() {
|
|
|
if (useMock()) {
|
|
|
@@ -852,6 +962,7 @@ export function updateStandard(payload: {
|
|
|
date: string
|
|
|
reason: string
|
|
|
rawId?: string
|
|
|
+ town?: string
|
|
|
}) {
|
|
|
if (useMock()) {
|
|
|
const row = mockStandards.find((s) => s.id === payload.id)
|
|
|
@@ -925,12 +1036,25 @@ export function applyPersonStatusAction(payload: {
|
|
|
}
|
|
|
|
|
|
/* ========== 特殊业务 ========== */
|
|
|
+export function fetchSpecialsPage(params?: {
|
|
|
+ town?: string
|
|
|
+ bizType?: string
|
|
|
+ approveStatus?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
+}) {
|
|
|
+ if (useMock()) {
|
|
|
+ let list = params?.town ? mockSpecials.filter((s) => s.town === params.town) : [...mockSpecials]
|
|
|
+ if (params?.bizType === 'FUNERAL') list = list.filter((s) => s.type === '丧葬补贴')
|
|
|
+ if (params?.bizType === 'REFUND') list = list.filter((s) => s.type === '多发退款')
|
|
|
+ return mockPaged(list, params?.pageNum, params?.pageSize)
|
|
|
+ }
|
|
|
+ return real.fetchSpecialsPage(params)
|
|
|
+}
|
|
|
+
|
|
|
export function fetchSpecials(params?: { town?: string }) {
|
|
|
if (useMock()) {
|
|
|
- const list = params?.town
|
|
|
- ? mockSpecials.filter((s) => s.town === params.town)
|
|
|
- : [...mockSpecials]
|
|
|
- return delay(list)
|
|
|
+ return fetchSpecialsPage(params).then((p) => p.list)
|
|
|
}
|
|
|
return real.fetchSpecials(params)
|
|
|
}
|
|
|
@@ -944,12 +1068,17 @@ export function fetchSpecialBizPerson(personnelId: string) {
|
|
|
return real.fetchSpecialBizPerson(personnelId)
|
|
|
}
|
|
|
|
|
|
-export function fetchDeaths(params?: { town?: string }) {
|
|
|
+export function fetchDeathsPage(params?: { town?: string; pageNum?: number; pageSize?: number }) {
|
|
|
if (useMock()) {
|
|
|
- const list = params?.town
|
|
|
- ? mockDeaths.filter((d) => d.town === params.town)
|
|
|
- : [...mockDeaths]
|
|
|
- return delay(list)
|
|
|
+ const list = params?.town ? mockDeaths.filter((d) => d.town === params.town) : [...mockDeaths]
|
|
|
+ return mockPaged(list, params?.pageNum, params?.pageSize)
|
|
|
+ }
|
|
|
+ return real.fetchDeathsPage(params)
|
|
|
+}
|
|
|
+
|
|
|
+export function fetchDeaths(params?: { town?: string; pageNum?: number; pageSize?: number }) {
|
|
|
+ if (useMock()) {
|
|
|
+ return fetchDeathsPage(params).then((p) => p.list)
|
|
|
}
|
|
|
return real.fetchDeaths(params)
|
|
|
}
|
|
|
@@ -1275,6 +1404,26 @@ function buildVillageMonthlyItem(b: VillageBatch): VillageMonthlyBatch {
|
|
|
}
|
|
|
|
|
|
/** 本镇各村月补贴清单批次(待提交/待审核/已审核/已出盘/已回盘) */
|
|
|
+export function fetchVillageMonthlyBatchesPage(params?: {
|
|
|
+ town?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
+}) {
|
|
|
+ if (useMock()) {
|
|
|
+ let list = mockVillageBatches.filter((b) => MONTHLY_LIST_STAGES.includes(b.stage))
|
|
|
+ if (params?.town) list = list.filter((b) => b.town === params.town)
|
|
|
+ const items = list.map(buildVillageMonthlyItem)
|
|
|
+ items.sort((a, b) => {
|
|
|
+ const ta = a.submittedAt || ''
|
|
|
+ const tb = b.submittedAt || ''
|
|
|
+ if (ta !== tb) return tb.localeCompare(ta)
|
|
|
+ return a.village.localeCompare(b.village)
|
|
|
+ })
|
|
|
+ return mockPaged(items, params?.pageNum, params?.pageSize)
|
|
|
+ }
|
|
|
+ return real.fetchVillageMonthlyBatchesPage(params)
|
|
|
+}
|
|
|
+
|
|
|
export function fetchVillageMonthlyBatches(town?: string) {
|
|
|
if (useMock()) {
|
|
|
let list = mockVillageBatches.filter((b) => MONTHLY_LIST_STAGES.includes(b.stage))
|
|
|
@@ -1450,10 +1599,21 @@ export function confirmVillageMonthlyReturn(payload: {
|
|
|
|
|
|
/* ========== 回盘信息确认 ========== */
|
|
|
/** 回盘批次列表(按批次号从新到旧) */
|
|
|
+export function fetchDisksPage(params?: { town?: string; pageNum?: number; pageSize?: number }) {
|
|
|
+ if (useMock()) {
|
|
|
+ const list = params?.town ? mockDisks.filter((d) => d.town === params.town) : [...mockDisks]
|
|
|
+ return mockPaged(
|
|
|
+ [...list].sort((a, b) => b.batchNo.localeCompare(a.batchNo)),
|
|
|
+ params?.pageNum,
|
|
|
+ params?.pageSize,
|
|
|
+ )
|
|
|
+ }
|
|
|
+ return real.fetchDisksPage(params)
|
|
|
+}
|
|
|
+
|
|
|
export function fetchDisks(town?: string) {
|
|
|
if (useMock()) {
|
|
|
- const list = town ? mockDisks.filter((d) => d.town === town) : [...mockDisks]
|
|
|
- return delay([...list].sort((a, b) => b.batchNo.localeCompare(a.batchNo)))
|
|
|
+ return fetchDisksPage({ town }).then((p) => p.list)
|
|
|
}
|
|
|
return real.fetchDisks(town)
|
|
|
}
|
|
|
@@ -1691,6 +1851,21 @@ function mTownVillageMatch(
|
|
|
}
|
|
|
|
|
|
/* ========== 告警 ========== */
|
|
|
+export function fetchAlertsPage(params?: {
|
|
|
+ town?: string
|
|
|
+ village?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
+}) {
|
|
|
+ if (useMock()) {
|
|
|
+ let list = [...mockAlerts]
|
|
|
+ if (params?.town) list = list.filter((a) => a.town === params.town)
|
|
|
+ if (params?.village) list = list.filter((a) => a.village === params.village)
|
|
|
+ return mockPaged(list, params?.pageNum, params?.pageSize)
|
|
|
+ }
|
|
|
+ return real.fetchAlertsPage(params)
|
|
|
+}
|
|
|
+
|
|
|
export function fetchAlerts() {
|
|
|
if (useMock()) return delay([...mockAlerts])
|
|
|
return real.fetchAlerts()
|
|
|
@@ -1773,6 +1948,11 @@ export function handleAlert(payload: HandleAlertPayload | string, result?: strin
|
|
|
if (data.town) person.town = data.town
|
|
|
if (data.village) person.village = data.village
|
|
|
if (a.type === '民政死亡比对') person.status = '死亡丧葬'
|
|
|
+ if (String(a.type || '').includes('退养资格驳回')) {
|
|
|
+ person.status = '待提交资格'
|
|
|
+ person.bizStatus = 'DRAFT'
|
|
|
+ person.retireQualifyType = undefined
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const role =
|
|
|
@@ -1799,6 +1979,27 @@ export function fetchReportBatches() {
|
|
|
return real.fetchReportBatches()
|
|
|
}
|
|
|
|
|
|
+export function fetchWorkbenchStats(params?: {
|
|
|
+ payMonth?: string
|
|
|
+ town?: string
|
|
|
+ village?: string
|
|
|
+ months?: number
|
|
|
+ roleKey?: string
|
|
|
+}) {
|
|
|
+ if (useMock()) {
|
|
|
+ return delay({
|
|
|
+ personnelCount: mockPeople.length,
|
|
|
+ withLandCount: mockPeople.filter((p) => p.retireQualifyType === '有土地退养').length,
|
|
|
+ withoutLandCount: mockPeople.filter((p) => p.retireQualifyType === '无土地有资格').length,
|
|
|
+ qualifiedCount: mockPeople.length,
|
|
|
+ monthAmount: 0,
|
|
|
+ townQualify: [],
|
|
|
+ villageCharts: [],
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return real.fetchWorkbenchStats(params)
|
|
|
+}
|
|
|
+
|
|
|
/* ========== 系统管理 ========== */
|
|
|
export function fetchAccounts() {
|
|
|
if (useMock()) return delay([...mockAccounts])
|
|
|
@@ -1810,6 +2011,37 @@ export function fetchOpLogs() {
|
|
|
return real.fetchOpLogs()
|
|
|
}
|
|
|
|
|
|
+export function fetchOpLogsPage(params?: {
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
+ operator?: string
|
|
|
+ operatorRole?: string
|
|
|
+ bizType?: string
|
|
|
+ action?: string
|
|
|
+ result?: string
|
|
|
+ operateTimeFrom?: number
|
|
|
+ operateTimeTo?: number
|
|
|
+}) {
|
|
|
+ const pageNum = params?.pageNum || 1
|
|
|
+ const pageSize = params?.pageSize || 10
|
|
|
+ if (useMock()) {
|
|
|
+ let list = [...mockLogs]
|
|
|
+ const op = params?.operator?.trim()
|
|
|
+ if (op) list = list.filter((r) => r.user.includes(op) || r.role.includes(op))
|
|
|
+ if (params?.result) list = list.filter((r) => r.result.includes(params.result!))
|
|
|
+ if (params?.bizType) list = list.filter((r) => r.module.includes(params.bizType!))
|
|
|
+ if (params?.action) list = list.filter((r) => r.action.includes(params.action!))
|
|
|
+ const start = (pageNum - 1) * pageSize
|
|
|
+ return delay({
|
|
|
+ list: list.slice(start, start + pageSize),
|
|
|
+ total: list.length,
|
|
|
+ pageNum,
|
|
|
+ pageSize,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return real.fetchOpLogsPage(params)
|
|
|
+}
|
|
|
+
|
|
|
export function factoryResetBusinessData() {
|
|
|
if (useMock()) return delay({ ok: true as const, destroyedTotal: 0, detail: {}, message: 'mock 跳过' })
|
|
|
return real.factoryResetBusinessData()
|
|
|
@@ -1849,8 +2081,10 @@ export function pageAdminBatches(params?: {
|
|
|
villageId?: string
|
|
|
batchLevel?: string
|
|
|
status?: string
|
|
|
+ pageNum?: number
|
|
|
+ pageSize?: number
|
|
|
}) {
|
|
|
- if (useMock()) return delay([])
|
|
|
+ if (useMock()) return delay({ list: [], total: 0, pageNum: 1, pageSize: 10 })
|
|
|
return real.pageAdminBatches(params)
|
|
|
}
|
|
|
|
|
|
@@ -1869,6 +2103,11 @@ export function deletePersonnelBatchAdmin(ids: string[]) {
|
|
|
return real.deletePersonnelBatchAdmin(ids)
|
|
|
}
|
|
|
|
|
|
+export function clearAllPersonnelAdmin() {
|
|
|
+ if (useMock()) return delay({ ok: true as const, successCount: 0, failCount: 0, message: '已清空 0 人' })
|
|
|
+ return real.clearAllPersonnelAdmin()
|
|
|
+}
|
|
|
+
|
|
|
export function updatePersonnelStatusAdmin(payload: {
|
|
|
personnelId: string
|
|
|
bizStatus: string
|
|
|
@@ -1980,6 +2219,15 @@ export function fetchLoginLogs(limit = 100) {
|
|
|
return real.fetchLoginLogs(limit)
|
|
|
}
|
|
|
|
|
|
+export function fetchLoginLogsPage(params?: { pageNum?: number; pageSize?: number }) {
|
|
|
+ const pageNum = params?.pageNum || 1
|
|
|
+ const pageSize = params?.pageSize || 10
|
|
|
+ if (useMock()) {
|
|
|
+ return delay({ list: [] as OpLog[], total: 0, pageNum, pageSize })
|
|
|
+ }
|
|
|
+ return real.fetchLoginLogsPage(params)
|
|
|
+}
|
|
|
+
|
|
|
export function recordLoginAudit(payload: {
|
|
|
username?: string
|
|
|
roleKey?: string
|