merge: 同步 upstream/main 新功能到定制版本

- feat: Add slider verification code (bd67997)
- fix bug: Inventory cannot be zero (1f7a6ee)
- fix: resolve merge conflicts and lint errors
This commit is contained in:
2026-03-23 21:50:10 -07:00
parent 3806264343
commit d6616c5859
63 changed files with 3111 additions and 1130 deletions
+4 -2
View File
@@ -53,11 +53,13 @@ export function DatePicker({
)}
variant="outline"
>
<span className="truncate">{value ? intlFormat(value) : <span>{placeholder}</span>}</span>
<span className="truncate">
{value ? intlFormat(value) : <span>{placeholder}</span>}
</span>
<div className="flex items-center gap-2">
{value && (
<span
className="flex items-center cursor-pointer"
className="flex cursor-pointer items-center"
onClick={handleClear}
onMouseDown={handleClear}
role="button"
+8 -5
View File
@@ -70,6 +70,13 @@ export function EnhancedInput<T = string>({
let inputValue = e.target.value;
if (props.type === "number") {
if (inputValue === "0") {
setValue("0");
setInternalValue(0);
onValueChange?.(processValue(0));
return;
}
if (
/^-?\d*\.?\d*$/.test(inputValue) ||
inputValue === "-" ||
@@ -105,11 +112,7 @@ export function EnhancedInput<T = string>({
};
const handleBlur = () => {
if (
props.type === "number" &&
value !== "" &&
(value === "-" || value === ".")
) {
if (props.type === "number" && value && (value === "-" || value === ".")) {
setValue("");
setInternalValue("");
onValueBlur?.("" as T);
+54
View File
@@ -2,6 +2,42 @@
/* eslint-disable */
import request from "@workspace/ui/lib/request";
/** Admin login POST /v1/auth/admin/login */
export async function adminLogin(
body: API.UserLoginRequest,
options?: { [key: string]: any }
) {
return request<API.Response & { data?: API.LoginResponse }>(
`${import.meta.env.VITE_API_PREFIX || ""}/v1/auth/admin/login`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
data: body,
...(options || {}),
}
);
}
/** Admin reset password POST /v1/auth/admin/reset */
export async function adminResetPassword(
body: API.ResetPasswordRequest,
options?: { [key: string]: any }
) {
return request<API.Response>(
`${import.meta.env.VITE_API_PREFIX || ""}/v1/auth/admin/reset`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
data: body,
...(options || {}),
}
);
}
/** Generate captcha POST /v1/auth/admin/captcha/generate */
export async function adminGenerateCaptcha(options?: { [key: string]: any }) {
return request<API.Response & { data?: API.GenerateCaptchaResponse }>(
@@ -15,3 +51,21 @@ export async function adminGenerateCaptcha(options?: { [key: string]: any }) {
}
);
}
/** Verify slider captcha POST /v1/auth/admin/captcha/slider/verify */
export async function adminVerifyCaptchaSlider(
body: { id: string; x: number; y: number; trail: string },
options?: { [key: string]: any }
) {
return request<API.Response & { data?: API.SliderVerifyCaptchaResponse }>(
`${import.meta.env.VITE_API_PREFIX || ""}/v1/auth/admin/captcha/slider/verify`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
data: body,
...(options || {}),
}
);
}
+7 -5
View File
@@ -180,10 +180,12 @@ export async function updateSubscribeMapping(
}
/** Get subscribe group mapping GET /v1/admin/group/subscribe/mapping */
export async function getSubscribeGroupMapping(
options?: { [key: string]: any }
) {
return request<API.Response & { data?: API.GetSubscribeGroupMappingResponse }>(
export async function getSubscribeGroupMapping(options?: {
[key: string]: any;
}) {
return request<
API.Response & { data?: API.GetSubscribeGroupMappingResponse }
>(
`${import.meta.env.VITE_API_PREFIX || ""}/v1/admin/group/subscribe/mapping`,
{
method: "GET",
@@ -298,7 +300,7 @@ export async function exportGroupResult(
{
method: "GET",
params: params || {},
responseType: 'blob',
responseType: "blob",
...(options || {}),
}
);
+2 -2
View File
@@ -2807,7 +2807,7 @@ declare namespace API {
list: RedemptionRecord[];
};
type Subscribe = {
type SubscribeSimple = {
id: number;
name: string;
unit_price: number;
@@ -2830,7 +2830,7 @@ declare namespace API {
id: number;
subscribe_id: number;
user_group_id: number;
subscribe?: Subscribe;
subscribe?: SubscribeSimple;
user_group?: UserGroup;
created_at: number;
updated_at: number;
+18
View File
@@ -177,3 +177,21 @@ export async function generateCaptcha(options?: { [key: string]: any }) {
}
);
}
/** Verify slider captcha POST /v1/auth/captcha/slider/verify */
export async function verifyCaptchaSlider(
body: { id: string; x: number; y: number; trail: string },
options?: { [key: string]: any }
) {
return request<API.Response & { data?: API.SliderVerifyCaptchaResponse }>(
`${import.meta.env.VITE_API_PREFIX || ""}/v1/auth/captcha/slider/verify`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
data: body,
...(options || {}),
}
);
}
+29
View File
@@ -338,6 +338,17 @@ declare namespace API {
state: string;
};
type GenerateCaptchaResponse = {
type: string;
id: string;
image: string;
block_image?: string;
};
type SliderVerifyCaptchaResponse = {
token: string;
};
type HeartbeatResponse = {
status: boolean;
message?: string;
@@ -732,6 +743,9 @@ declare namespace API {
password: string;
code?: string;
cf_token?: string;
captcha_id?: string;
captcha_code?: string;
slider_token?: string;
};
type ResetSubscribeTrafficLog = {
@@ -931,6 +945,9 @@ declare namespace API {
telephone_area_code: string;
password: string;
cf_token?: string;
captcha_id?: string;
captcha_code?: string;
slider_token?: string;
};
type TelephoneRegisterRequest = {
@@ -941,6 +958,9 @@ declare namespace API {
invite?: string;
code?: string;
cf_token?: string;
captcha_id?: string;
captcha_code?: string;
slider_token?: string;
};
type TelephoneResetPasswordRequest = {
@@ -950,6 +970,9 @@ declare namespace API {
password: string;
code?: string;
cf_token?: string;
captcha_id?: string;
captcha_code?: string;
slider_token?: string;
};
type Ticket = {
@@ -1069,6 +1092,9 @@ declare namespace API {
email: string;
password: string;
cf_token?: string;
captcha_id?: string;
captcha_code?: string;
slider_token?: string;
};
type UserRegisterRequest = {
@@ -1078,6 +1104,9 @@ declare namespace API {
invite?: string;
code?: string;
cf_token?: string;
captcha_id?: string;
captcha_code?: string;
slider_token?: string;
};
type UserSubscribe = {
+1 -1
View File
@@ -1,7 +1,7 @@
import request from "@workspace/ui/lib/request";
export interface GetUserTrafficStatsRequest {
user_subscribe_id: string; // 保持字符串,避免精度问题
user_subscribe_id: string; // 保持字符串,避免精度问题
days: 7 | 30;
}