优化客服权限
This commit is contained in:
@@ -81,7 +81,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/kuaishou-industry/vouchers/check-available',
|
||||
requireAdminRoles(['admin', 'operator']),
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
checkAdminKuaishouIndustryVoucherAvailable(
|
||||
@@ -98,7 +98,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/kuaishou-industry/vouchers/reverse',
|
||||
requireAdminRoles(['admin', 'operator']),
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
reverseAdminKuaishouIndustryVoucher(req.body as AdminKuaishouIndustryVoucherReverseRouteBody),
|
||||
@@ -113,7 +113,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/kuaishou-industry/vouchers/consume',
|
||||
requireAdminRoles(['admin', 'operator']),
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
consumeAdminKuaishouIndustryVoucherByCode(
|
||||
@@ -130,7 +130,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/kuaishou-industry/vouchers/resend-code',
|
||||
requireAdminRoles(['admin', 'operator']),
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
resendAdminKuaishouIndustryVoucherCode(
|
||||
|
||||
@@ -34,7 +34,7 @@ router.get('/orders/:orderId', createJsonHandler(
|
||||
|
||||
router.post(
|
||||
'/orders/:orderId/kuaishou-industry/resend-code',
|
||||
requireAdminRoles(['admin', 'operator']),
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
resendAdminOrderKuaishouIndustryVoucherCodes(
|
||||
|
||||
@@ -10,9 +10,9 @@ import fulfillmentRoutingRouter from "./platform-config/fulfillment-routing.js";
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.use("/platform-config", kuaishouIndustryRouter);
|
||||
router.use("/platform-config", requireAdminRoles(["admin"]));
|
||||
router.use("/platform-config", notificationsRouter);
|
||||
router.use("/platform-config", kuaishouIndustryRouter);
|
||||
router.use("/platform-config", kuaishouFeifeiRouter);
|
||||
router.use("/platform-config", ninetyoneRouter);
|
||||
router.use("/platform-config", fulfillmentRoutingRouter);
|
||||
|
||||
@@ -10,13 +10,14 @@ import type {
|
||||
AdminKuaishouIndustryAuthorizationCodeRouteBody,
|
||||
AdminKuaishouIndustrySourceConfigRouteBody,
|
||||
} from '../../../types/admin/route-inputs.js'
|
||||
import { createJsonHandler } from '../session.js'
|
||||
import { createJsonHandler, requireAdminRoles } from '../session.js'
|
||||
import type { JsonRecord } from '../../../types/json.js'
|
||||
|
||||
const router = Router()
|
||||
|
||||
router.get(
|
||||
'/kuaishou-industry-source',
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(() => getAdminKuaishouIndustrySourceConfig(), {
|
||||
successMessage: 'ok',
|
||||
errorMessage: '读取快手行业电子凭证配置失败',
|
||||
@@ -26,6 +27,7 @@ router.get(
|
||||
|
||||
router.post(
|
||||
'/kuaishou-industry-source',
|
||||
requireAdminRoles(['admin']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
updateAdminKuaishouIndustrySourceConfig(
|
||||
@@ -57,6 +59,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/kuaishou-industry-source/refresh-token',
|
||||
requireAdminRoles(['admin']),
|
||||
createJsonHandler((req) => refreshAdminKuaishouIndustryAccessToken(req.body as JsonRecord), {
|
||||
successMessage: '快手行业电子凭证 accessToken 已刷新',
|
||||
errorMessage: '刷新快手行业电子凭证 accessToken 失败',
|
||||
@@ -80,6 +83,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/kuaishou-industry-source/exchange-code',
|
||||
requireAdminRoles(['admin']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
exchangeAdminKuaishouIndustryAuthorizationCode(
|
||||
|
||||
@@ -149,7 +149,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/tasks/:taskId/kuaishou-industry/resend-code',
|
||||
requireAdminRoles(['admin', 'operator']),
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
resendAdminTaskKuaishouIndustryVoucherCode(getTaskId(req), req.adminSession || null),
|
||||
@@ -164,7 +164,7 @@ router.post(
|
||||
|
||||
router.post(
|
||||
'/tasks/:taskId/kuaishou-industry/consume',
|
||||
requireAdminRoles(['admin', 'operator']),
|
||||
requireAdminRoles(['admin', 'operator', 'support']),
|
||||
createJsonHandler(
|
||||
(req) =>
|
||||
consumeAdminTaskKuaishouIndustryVoucher(
|
||||
|
||||
@@ -154,7 +154,7 @@ export async function getAdminOrderDetail(
|
||||
kuaishouIndustryVouchers: kuaishouIndustryVouchers.map(mapAdminKuaishouIndustryVoucher),
|
||||
operations: {
|
||||
canResendKuaishouIndustryVoucherCode:
|
||||
viewerContext.canManageTaskLifecycle && kuaishouIndustryVouchers.length > 0,
|
||||
viewerContext.canOperateKuaishouIndustryVoucher && kuaishouIndustryVouchers.length > 0,
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -360,9 +360,9 @@ export async function getAdminTaskDetail(
|
||||
String(task.executor_key || '').trim() === 'kuaishou_ct_assisted' &&
|
||||
canReturnKuaishouCloudFulfillmentStatus(task.task_status),
|
||||
canResendKuaishouIndustryVoucherCode:
|
||||
viewerContext.canManageTaskLifecycle && hasKuaishouIndustryVoucher,
|
||||
viewerContext.canOperateKuaishouIndustryVoucher && hasKuaishouIndustryVoucher,
|
||||
canConsumeKuaishouIndustryVoucher:
|
||||
viewerContext.canManageTaskLifecycle &&
|
||||
viewerContext.canOperateKuaishouIndustryVoucher &&
|
||||
hasKuaishouIndustryVoucher &&
|
||||
kuaishouIndustryVoucherStatus !== 'CONSUMED' &&
|
||||
kuaishouIndustryVoucherSendCallbackStatus === 'success',
|
||||
|
||||
@@ -39,6 +39,13 @@ test('canViewerCloseTask allows support to close active task but not redeemed ta
|
||||
assert.equal(canViewerCloseTask({ task_status: 'redeemed' }, viewerContext), false)
|
||||
})
|
||||
|
||||
test('createAdminViewerContext lets support operate vouchers without lifecycle permissions', () => {
|
||||
const viewerContext = createAdminViewerContext({ role: 'support' })
|
||||
|
||||
assert.equal(viewerContext.canOperateKuaishouIndustryVoucher, true)
|
||||
assert.equal(viewerContext.canManageTaskLifecycle, false)
|
||||
})
|
||||
|
||||
test('mapKuaishouCloudFulfillmentContext exposes cloud account display labels', () => {
|
||||
const flow = mapKuaishouCloudFulfillmentContext(
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ export type AdminViewerContext = {
|
||||
canViewSensitiveTaskData: boolean
|
||||
canManageTaskLifecycle: boolean
|
||||
canOperateAssistedTask: boolean
|
||||
canOperateKuaishouIndustryVoucher: boolean
|
||||
}
|
||||
|
||||
type RedeemResolutionAttempt = {
|
||||
@@ -370,6 +371,7 @@ export function createAdminViewerContext(
|
||||
canViewSensitiveTaskData: role === 'admin' || role === 'operator',
|
||||
canManageTaskLifecycle: role === 'admin' || role === 'operator',
|
||||
canOperateAssistedTask: role === 'admin' || role === 'operator' || role === 'support',
|
||||
canOperateKuaishouIndustryVoucher: role === 'admin' || role === 'operator' || role === 'support',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,7 +369,7 @@ export async function resendAdminTaskKuaishouIndustryVoucherCode(
|
||||
const now = nowIso()
|
||||
const viewerContext = createAdminViewerContext(session)
|
||||
|
||||
if (!viewerContext.canManageTaskLifecycle) {
|
||||
if (!viewerContext.canOperateKuaishouIndustryVoucher) {
|
||||
throw createHttpError('当前账号没有权限重发电子凭证发码回调', {
|
||||
statusCode: 403,
|
||||
errorCode: 'admin_task_kuaishou_industry_resend_forbidden',
|
||||
@@ -446,7 +446,7 @@ export async function resendAdminOrderKuaishouIndustryVoucherCodes(
|
||||
const viewerContext = createAdminViewerContext(session)
|
||||
const now = nowIso()
|
||||
|
||||
if (!viewerContext.canManageTaskLifecycle) {
|
||||
if (!viewerContext.canOperateKuaishouIndustryVoucher) {
|
||||
throw createHttpError('当前账号没有权限重发电子凭证发码回调', {
|
||||
statusCode: 403,
|
||||
errorCode: 'admin_order_kuaishou_industry_resend_forbidden',
|
||||
@@ -519,7 +519,7 @@ export async function consumeAdminTaskKuaishouIndustryVoucher(
|
||||
const now = nowIso()
|
||||
const viewerContext = createAdminViewerContext(session)
|
||||
|
||||
if (!viewerContext.canManageTaskLifecycle) {
|
||||
if (!viewerContext.canOperateKuaishouIndustryVoucher) {
|
||||
throw createHttpError('当前账号没有权限执行电子凭证核销', {
|
||||
statusCode: 403,
|
||||
errorCode: 'admin_task_kuaishou_industry_consume_forbidden',
|
||||
|
||||
Reference in New Issue
Block a user