175 lines
7.7 KiB
TypeScript
175 lines
7.7 KiB
TypeScript
import { z } from "zod";
|
|
|
|
const commandBaseSchema = z.object({
|
|
commandId: z.string().trim().min(1, "请输入 Command ID").max(120, "Command ID 不能超过 120 个字符"),
|
|
reason: z.string().trim().max(200, "原因不能超过 200 个字符").optional().default(""),
|
|
});
|
|
|
|
const commandContactSchema = z.object({
|
|
commandId: z.string().trim().min(1, "请输入 Command ID").max(120, "Command ID 不能超过 120 个字符"),
|
|
contact: z.string().trim().max(128, "联系方式不能超过 128 个字符").optional().default(""),
|
|
reason: z.string().trim().max(200, "原因不能超过 200 个字符").optional().default(""),
|
|
});
|
|
|
|
const userIdSchema = z.coerce.number().int().positive("请输入有效用户短 ID");
|
|
const optionalUserIdSchema = z.preprocess(
|
|
(value) => {
|
|
if (value === null || value === undefined) {
|
|
return 0;
|
|
}
|
|
if (typeof value === "string" && value.trim() === "") {
|
|
return 0;
|
|
}
|
|
return value;
|
|
},
|
|
z.coerce.number().int().min(0, "请输入有效用户短 ID"),
|
|
);
|
|
const regionIdSchema = z.coerce.number().int().positive("请输入有效区域 ID");
|
|
const sortOrderSchema = z.coerce.number().int().min(0, "排序不能小于 0").default(0);
|
|
const optionalTextSchema = (max: number, message: string) => z.string().trim().max(max, message).optional().default("");
|
|
const codeSchema = (label: string) => z.string().trim().min(1, `请输入${label}`).max(40, `${label}不能超过 40 个字符`);
|
|
const countryCodesSchema = z.array(z.string()).transform((values, ctx) => {
|
|
const countries = values.map((item) => item.trim().toUpperCase()).filter(Boolean);
|
|
if (new Set(countries).size !== countries.length) {
|
|
ctx.addIssue({ code: "custom", message: "国家码不能重复" });
|
|
}
|
|
return countries;
|
|
});
|
|
const retiredRegionCodes = new Set([
|
|
"AUSTRALIA AND NEW ZEALAND",
|
|
"CARIBBEAN",
|
|
"MELANESIA",
|
|
"MICRONESIA",
|
|
"POLYNESIA",
|
|
"SOUTHERN AFRICA",
|
|
"UNSPECIFIED",
|
|
]);
|
|
const requiredCountryCodesSchema = countryCodesSchema.superRefine((countries, ctx) => {
|
|
if (!countries.length) {
|
|
ctx.addIssue({ code: "custom", message: "请选择国家码" });
|
|
}
|
|
});
|
|
const regionBaseSchema = z
|
|
.object({
|
|
countries: countryCodesSchema,
|
|
name: z.string().trim().min(1, "请输入区域名称").max(80, "区域名称不能超过 80 个字符"),
|
|
regionCode: codeSchema("区域编码").transform((value) => value.toUpperCase()),
|
|
sortOrder: sortOrderSchema,
|
|
})
|
|
.superRefine((value, ctx) => {
|
|
if (retiredRegionCodes.has(value.regionCode)) {
|
|
ctx.addIssue({ code: "custom", message: "该区域已移除", path: ["regionCode"] });
|
|
}
|
|
if (value.regionCode !== "GLOBAL" && !value.countries.length) {
|
|
ctx.addIssue({ code: "custom", message: "请选择国家码", path: ["countries"] });
|
|
}
|
|
if (value.regionCode === "GLOBAL" && value.countries.length) {
|
|
ctx.addIssue({ code: "custom", message: "GLOBAL 区域不需要选择国家", path: ["countries"] });
|
|
}
|
|
});
|
|
|
|
export const createBDLeaderSchema = commandContactSchema.extend({
|
|
positionAlias: optionalTextSchema(64, "职位别名不能超过 64 个字符"),
|
|
targetUserId: userIdSchema,
|
|
});
|
|
|
|
export const createBDSchema = commandBaseSchema.extend({
|
|
parentLeaderUserId: optionalUserIdSchema,
|
|
targetUserId: userIdSchema,
|
|
});
|
|
|
|
export const bdStatusSchema = commandBaseSchema.extend({
|
|
status: z.string().trim().min(1, "请输入状态").max(40, "状态不能超过 40 个字符"),
|
|
targetType: z.enum(["bd", "leader"]),
|
|
targetUserId: userIdSchema,
|
|
});
|
|
|
|
export const createCoinSellerSchema = commandContactSchema.extend({
|
|
targetUserId: userIdSchema,
|
|
});
|
|
|
|
export const coinSellerStatusSchema = commandContactSchema.extend({
|
|
status: z.enum(["active", "disabled"]),
|
|
targetUserId: userIdSchema,
|
|
});
|
|
|
|
export const coinSellerStockCreditSchema = z
|
|
.object({
|
|
coinAmount: z.coerce.number().int().positive("请输入充值金币"),
|
|
commandId: z.string().trim().min(1, "请输入 Command ID").max(120, "Command ID 不能超过 120 个字符"),
|
|
reason: z.string().trim().max(512, "原因不能超过 512 个字符").optional().default(""),
|
|
rechargeAmount: z.string().trim().max(32, "充值金额不能超过 32 个字符").optional().default(""),
|
|
type: z.enum(["usdt_purchase", "coin_compensation"]),
|
|
})
|
|
.superRefine((value, ctx) => {
|
|
if (value.type === "usdt_purchase") {
|
|
if (!/^(0|[1-9]\d*)(\.\d{1,6})?$/.test(value.rechargeAmount) || Number(value.rechargeAmount) <= 0) {
|
|
ctx.addIssue({ code: "custom", message: "请输入最多 6 位小数的 USDT 金额", path: ["rechargeAmount"] });
|
|
}
|
|
return;
|
|
}
|
|
if (value.rechargeAmount) {
|
|
ctx.addIssue({ code: "custom", message: "金币补偿不能提交充值金额", path: ["rechargeAmount"] });
|
|
}
|
|
});
|
|
|
|
export const createAgencySchema = commandBaseSchema.extend({
|
|
joinEnabled: z.boolean().default(true),
|
|
name: z.string().trim().min(1, "请输入 Agency 名称").max(80, "Agency 名称不能超过 80 个字符"),
|
|
ownerUserId: userIdSchema,
|
|
parentBdUserId: optionalUserIdSchema,
|
|
});
|
|
|
|
export const agencyCloseSchema = commandBaseSchema.extend({
|
|
agencyId: z.coerce.number().int().positive("请输入有效 Agency ID"),
|
|
});
|
|
|
|
export const agencyJoinEnabledSchema = commandBaseSchema.extend({
|
|
agencyId: z.coerce.number().int().positive("请输入有效 Agency ID"),
|
|
joinEnabled: z.boolean().default(true),
|
|
});
|
|
|
|
export const countryCreateSchema = z.object({
|
|
countryCode: z
|
|
.string()
|
|
.trim()
|
|
.regex(/^[A-Za-z]{2,3}$/, "国家码必须是 2-3 位字母")
|
|
.transform((value) => value.toUpperCase()),
|
|
countryDisplayName: z.string().trim().min(1, "请输入展示名称").max(80, "展示名称不能超过 80 个字符"),
|
|
countryName: z.string().trim().min(1, "请输入国家名称").max(80, "国家名称不能超过 80 个字符"),
|
|
enabled: z.boolean().default(true),
|
|
flag: optionalTextSchema(16, "国旗不能超过 16 个字符"),
|
|
isoAlpha3: optionalTextSchema(8, "ISO Alpha-3 不能超过 8 个字符").transform((value) => value.toUpperCase()),
|
|
isoNumeric: optionalTextSchema(8, "ISO Numeric 不能超过 8 个字符"),
|
|
phoneCountryCode: optionalTextSchema(16, "电话区号不能超过 16 个字符"),
|
|
sortOrder: sortOrderSchema,
|
|
});
|
|
|
|
export const countryUpdateSchema = countryCreateSchema.omit({
|
|
countryCode: true,
|
|
enabled: true,
|
|
});
|
|
|
|
export const regionCreateSchema = regionBaseSchema;
|
|
|
|
export const regionUpdateSchema = regionBaseSchema;
|
|
|
|
export const regionCountriesSchema = z.object({
|
|
countries: requiredCountryCodesSchema,
|
|
});
|
|
|
|
export type CreateBDLeaderForm = z.infer<typeof createBDLeaderSchema>;
|
|
export type CreateBDForm = z.infer<typeof createBDSchema>;
|
|
export type BDStatusForm = z.infer<typeof bdStatusSchema>;
|
|
export type CreateCoinSellerForm = z.infer<typeof createCoinSellerSchema>;
|
|
export type CoinSellerStatusForm = z.infer<typeof coinSellerStatusSchema>;
|
|
export type CoinSellerStockCreditForm = z.infer<typeof coinSellerStockCreditSchema>;
|
|
export type CreateAgencyForm = z.infer<typeof createAgencySchema>;
|
|
export type AgencyCloseForm = z.infer<typeof agencyCloseSchema>;
|
|
export type AgencyJoinEnabledForm = z.infer<typeof agencyJoinEnabledSchema>;
|
|
export type CountryCreateForm = z.infer<typeof countryCreateSchema>;
|
|
export type CountryUpdateForm = z.infer<typeof countryUpdateSchema>;
|
|
export type RegionCreateForm = z.infer<typeof regionCreateSchema>;
|
|
export type RegionUpdateForm = z.infer<typeof regionUpdateSchema>;
|
|
export type RegionCountriesForm = z.infer<typeof regionCountriesSchema>;
|