添加快手 Cloud 换绑角色功能

This commit is contained in:
yml
2026-05-30 11:23:52 +08:00
parent 681ff44cbc
commit 1c50569ea9
22 changed files with 1537 additions and 953 deletions
+98 -109
View File
@@ -1,177 +1,166 @@
import type { Request } from "express";
import { Router } from "express";
import type { Request } from 'express'
import { Router } from 'express'
import {
getAdminTaskDetail,
getAdminTasks,
} from "../../services/admin/admin-read-service.js";
import { closeAdminTask } from "../../services/admin/write/task-actions.js";
import { getAdminTaskDetail, getAdminTasks } from '../../services/admin/admin-read-service.js'
import { closeAdminTask } from '../../services/admin/write/task-actions.js'
import {
dispatchAdminTaskKuaishouCloudFulfillment,
prepareAdminTaskKuaishouCloudFulfillment,
rebindAdminTaskKuaishouCloudRole,
refreshAdminTaskKuaishouCloudRoleInfo,
returnNumberAdminTaskKuaishouCloudFulfillment,
} from "../../services/admin/write/kuaishou-cloud-actions.js";
import {
createJsonHandler,
requireAdminRoles,
} from "./session.js";
} from '../../services/admin/write/kuaishou-cloud-actions.js'
import { createJsonHandler, requireAdminRoles } from './session.js'
import type {
AdminTaskKuaishouCloudDispatchRouteBody,
AdminTaskRouteParams,
AdminTaskRouteQuery,
} from "../../types/admin/route-inputs.js";
import type { AdminTaskActionResponse } from "../../types/admin/write-models.js";
} from '../../types/admin/route-inputs.js'
import type { AdminTaskActionResponse } from '../../types/admin/write-models.js'
const router = Router();
const router = Router()
function getTaskId(req: Request): string {
return String((req.params as AdminTaskRouteParams).taskId || "");
return String((req.params as AdminTaskRouteParams).taskId || '')
}
router.get(
"/tasks",
'/tasks',
createJsonHandler(
(req) =>
getAdminTasks(req.query as AdminTaskRouteQuery, req.adminSession || null),
(req) => getAdminTasks(req.query as AdminTaskRouteQuery, req.adminSession || null),
{
successMessage: "ok",
errorMessage: "读取任务列表失败",
scope: "[admin/tasks]",
}
)
);
successMessage: 'ok',
errorMessage: '读取任务列表失败',
scope: '[admin/tasks]',
},
),
)
router.get(
"/tasks/:taskId",
createJsonHandler(
(req) => getAdminTaskDetail(getTaskId(req), req.adminSession || null),
{
successMessage: "ok",
errorMessage: "读取任务详情失败",
scope: "[admin/tasks/:taskId]",
}
)
);
'/tasks/:taskId',
createJsonHandler((req) => getAdminTaskDetail(getTaskId(req), req.adminSession || null), {
successMessage: 'ok',
errorMessage: '读取任务详情失败',
scope: '[admin/tasks/:taskId]',
}),
)
router.post(
"/tasks/:taskId/close",
requireAdminRoles(["admin", "operator", "support"]),
createJsonHandler(
(req) => closeAdminTask(getTaskId(req), req.adminSession || null),
{
successMessage: "任务已关闭",
errorMessage: "关闭任务失败",
scope: "[admin/tasks/:taskId/close]",
audit: (req, data) => buildTaskAudit("task_closed", req, data),
}
)
);
'/tasks/:taskId/close',
requireAdminRoles(['admin', 'operator', 'support']),
createJsonHandler((req) => closeAdminTask(getTaskId(req), req.adminSession || null), {
successMessage: '任务已关闭',
errorMessage: '关闭任务失败',
scope: '[admin/tasks/:taskId/close]',
audit: (req, data) => buildTaskAudit('task_closed', req, data),
}),
)
router.post(
"/tasks/:taskId/kuaishou-cloud/prepare",
requireAdminRoles(["admin", "operator"]),
'/tasks/:taskId/kuaishou-cloud/prepare',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(
(req) =>
prepareAdminTaskKuaishouCloudFulfillment(
getTaskId(req),
req.adminSession || null
),
(req) => prepareAdminTaskKuaishouCloudFulfillment(getTaskId(req), req.adminSession || null),
{
successMessage: "绑定资源已准备完成",
errorMessage: "准备绑定资源失败",
scope: "[admin/tasks/:taskId/kuaishou-cloud/prepare]",
audit: (req, data) => buildTaskAudit("task_kuaishou_cloud_prepare", req, data),
}
)
);
successMessage: '绑定资源已准备完成',
errorMessage: '准备绑定资源失败',
scope: '[admin/tasks/:taskId/kuaishou-cloud/prepare]',
audit: (req, data) => buildTaskAudit('task_kuaishou_cloud_prepare', req, data),
},
),
)
router.post(
"/tasks/:taskId/kuaishou-cloud/refresh-role-info",
requireAdminRoles(["admin", "operator", "support"]),
'/tasks/:taskId/kuaishou-cloud/refresh-role-info',
requireAdminRoles(['admin', 'operator', 'support']),
createJsonHandler(
(req) =>
refreshAdminTaskKuaishouCloudRoleInfo(
getTaskId(req),
req.adminSession || null
),
(req) => refreshAdminTaskKuaishouCloudRoleInfo(getTaskId(req), req.adminSession || null),
{
successMessage: "角色信息已刷新",
errorMessage: "刷新角色信息失败",
scope: "[admin/tasks/:taskId/kuaishou-cloud/refresh-role-info]",
audit: (req, data) =>
buildTaskAudit("task_kuaishou_cloud_role_info_refreshed", req, data),
}
)
);
successMessage: '角色信息已刷新',
errorMessage: '刷新角色信息失败',
scope: '[admin/tasks/:taskId/kuaishou-cloud/refresh-role-info]',
audit: (req, data) => buildTaskAudit('task_kuaishou_cloud_role_info_refreshed', req, data),
},
),
)
router.post(
"/tasks/:taskId/kuaishou-cloud/dispatch",
requireAdminRoles(["admin", "operator"]),
'/tasks/:taskId/kuaishou-cloud/rebind-role',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(
(req) => rebindAdminTaskKuaishouCloudRole(getTaskId(req), req.adminSession || null),
{
successMessage: '角色换绑资源已准备完成',
errorMessage: '换绑角色失败',
scope: '[admin/tasks/:taskId/kuaishou-cloud/rebind-role]',
audit: (req, data) => buildTaskAudit('task_kuaishou_cloud_rebind_role', req, data),
},
),
)
router.post(
'/tasks/:taskId/kuaishou-cloud/dispatch',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(
(req) =>
dispatchAdminTaskKuaishouCloudFulfillment(
getTaskId(req),
req.body as AdminTaskKuaishouCloudDispatchRouteBody,
req.adminSession || null
req.adminSession || null,
),
{
successMessage: "已完成绑定确认并发货",
errorMessage: "执行发货失败",
scope: "[admin/tasks/:taskId/kuaishou-cloud/dispatch]",
successMessage: '已完成绑定确认并发货',
errorMessage: '执行发货失败',
scope: '[admin/tasks/:taskId/kuaishou-cloud/dispatch]',
audit: (req, data) => {
const result = data as AdminTaskActionResponse;
const body = req.body as AdminTaskKuaishouCloudDispatchRouteBody;
const result = data as AdminTaskActionResponse
const body = req.body as AdminTaskKuaishouCloudDispatchRouteBody
return {
action: "task_kuaishou_cloud_dispatch",
targetType: "task",
action: 'task_kuaishou_cloud_dispatch',
targetType: 'task',
targetId: String(getTaskId(req)),
data: {
taskId: result.task.taskId,
taskNo: result.task.taskNo,
status: result.task.status,
deliveryStatus: result.task.deliveryStatus,
ticketCodeProvided: Boolean(String(body.ticketCode || "").trim()),
ticketCodeProvided: Boolean(String(body.ticketCode || '').trim()),
},
};
}
},
}
)
);
},
),
)
router.post(
"/tasks/:taskId/kuaishou-cloud/return-number",
requireAdminRoles(["admin", "operator"]),
'/tasks/:taskId/kuaishou-cloud/return-number',
requireAdminRoles(['admin', 'operator']),
createJsonHandler(
(req) =>
returnNumberAdminTaskKuaishouCloudFulfillment(
getTaskId(req),
req.adminSession || null
),
returnNumberAdminTaskKuaishouCloudFulfillment(getTaskId(req), req.adminSession || null),
{
successMessage: "号码已退还",
errorMessage: "退还号码失败",
scope: "[admin/tasks/:taskId/kuaishou-cloud/return-number]",
audit: (req, data) =>
buildTaskAudit("task_kuaishou_cloud_return_number", req, data),
}
)
);
successMessage: '号码已退还',
errorMessage: '退还号码失败',
scope: '[admin/tasks/:taskId/kuaishou-cloud/return-number]',
audit: (req, data) => buildTaskAudit('task_kuaishou_cloud_return_number', req, data),
},
),
)
function buildTaskAudit(action: string, req: Request, data: unknown) {
const result = data as AdminTaskActionResponse;
const result = data as AdminTaskActionResponse
return {
action,
targetType: "task",
targetType: 'task',
targetId: String(getTaskId(req)),
data: {
taskId: result.task.taskId,
taskNo: result.task.taskNo,
status: result.task.status,
},
};
}
}
export default router;
export default router
+55 -54
View File
@@ -1,88 +1,89 @@
import { Router } from "express";
import { Router } from 'express'
import { createRateLimitMiddleware, getParamRateLimitKey } from "../middleware/rate-limit.js";
import { createRateLimitMiddleware, getParamRateLimitKey } from '../middleware/rate-limit.js'
import {
confirmKuaishouCloudClaimRole,
getKuaishouCloudClaimDetail,
getKuaishouCloudClaimGuideAssetPath,
rebindKuaishouCloudClaimRole,
redeemKuaishouCloudClaim,
verifyKuaishouCloudClaimTicket,
} from "../services/claim/kuaishou-cloud-claim-service.js";
import {
buildNotFoundPayload,
createRouteFileHandler,
createRouteHandler,
} from "../utils/http.js";
} from '../services/claim/kuaishou-cloud-claim-service.js'
import { buildNotFoundPayload, createRouteFileHandler, createRouteHandler } from '../utils/http.js'
const router = Router();
const router = Router()
const claimReadRateLimit = createRateLimitMiddleware({
scope: "claim:read",
scope: 'claim:read',
windowMs: 60_000,
max: 120,
key: getParamRateLimitKey("token"),
});
key: getParamRateLimitKey('token'),
})
const claimWriteRateLimit = createRateLimitMiddleware({
scope: "claim:write",
scope: 'claim:write',
windowMs: 60_000,
max: 30,
key: getParamRateLimitKey("token"),
});
key: getParamRateLimitKey('token'),
})
router.get(
"/:token",
'/:token',
claimReadRateLimit,
createRouteHandler((req) => getKuaishouCloudClaimDetail(req.params.token), {
errorMessage: "查询快手领取详情失败",
scope: "[claims/:token]",
})
);
errorMessage: '查询快手领取详情失败',
scope: '[claims/:token]',
}),
)
router.post(
"/:token/kuaishou-cloud/verify-ticket",
'/:token/kuaishou-cloud/verify-ticket',
claimWriteRateLimit,
createRouteHandler(
(req) => verifyKuaishouCloudClaimTicket(req.params.token, req.body),
{
successMessage: "核销码校验成功",
errorMessage: "校验核销码失败",
scope: "[claims/:token/kuaishou-cloud/verify-ticket]",
}
)
);
createRouteHandler((req) => verifyKuaishouCloudClaimTicket(req.params.token, req.body), {
successMessage: '核销码校验成功',
errorMessage: '校验核销码失败',
scope: '[claims/:token/kuaishou-cloud/verify-ticket]',
}),
)
router.post(
"/:token/kuaishou-cloud/confirm-role",
'/:token/kuaishou-cloud/confirm-role',
claimWriteRateLimit,
createRouteHandler((req) => confirmKuaishouCloudClaimRole(req.params.token), {
successMessage: "角色已确认",
errorMessage: "确认角色失败",
scope: "[claims/:token/kuaishou-cloud/confirm-role]",
})
);
successMessage: '角色已确认',
errorMessage: '确认角色失败',
scope: '[claims/:token/kuaishou-cloud/confirm-role]',
}),
)
router.post(
"/:token/kuaishou-cloud/redeem",
'/:token/kuaishou-cloud/rebind-role',
claimWriteRateLimit,
createRouteHandler((req) => rebindKuaishouCloudClaimRole(req.params.token), {
successMessage: '角色换绑资源已准备完成',
errorMessage: '换绑角色失败',
scope: '[claims/:token/kuaishou-cloud/rebind-role]',
}),
)
router.post(
'/:token/kuaishou-cloud/redeem',
claimWriteRateLimit,
createRouteHandler((req) => redeemKuaishouCloudClaim(req.params.token), {
successMessage: "兑换请求已提交",
errorMessage: "兑换失败",
scope: "[claims/:token/kuaishou-cloud/redeem]",
})
);
successMessage: '兑换请求已提交',
errorMessage: '兑换失败',
scope: '[claims/:token/kuaishou-cloud/redeem]',
}),
)
router.get(
"/assets/kuaishou-cloud/:filename",
createRouteFileHandler(
(req) => getKuaishouCloudClaimGuideAssetPath(req.params.filename),
{
errorMessage: "读取指引图片失败",
scope: "[claims/assets/kuaishou-cloud/:filename]",
}
)
);
'/assets/kuaishou-cloud/:filename',
createRouteFileHandler((req) => getKuaishouCloudClaimGuideAssetPath(req.params.filename), {
errorMessage: '读取指引图片失败',
scope: '[claims/assets/kuaishou-cloud/:filename]',
}),
)
router.use((req, res) => {
res.status(404).json(buildNotFoundPayload(req));
});
res.status(404).json(buildNotFoundPayload(req))
})
export default router;
export default router