feat: 本次提交更新内容如下
eslint规则校验
This commit is contained in:
@@ -1,36 +1,40 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
env: {
|
env: {
|
||||||
browser: true,
|
browser: true,
|
||||||
es2021: true,
|
es2021: true,
|
||||||
node: true,
|
node: true,
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:react/recommended",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"plugin:prettier/recommended",
|
||||||
|
],
|
||||||
|
parser: "@typescript-eslint/parser",
|
||||||
|
parserOptions: {
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
},
|
},
|
||||||
extends: [
|
ecmaVersion: 12,
|
||||||
'eslint:recommended',
|
sourceType: "module",
|
||||||
'plugin:react/recommended',
|
},
|
||||||
'plugin:@typescript-eslint/recommended',
|
plugins: ["react", "@typescript-eslint", "prettier"],
|
||||||
'plugin:prettier/recommended',
|
rules: {
|
||||||
],
|
"prettier/prettier": "error",
|
||||||
parser: '@typescript-eslint/parser',
|
"react/react-in-jsx-scope": "off",
|
||||||
parserOptions: {
|
"@typescript-eslint/no-unused-vars": "warn",
|
||||||
ecmaFeatures: {
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
jsx: true,
|
"react/prop-types": "off",
|
||||||
},
|
"linebreak-style": "off",
|
||||||
ecmaVersion: 12,
|
"eol-last": "off",
|
||||||
sourceType: 'module',
|
"comma-dangle": "off",
|
||||||
},
|
"no-empty": "warn",
|
||||||
plugins: ['react', '@typescript-eslint', 'prettier'],
|
"prefer-const": "warn",
|
||||||
rules: {
|
},
|
||||||
'prettier/prettier': 'warn',
|
settings: {
|
||||||
'react/react-in-jsx-scope': 'off',
|
react: {
|
||||||
'@typescript-eslint/no-unused-vars': 'warn',
|
version: "detect",
|
||||||
'react/prop-types': 'off',
|
|
||||||
'linebreak-style': ['error', 'unix'],
|
|
||||||
'eol-last': ['error', 'always'],
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
react: {
|
|
||||||
version: 'detect',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"semi": true,
|
"semi": true,
|
||||||
"trailingComma": "es5",
|
"trailingComma": "all",
|
||||||
"singleQuote": false,
|
"singleQuote": false,
|
||||||
"printWidth": 80,
|
"printWidth": 80,
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
@@ -9,5 +9,6 @@
|
|||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
"arrowParens": "avoid",
|
"arrowParens": "avoid",
|
||||||
"jsxSingleQuote": false,
|
"jsxSingleQuote": false,
|
||||||
"quoteProps": "as-needed"
|
"quoteProps": "as-needed",
|
||||||
|
"commaDangle": "all"
|
||||||
}
|
}
|
||||||
20
nkebao/.vscode/settings.json
vendored
20
nkebao/.vscode/settings.json
vendored
@@ -4,21 +4,29 @@
|
|||||||
"files.trimFinalNewlines": true,
|
"files.trimFinalNewlines": true,
|
||||||
"files.trimTrailingWhitespace": true,
|
"files.trimTrailingWhitespace": true,
|
||||||
"editor.formatOnSave": true,
|
"editor.formatOnSave": true,
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": "explicit"
|
"source.fixAll.eslint": "explicit",
|
||||||
|
"source.organizeImports": "never"
|
||||||
},
|
},
|
||||||
|
"eslint.validate": [
|
||||||
|
"javascript",
|
||||||
|
"javascriptreact",
|
||||||
|
"typescript",
|
||||||
|
"typescriptreact"
|
||||||
|
],
|
||||||
|
"eslint.format.enable": true,
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||||
},
|
},
|
||||||
"[typescript]": {
|
"[typescript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||||
},
|
},
|
||||||
"[javascriptreact]": {
|
"[javascriptreact]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||||
},
|
},
|
||||||
"[typescriptreact]": {
|
"[typescriptreact]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||||
},
|
},
|
||||||
"[json]": {
|
"[json]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import request from "./request";
|
|||||||
*/
|
*/
|
||||||
export async function uploadFile(
|
export async function uploadFile(
|
||||||
file: File,
|
file: File,
|
||||||
uploadUrl: string = "/v1/attachment/upload"
|
uploadUrl: string = "/v1/attachment/upload",
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
try {
|
try {
|
||||||
// 创建 FormData 对象用于文件上传
|
// 创建 FormData 对象用于文件上传
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export const fetchDeviceRelatedAccounts = (id: string | number) =>
|
|||||||
export const fetchDeviceHandleLogs = (
|
export const fetchDeviceHandleLogs = (
|
||||||
id: string | number,
|
id: string | number,
|
||||||
page = 1,
|
page = 1,
|
||||||
limit = 10
|
limit = 10,
|
||||||
) => request(`/v1/devices/${id}/handle-logs`, { page, limit }, "GET");
|
) => request(`/v1/devices/${id}/handle-logs`, { page, limit }, "GET");
|
||||||
|
|
||||||
// 更新设备任务配置
|
// 更新设备任务配置
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ instance.interceptors.response.use(
|
|||||||
err => {
|
err => {
|
||||||
Toast.show({ content: err.message || "网络异常", position: "top" });
|
Toast.show({ content: err.message || "网络异常", position: "top" });
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export function request(
|
export function request(
|
||||||
@@ -55,7 +55,7 @@ export function request(
|
|||||||
data?: any,
|
data?: any,
|
||||||
method: Method = "GET",
|
method: Method = "GET",
|
||||||
config?: AxiosRequestConfig,
|
config?: AxiosRequestConfig,
|
||||||
debounceGap?: number
|
debounceGap?: number,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const gap =
|
const gap =
|
||||||
typeof debounceGap === "number" ? debounceGap : DEFAULT_DEBOUNCE_GAP;
|
typeof debounceGap === "number" ? debounceGap : DEFAULT_DEBOUNCE_GAP;
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export default function AccountSelection({
|
|||||||
acc =>
|
acc =>
|
||||||
acc.userName.includes(searchQuery) ||
|
acc.userName.includes(searchQuery) ||
|
||||||
acc.realName.includes(searchQuery) ||
|
acc.realName.includes(searchQuery) ||
|
||||||
acc.departmentName.includes(searchQuery)
|
acc.departmentName.includes(searchQuery),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 处理账号选择
|
// 处理账号选择
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ interface ContentLibrarySelectionProps {
|
|||||||
readonly?: boolean;
|
readonly?: boolean;
|
||||||
onConfirm?: (
|
onConfirm?: (
|
||||||
selectedIds: string[],
|
selectedIds: string[],
|
||||||
selectedItems: ContentLibraryItem[]
|
selectedItems: ContentLibraryItem[],
|
||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ export default function ContentLibrarySelection({
|
|||||||
|
|
||||||
// 获取已选内容库详细信息
|
// 获取已选内容库详细信息
|
||||||
const selectedLibraryObjs = libraries.filter(item =>
|
const selectedLibraryObjs = libraries.filter(item =>
|
||||||
selectedLibraries.includes(item.id)
|
selectedLibraries.includes(item.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 删除已选内容库
|
// 删除已选内容库
|
||||||
@@ -132,7 +132,7 @@ export default function ContentLibrarySelection({
|
|||||||
const fetchLibraries = async (page: number, keyword: string = "") => {
|
const fetchLibraries = async (page: number, keyword: string = "") => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
let params: any = {
|
const params: any = {
|
||||||
page,
|
page,
|
||||||
limit: 20,
|
limit: 20,
|
||||||
};
|
};
|
||||||
@@ -161,7 +161,7 @@ export default function ContentLibrarySelection({
|
|||||||
onSelect(newSelected);
|
onSelect(newSelected);
|
||||||
if (onSelectDetail) {
|
if (onSelectDetail) {
|
||||||
const selectedObjs = libraries.filter(item =>
|
const selectedObjs = libraries.filter(item =>
|
||||||
newSelected.includes(item.id)
|
newSelected.includes(item.id),
|
||||||
);
|
);
|
||||||
onSelectDetail(selectedObjs);
|
onSelectDetail(selectedObjs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ const SelectionPopup: React.FC<SelectionPopupProps> = ({
|
|||||||
wxid: d.wechatId || "",
|
wxid: d.wechatId || "",
|
||||||
nickname: d.nickname || "",
|
nickname: d.nickname || "",
|
||||||
usedInPlans: d.usedInPlans || 0,
|
usedInPlans: d.usedInPlans || 0,
|
||||||
}))
|
})),
|
||||||
);
|
);
|
||||||
setTotal(res.total || 0);
|
setTotal(res.total || 0);
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ const SelectionPopup: React.FC<SelectionPopupProps> = ({
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[]
|
[],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 打开弹窗时获取第一页
|
// 打开弹窗时获取第一页
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ export default function FriendSelection({
|
|||||||
const fetchFriends = async (page: number, keyword: string = "") => {
|
const fetchFriends = async (page: number, keyword: string = "") => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
let params: any = {
|
const params: any = {
|
||||||
page,
|
page,
|
||||||
limit: 20,
|
limit: 20,
|
||||||
};
|
};
|
||||||
@@ -137,7 +137,7 @@ export default function FriendSelection({
|
|||||||
// 如果有 onSelectDetail 回调,传递完整的好友对象
|
// 如果有 onSelectDetail 回调,传递完整的好友对象
|
||||||
if (onSelectDetail) {
|
if (onSelectDetail) {
|
||||||
const selectedFriendObjs = friends.filter(friend =>
|
const selectedFriendObjs = friends.filter(friend =>
|
||||||
newSelectedFriends.includes(friend.id)
|
newSelectedFriends.includes(friend.id),
|
||||||
);
|
);
|
||||||
onSelectDetail(selectedFriendObjs);
|
onSelectDetail(selectedFriendObjs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default function GroupSelection({
|
|||||||
|
|
||||||
// 获取已选群聊详细信息
|
// 获取已选群聊详细信息
|
||||||
const selectedGroupObjs = groups.filter(group =>
|
const selectedGroupObjs = groups.filter(group =>
|
||||||
selectedGroups.includes(group.id)
|
selectedGroups.includes(group.id),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 删除已选群聊
|
// 删除已选群聊
|
||||||
@@ -106,7 +106,7 @@ export default function GroupSelection({
|
|||||||
const fetchGroups = async (page: number, keyword: string = "") => {
|
const fetchGroups = async (page: number, keyword: string = "") => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
try {
|
try {
|
||||||
let params: any = {
|
const params: any = {
|
||||||
page,
|
page,
|
||||||
limit: 20,
|
limit: 20,
|
||||||
};
|
};
|
||||||
@@ -141,7 +141,7 @@ export default function GroupSelection({
|
|||||||
// 如果有 onSelectDetail 回调,传递完整的群聊对象
|
// 如果有 onSelectDetail 回调,传递完整的群聊对象
|
||||||
if (onSelectDetail) {
|
if (onSelectDetail) {
|
||||||
const selectedGroupObjs = groups.filter(group =>
|
const selectedGroupObjs = groups.filter(group =>
|
||||||
newSelectedGroups.includes(group.id)
|
newSelectedGroups.includes(group.id),
|
||||||
);
|
);
|
||||||
onSelectDetail(selectedGroupObjs);
|
onSelectDetail(selectedGroupObjs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ const Layout: React.FC<LayoutProps> = ({
|
|||||||
const setRealHeight = () => {
|
const setRealHeight = () => {
|
||||||
document.documentElement.style.setProperty(
|
document.documentElement.style.setProperty(
|
||||||
"--real-vh",
|
"--real-vh",
|
||||||
`${window.innerHeight * 0.01}px`
|
`${window.innerHeight * 0.01}px`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
setRealHeight();
|
setRealHeight();
|
||||||
|
|||||||
@@ -54,11 +54,50 @@ const VideoUpload: React.FC<VideoUploadProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 处理文件变化
|
// 处理文件变化
|
||||||
const handleChange: UploadProps["onChange"] = info => {
|
const handleChange: UploadProps["onChange"] = async info => {
|
||||||
if (info.file.status === "uploading") {
|
if (info.file.status === "uploading") {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
|
// 在这里处理文件上传
|
||||||
|
try {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", info.file.originFileObj as File);
|
||||||
|
|
||||||
|
const response = await request(
|
||||||
|
"/v1/attachment/upload",
|
||||||
|
formData,
|
||||||
|
"POST",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
const uploadedUrl =
|
||||||
|
typeof response === "string" ? response : response.url || response;
|
||||||
|
|
||||||
|
// 更新文件状态
|
||||||
|
const updatedFile = {
|
||||||
|
...info.file,
|
||||||
|
status: "done" as const,
|
||||||
|
url: uploadedUrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新fileList
|
||||||
|
setFileList([updatedFile]);
|
||||||
|
// 调用onChange
|
||||||
|
onChange?.(uploadedUrl);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
message.success("上传成功");
|
||||||
|
} else {
|
||||||
|
throw new Error("上传失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("上传失败:", error);
|
||||||
|
message.error("上传失败,请重试");
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.file.status === "done") {
|
if (info.file.status === "done") {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
// 更新fileList
|
// 更新fileList
|
||||||
@@ -68,35 +107,6 @@ const VideoUpload: React.FC<VideoUploadProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 自定义上传请求
|
|
||||||
const customRequest: UploadProps["customRequest"] = async ({
|
|
||||||
file,
|
|
||||||
onSuccess,
|
|
||||||
onError,
|
|
||||||
}) => {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("file", file as File);
|
|
||||||
|
|
||||||
const response = await request("/v1/attachment/upload", formData, "POST");
|
|
||||||
|
|
||||||
if (response) {
|
|
||||||
const uploadedUrl =
|
|
||||||
typeof response === "string" ? response : response.url || response;
|
|
||||||
onSuccess?.(uploadedUrl);
|
|
||||||
} else {
|
|
||||||
throw new Error("上传失败");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("上传失败:", error);
|
|
||||||
onError?.(error as Error);
|
|
||||||
message.error("上传失败,请重试");
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除文件
|
// 删除文件
|
||||||
const handleRemove = () => {
|
const handleRemove = () => {
|
||||||
setFileList([]);
|
setFileList([]);
|
||||||
@@ -131,7 +141,6 @@ const VideoUpload: React.FC<VideoUploadProps> = ({
|
|||||||
showUploadList={true}
|
showUploadList={true}
|
||||||
disabled={disabled || loading}
|
disabled={disabled || loading}
|
||||||
beforeUpload={beforeUpload}
|
beforeUpload={beforeUpload}
|
||||||
customRequest={customRequest}
|
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
onRemove={handleRemove}
|
onRemove={handleRemove}
|
||||||
>
|
>
|
||||||
|
|||||||
6
nkebao/src/components/Upload/api.ts
Normal file
6
nkebao/src/components/Upload/api.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import request from "@/api/request";
|
||||||
|
|
||||||
|
// 创建素材
|
||||||
|
export function createContentItem(params: any) {
|
||||||
|
return request("/v1/content/library/create-item", params, "POST");
|
||||||
|
}
|
||||||
@@ -60,11 +60,61 @@ const UploadComponent: React.FC<UploadComponentProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 处理文件变化
|
// 处理文件变化
|
||||||
const handleChange: UploadProps["onChange"] = info => {
|
const handleChange: UploadProps["onChange"] = async info => {
|
||||||
|
console.log(info);
|
||||||
|
|
||||||
if (info.file.status === "uploading") {
|
if (info.file.status === "uploading") {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
|
// 在这里处理文件上传
|
||||||
|
try {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", info.file.originFileObj as File);
|
||||||
|
|
||||||
|
const response = await request(
|
||||||
|
"/v1/attachment/upload",
|
||||||
|
formData,
|
||||||
|
"POST",
|
||||||
|
);
|
||||||
|
|
||||||
|
if (response) {
|
||||||
|
const uploadedUrl =
|
||||||
|
typeof response === "string" ? response : response.url || response;
|
||||||
|
|
||||||
|
// 更新文件状态
|
||||||
|
const updatedFile = {
|
||||||
|
...info.file,
|
||||||
|
status: "done" as const,
|
||||||
|
url: uploadedUrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新fileList
|
||||||
|
const newFileList = [...fileList];
|
||||||
|
const fileIndex = newFileList.findIndex(f => f.uid === info.file.uid);
|
||||||
|
if (fileIndex > -1) {
|
||||||
|
newFileList[fileIndex] = updatedFile;
|
||||||
|
} else {
|
||||||
|
newFileList.push(updatedFile);
|
||||||
|
}
|
||||||
|
setFileList(newFileList);
|
||||||
|
|
||||||
|
// 调用onChange
|
||||||
|
const urls = newFileList.map(f => f.url).filter(Boolean) as string[];
|
||||||
|
onChange?.(urls);
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
message.success("上传成功");
|
||||||
|
} else {
|
||||||
|
throw new Error("上传失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("上传失败:", error);
|
||||||
|
message.error("上传失败,请重试");
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.file.status === "done") {
|
if (info.file.status === "done") {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
// 更新fileList
|
// 更新fileList
|
||||||
@@ -83,36 +133,6 @@ const UploadComponent: React.FC<UploadComponentProps> = ({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 自定义上传请求
|
|
||||||
const customRequest: UploadProps["customRequest"] = async ({
|
|
||||||
file,
|
|
||||||
onSuccess,
|
|
||||||
onError,
|
|
||||||
onProgress,
|
|
||||||
}) => {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
const formData = new FormData();
|
|
||||||
formData.append("file", file as File);
|
|
||||||
|
|
||||||
const response = await request("/v1/attachment/upload", formData, "POST");
|
|
||||||
|
|
||||||
if (response) {
|
|
||||||
const uploadedUrl =
|
|
||||||
typeof response === "string" ? response : response.url || response;
|
|
||||||
onSuccess?.(uploadedUrl);
|
|
||||||
} else {
|
|
||||||
throw new Error("上传失败");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("上传失败:", error);
|
|
||||||
onError?.(error as Error);
|
|
||||||
message.error("上传失败,请重试");
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除文件
|
// 删除文件
|
||||||
const handleRemove = (file: UploadFile) => {
|
const handleRemove = (file: UploadFile) => {
|
||||||
const newFileList = fileList.filter(f => f.uid !== file.uid);
|
const newFileList = fileList.filter(f => f.uid !== file.uid);
|
||||||
@@ -151,7 +171,6 @@ const UploadComponent: React.FC<UploadComponentProps> = ({
|
|||||||
showUploadList={true}
|
showUploadList={true}
|
||||||
disabled={disabled || loading}
|
disabled={disabled || loading}
|
||||||
beforeUpload={beforeUpload}
|
beforeUpload={beforeUpload}
|
||||||
customRequest={customRequest}
|
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
onRemove={handleRemove}
|
onRemove={handleRemove}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ export function getContentLibraryDetail(id: string): Promise<any> {
|
|||||||
|
|
||||||
// 创建内容库
|
// 创建内容库
|
||||||
export function createContentLibrary(
|
export function createContentLibrary(
|
||||||
params: CreateContentLibraryParams
|
params: CreateContentLibraryParams,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return request("/v1/content/library/create", params, "POST");
|
return request("/v1/content/library/create", params, "POST");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新内容库
|
// 更新内容库
|
||||||
export function updateContentLibrary(
|
export function updateContentLibrary(
|
||||||
params: UpdateContentLibraryParams
|
params: UpdateContentLibraryParams,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const { id, ...data } = params;
|
const { id, ...data } = params;
|
||||||
return request(`/v1/content/library/update`, { id, ...data }, "POST");
|
return request(`/v1/content/library/update`, { id, ...data }, "POST");
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ export default function ContentForm() {
|
|||||||
setUseAI(!!data.aiPrompt);
|
setUseAI(!!data.aiPrompt);
|
||||||
setEnabled(data.status === 1);
|
setEnabled(data.status === 1);
|
||||||
// 时间范围
|
// 时间范围
|
||||||
let start = data.timeStart || data.startTime;
|
const start = data.timeStart || data.startTime;
|
||||||
let end = data.timeEnd || data.endTime;
|
const end = data.timeEnd || data.endTime;
|
||||||
setDateRange([
|
setDateRange([
|
||||||
start ? new Date(start) : null,
|
start ? new Date(start) : null,
|
||||||
end ? new Date(end) : null,
|
end ? new Date(end) : null,
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ export function getContentLibraryDetail(id: string): Promise<any> {
|
|||||||
|
|
||||||
// 创建内容库
|
// 创建内容库
|
||||||
export function createContentLibrary(
|
export function createContentLibrary(
|
||||||
params: CreateContentLibraryParams
|
params: CreateContentLibraryParams,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return request("/v1/content/library/create", params, "POST");
|
return request("/v1/content/library/create", params, "POST");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新内容库
|
// 更新内容库
|
||||||
export function updateContentLibrary(
|
export function updateContentLibrary(
|
||||||
params: UpdateContentLibraryParams
|
params: UpdateContentLibraryParams,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
const { id, ...data } = params;
|
const { id, ...data } = params;
|
||||||
return request(`/v1/content/library/update`, { id, ...data }, "POST");
|
return request(`/v1/content/library/update`, { id, ...data }, "POST");
|
||||||
@@ -43,7 +43,7 @@ export function deleteContentLibrary(id: string): Promise<any> {
|
|||||||
// 切换内容库状态
|
// 切换内容库状态
|
||||||
export function toggleContentLibraryStatus(
|
export function toggleContentLibraryStatus(
|
||||||
id: string,
|
id: string,
|
||||||
status: number
|
status: number,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return request("/v1/content/library/update-status", { id, status }, "POST");
|
return request("/v1/content/library/update-status", { id, status }, "POST");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ const ContentLibraryList: React.FC = () => {
|
|||||||
const filteredLibraries = libraries.filter(
|
const filteredLibraries = libraries.filter(
|
||||||
library =>
|
library =>
|
||||||
library.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
library.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||||
library.creatorName?.toLowerCase().includes(searchQuery.toLowerCase())
|
library.creatorName?.toLowerCase().includes(searchQuery.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ const MaterialForm: React.FC = () => {
|
|||||||
setSendTime(
|
setSendTime(
|
||||||
response.sendTime
|
response.sendTime
|
||||||
? new Date(response.sendTime * 1000).toISOString().slice(0, 16)
|
? new Date(response.sendTime * 1000).toISOString().slice(0, 16)
|
||||||
: ""
|
: "",
|
||||||
);
|
);
|
||||||
setResUrls(response.resUrls || []);
|
setResUrls(response.resUrls || []);
|
||||||
setUrls(response.urls || []);
|
setUrls(response.urls || []);
|
||||||
|
|||||||
@@ -206,8 +206,8 @@ const Home: React.FC = () => {
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
navigate(
|
navigate(
|
||||||
`/scenarios/list/${scenario.id}/${encodeURIComponent(
|
`/scenarios/list/${scenario.id}/${encodeURIComponent(
|
||||||
scenario.name
|
scenario.name,
|
||||||
)}`
|
)}`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const DeviceDetail: React.FC = () => {
|
|||||||
const [logs, setLogs] = useState<HandleLog[]>([]);
|
const [logs, setLogs] = useState<HandleLog[]>([]);
|
||||||
const [logsLoading, setLogsLoading] = useState(false);
|
const [logsLoading, setLogsLoading] = useState(false);
|
||||||
const [featureSaving, setFeatureSaving] = useState<{ [k: string]: boolean }>(
|
const [featureSaving, setFeatureSaving] = useState<{ [k: string]: boolean }>(
|
||||||
{}
|
{},
|
||||||
);
|
);
|
||||||
|
|
||||||
// 获取设备详情
|
// 获取设备详情
|
||||||
@@ -82,7 +82,7 @@ const DeviceDetail: React.FC = () => {
|
|||||||
// 功能开关
|
// 功能开关
|
||||||
const handleFeatureChange = async (
|
const handleFeatureChange = async (
|
||||||
feature: keyof Device["features"],
|
feature: keyof Device["features"],
|
||||||
checked: boolean
|
checked: boolean,
|
||||||
) => {
|
) => {
|
||||||
if (!id) return;
|
if (!id) return;
|
||||||
setFeatureSaving(prev => ({ ...prev, [feature]: true }));
|
setFeatureSaving(prev => ({ ...prev, [feature]: true }));
|
||||||
@@ -94,7 +94,7 @@ const DeviceDetail: React.FC = () => {
|
|||||||
...prev,
|
...prev,
|
||||||
features: { ...prev.features, [feature]: checked },
|
features: { ...prev.features, [feature]: checked },
|
||||||
}
|
}
|
||||||
: prev
|
: prev,
|
||||||
);
|
);
|
||||||
Toast.show({
|
Toast.show({
|
||||||
content: `${getFeatureName(feature)}已${checked ? "开启" : "关闭"}`,
|
content: `${getFeatureName(feature)}已${checked ? "开启" : "关闭"}`,
|
||||||
@@ -219,12 +219,12 @@ const DeviceDetail: React.FC = () => {
|
|||||||
onChange={checked =>
|
onChange={checked =>
|
||||||
handleFeatureChange(
|
handleFeatureChange(
|
||||||
f as keyof Device["features"],
|
f as keyof Device["features"],
|
||||||
checked
|
checked,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ const Devices: React.FC = () => {
|
|||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[loading, search, page]
|
[loading, search, page],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 首次加载和搜索
|
// 首次加载和搜索
|
||||||
@@ -86,7 +86,7 @@ const Devices: React.FC = () => {
|
|||||||
setPage(p => p + 1);
|
setPage(p => p + 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ threshold: 0.5 }
|
{ threshold: 0.5 },
|
||||||
);
|
);
|
||||||
if (observerRef.current) observer.observe(observerRef.current);
|
if (observerRef.current) observer.observe(observerRef.current);
|
||||||
return () => observer.disconnect();
|
return () => observer.disconnect();
|
||||||
@@ -166,7 +166,7 @@ const Devices: React.FC = () => {
|
|||||||
try {
|
try {
|
||||||
await comfirm(
|
await comfirm(
|
||||||
`将删除${selected.length}个设备,删除后本设备配置的计划任务操作也将失效。确认删除?`,
|
`将删除${selected.length}个设备,删除后本设备配置的计划任务操作也将失效。确认删除?`,
|
||||||
{ title: "确认删除", confirmText: "确认删除", cancelText: "取消" }
|
{ title: "确认删除", confirmText: "确认删除", cancelText: "取消" },
|
||||||
);
|
);
|
||||||
handleDelete();
|
handleDelete();
|
||||||
} catch {
|
} catch {
|
||||||
@@ -301,7 +301,7 @@ const Devices: React.FC = () => {
|
|||||||
setSelected(prev =>
|
setSelected(prev =>
|
||||||
e.target.checked
|
e.target.checked
|
||||||
? [...prev, device.id!]
|
? [...prev, device.id!]
|
||||||
: prev.filter(id => id !== device.id)
|
: prev.filter(id => id !== device.id),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const TrafficPoolDetail: React.FC = () => {
|
|||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
const [user, setUser] = useState<TrafficPoolUserDetail | null>(null);
|
const [user, setUser] = useState<TrafficPoolUserDetail | null>(null);
|
||||||
const [activeTab, setActiveTab] = useState<"base" | "journey" | "tags">(
|
const [activeTab, setActiveTab] = useState<"base" | "journey" | "tags">(
|
||||||
"base"
|
"base",
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ export function useTrafficPoolListLogic() {
|
|||||||
// 单选
|
// 单选
|
||||||
const handleSelect = (id: number, checked: boolean) => {
|
const handleSelect = (id: number, checked: boolean) => {
|
||||||
setSelectedIds(prev =>
|
setSelectedIds(prev =>
|
||||||
checked ? [...prev, id] : prev.filter(i => i !== id)
|
checked ? [...prev, id] : prev.filter(i => i !== id),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function getWechatFriends(params: {
|
|||||||
limit: params.limit,
|
limit: params.limit,
|
||||||
keyword: params.keyword,
|
keyword: params.keyword,
|
||||||
},
|
},
|
||||||
"GET"
|
"GET",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ const WechatAccountDetail: React.FC = () => {
|
|||||||
setIsFetchingFriends(false);
|
setIsFetchingFriends(false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[id]
|
[id],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 搜索好友
|
// 搜索好友
|
||||||
@@ -153,7 +153,7 @@ const WechatAccountDetail: React.FC = () => {
|
|||||||
setFriendsPage(page);
|
setFriendsPage(page);
|
||||||
fetchFriendsList(page, searchQuery);
|
fetchFriendsList(page, searchQuery);
|
||||||
},
|
},
|
||||||
[searchQuery, fetchFriendsList]
|
[searchQuery, fetchFriendsList],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 初始化数据
|
// 初始化数据
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const Scene: React.FC = () => {
|
|||||||
|
|
||||||
const handleScenarioClick = (scenarioId: string, scenarioName: string) => {
|
const handleScenarioClick = (scenarioId: string, scenarioName: string) => {
|
||||||
navigate(
|
navigate(
|
||||||
`/scenarios/list/${scenarioId}/${encodeURIComponent(scenarioName)}`
|
`/scenarios/list/${scenarioId}/${encodeURIComponent(scenarioName)}`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ const ScenarioList: React.FC = () => {
|
|||||||
if (response) {
|
if (response) {
|
||||||
// 处理webhook URL,使用工具函数构建完整地址
|
// 处理webhook URL,使用工具函数构建完整地址
|
||||||
const webhookUrl = buildApiUrl(
|
const webhookUrl = buildApiUrl(
|
||||||
response.textUrl?.fullUrl || `webhook/${taskId}`
|
response.textUrl?.fullUrl || `webhook/${taskId}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
setCurrentApiSettings({
|
setCurrentApiSettings({
|
||||||
@@ -286,7 +286,7 @@ const ScenarioList: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filteredTasks = tasks.filter(task =>
|
const filteredTasks = tasks.filter(task =>
|
||||||
task.name.toLowerCase().includes(searchTerm.toLowerCase())
|
task.name.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 生成操作菜单
|
// 生成操作菜单
|
||||||
@@ -537,7 +537,7 @@ const ScenarioList: React.FC = () => {
|
|||||||
<span className={style["action-icon"]}>{item.icon}</span>
|
<span className={style["action-icon"]}>{item.icon}</span>
|
||||||
<span className={style["action-text"]}>{item.text}</span>
|
<span className={style["action-text"]}>{item.text}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
),
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.o
|
|||||||
onClick={() =>
|
onClick={() =>
|
||||||
handleCopy(
|
handleCopy(
|
||||||
codeExamples[activeLanguage as keyof typeof codeExamples],
|
codeExamples[activeLanguage as keyof typeof codeExamples],
|
||||||
"代码"
|
"代码",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className={style["copy-code-btn"]}
|
className={style["copy-code-btn"]}
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ export default function NewPlan() {
|
|||||||
? error
|
? error
|
||||||
: isEdit
|
: isEdit
|
||||||
? "更新计划失败,请重试"
|
? "更新计划失败,请重试"
|
||||||
: "创建计划失败,请重试"
|
: "创建计划失败,请重试",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -105,10 +105,10 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
const [accounts] = useState<Account[]>(generateRandomAccounts(50));
|
const [accounts] = useState<Account[]>(generateRandomAccounts(50));
|
||||||
const [materials] = useState<Material[]>(generatePosterMaterials());
|
const [materials] = useState<Material[]>(generatePosterMaterials());
|
||||||
const [selectedAccounts, setSelectedAccounts] = useState<Account[]>(
|
const [selectedAccounts, setSelectedAccounts] = useState<Account[]>(
|
||||||
formData.accounts?.length > 0 ? formData.accounts : []
|
formData.accounts?.length > 0 ? formData.accounts : [],
|
||||||
);
|
);
|
||||||
const [selectedMaterials, setSelectedMaterials] = useState<Material[]>(
|
const [selectedMaterials, setSelectedMaterials] = useState<Material[]>(
|
||||||
formData.materials?.length > 0 ? formData.materials : []
|
formData.materials?.length > 0 ? formData.materials : [],
|
||||||
);
|
);
|
||||||
// showAllScenarios 默认为 true
|
// showAllScenarios 默认为 true
|
||||||
const [showAllScenarios, setShowAllScenarios] = useState(true);
|
const [showAllScenarios, setShowAllScenarios] = useState(true);
|
||||||
@@ -128,7 +128,7 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
const [customTags, setCustomTags] = useState(formData.customTags || []);
|
const [customTags, setCustomTags] = useState(formData.customTags || []);
|
||||||
const [tips, setTips] = useState(formData.tips || "");
|
const [tips, setTips] = useState(formData.tips || "");
|
||||||
const [selectedScenarioTags, setSelectedScenarioTags] = useState(
|
const [selectedScenarioTags, setSelectedScenarioTags] = useState(
|
||||||
formData.scenarioTags || []
|
formData.scenarioTags || [],
|
||||||
);
|
);
|
||||||
|
|
||||||
// 电话获客相关状态
|
// 电话获客相关状态
|
||||||
@@ -140,10 +140,10 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
|
|
||||||
// 群设置相关状态
|
// 群设置相关状态
|
||||||
const [weixinqunName, setWeixinqunName] = useState(
|
const [weixinqunName, setWeixinqunName] = useState(
|
||||||
formData.weixinqunName || ""
|
formData.weixinqunName || "",
|
||||||
);
|
);
|
||||||
const [weixinqunNotice, setWeixinqunNotice] = useState(
|
const [weixinqunNotice, setWeixinqunNotice] = useState(
|
||||||
formData.weixinqunNotice || ""
|
formData.weixinqunNotice || "",
|
||||||
);
|
);
|
||||||
|
|
||||||
// 新增:自定义海报相关状态
|
// 新增:自定义海报相关状态
|
||||||
@@ -232,7 +232,7 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
onChange({ ...formData, customTags: updatedCustomTags });
|
onChange({ ...formData, customTags: updatedCustomTags });
|
||||||
// 同时从选中标签中移除
|
// 同时从选中标签中移除
|
||||||
const updatedSelectedTags = selectedScenarioTags.filter(
|
const updatedSelectedTags = selectedScenarioTags.filter(
|
||||||
(t: string) => t !== tagId
|
(t: string) => t !== tagId,
|
||||||
);
|
);
|
||||||
setSelectedScenarioTags(updatedSelectedTags);
|
setSelectedScenarioTags(updatedSelectedTags);
|
||||||
onChange({
|
onChange({
|
||||||
@@ -292,12 +292,12 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
// 账号多选切换
|
// 账号多选切换
|
||||||
const handleAccountToggle = (account: Account) => {
|
const handleAccountToggle = (account: Account) => {
|
||||||
const isSelected = selectedAccounts.some(
|
const isSelected = selectedAccounts.some(
|
||||||
(a: Account) => a.id === account.id
|
(a: Account) => a.id === account.id,
|
||||||
);
|
);
|
||||||
let newSelected;
|
let newSelected;
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
newSelected = selectedAccounts.filter(
|
newSelected = selectedAccounts.filter(
|
||||||
(a: Account) => a.id !== account.id
|
(a: Account) => a.id !== account.id,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
newSelected = [...selectedAccounts, account];
|
newSelected = [...selectedAccounts, account];
|
||||||
@@ -362,7 +362,7 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
const [orderUploaded, setOrderUploaded] = useState(false);
|
const [orderUploaded, setOrderUploaded] = useState(false);
|
||||||
|
|
||||||
const handleOrderFileUpload = async (
|
const handleOrderFileUpload = async (
|
||||||
event: React.ChangeEvent<HTMLInputElement>
|
event: React.ChangeEvent<HTMLInputElement>,
|
||||||
) => {
|
) => {
|
||||||
const file = event.target.files?.[0];
|
const file = event.target.files?.[0];
|
||||||
if (file) {
|
if (file) {
|
||||||
@@ -518,7 +518,7 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
<div className={styles["basic-materials-grid"]}>
|
<div className={styles["basic-materials-grid"]}>
|
||||||
{[...materials, ...customPosters].map(material => {
|
{[...materials, ...customPosters].map(material => {
|
||||||
const isSelected = selectedMaterials.some(
|
const isSelected = selectedMaterials.some(
|
||||||
m => m.id === material.id
|
m => m.id === material.id,
|
||||||
);
|
);
|
||||||
const isCustom = material.id.startsWith("custom-");
|
const isCustom = material.id.startsWith("custom-");
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const FriendRequestSettings: React.FC<FriendRequestSettingsProps> = ({
|
|||||||
const [isTemplateDialogOpen, setIsTemplateDialogOpen] = useState(false);
|
const [isTemplateDialogOpen, setIsTemplateDialogOpen] = useState(false);
|
||||||
const [hasWarnings, setHasWarnings] = useState(false);
|
const [hasWarnings, setHasWarnings] = useState(false);
|
||||||
const [selectedDevices, setSelectedDevices] = useState<string[]>(
|
const [selectedDevices, setSelectedDevices] = useState<string[]>(
|
||||||
formData.device || []
|
formData.device || [],
|
||||||
);
|
);
|
||||||
const [showRemarkTip, setShowRemarkTip] = useState(false);
|
const [showRemarkTip, setShowRemarkTip] = useState(false);
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ const MessageSettings: React.FC<MessageSettingsProps> = ({
|
|||||||
const handleUpdateMessage = (
|
const handleUpdateMessage = (
|
||||||
dayIndex: number,
|
dayIndex: number,
|
||||||
messageIndex: number,
|
messageIndex: number,
|
||||||
updates: Partial<MessageContent>
|
updates: Partial<MessageContent>,
|
||||||
) => {
|
) => {
|
||||||
const updatedPlans = [...dayPlans];
|
const updatedPlans = [...dayPlans];
|
||||||
updatedPlans[dayIndex].messages[messageIndex] = {
|
updatedPlans[dayIndex].messages[messageIndex] = {
|
||||||
@@ -181,7 +181,7 @@ const MessageSettings: React.FC<MessageSettingsProps> = ({
|
|||||||
setSelectedGroupId(groupId);
|
setSelectedGroupId(groupId);
|
||||||
setIsGroupSelectOpen(false);
|
setIsGroupSelectOpen(false);
|
||||||
message.success(
|
message.success(
|
||||||
`已选择群组:${mockGroups.find(g => g.id === groupId)?.name}`
|
`已选择群组:${mockGroups.find(g => g.id === groupId)?.name}`,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ const MessageSettings: React.FC<MessageSettingsProps> = ({
|
|||||||
const triggerUpload = (
|
const triggerUpload = (
|
||||||
dayIdx: number,
|
dayIdx: number,
|
||||||
msgIdx: number,
|
msgIdx: number,
|
||||||
type: "miniprogram" | "link"
|
type: "miniprogram" | "link",
|
||||||
) => {
|
) => {
|
||||||
setUploadingDay(dayIdx);
|
setUploadingDay(dayIdx);
|
||||||
setUploadingMsgIdx(msgIdx);
|
setUploadingMsgIdx(msgIdx);
|
||||||
@@ -539,7 +539,7 @@ const MessageSettings: React.FC<MessageSettingsProps> = ({
|
|||||||
handleFileUpload(
|
handleFileUpload(
|
||||||
dayIndex,
|
dayIndex,
|
||||||
messageIndex,
|
messageIndex,
|
||||||
message.type as any
|
message.type as any,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ export function deleteScenario(id: string) {
|
|||||||
export function getPlanList(
|
export function getPlanList(
|
||||||
scenarioId: string,
|
scenarioId: string,
|
||||||
page: number = 1,
|
page: number = 1,
|
||||||
limit: number = 20
|
limit: number = 20,
|
||||||
) {
|
) {
|
||||||
return request(`/api/scenarios/${scenarioId}/plans`, { page, limit }, "GET");
|
return request(`/api/scenarios/${scenarioId}/plans`, { page, limit }, "GET");
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ export function deleteAutoLikeTask(taskId: string) {
|
|||||||
return request(
|
return request(
|
||||||
`/api/workspace/auto-like/tasks/${taskId}`,
|
`/api/workspace/auto-like/tasks/${taskId}`,
|
||||||
undefined,
|
undefined,
|
||||||
"DELETE"
|
"DELETE",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ export function deleteGroupPushTask(taskId: string) {
|
|||||||
return request(
|
return request(
|
||||||
`/api/workspace/group-push/tasks/${taskId}`,
|
`/api/workspace/group-push/tasks/${taskId}`,
|
||||||
undefined,
|
undefined,
|
||||||
"DELETE"
|
"DELETE",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +266,7 @@ export function deleteAutoGroupTask(taskId: string) {
|
|||||||
return request(
|
return request(
|
||||||
`/api/workspace/auto-group/tasks/${taskId}`,
|
`/api/workspace/auto-group/tasks/${taskId}`,
|
||||||
undefined,
|
undefined,
|
||||||
"DELETE"
|
"DELETE",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ export function getAIAnalysisReport() {
|
|||||||
return request(
|
return request(
|
||||||
"/api/workspace/ai-assistant/analysis-report",
|
"/api/workspace/ai-assistant/analysis-report",
|
||||||
undefined,
|
undefined,
|
||||||
"GET"
|
"GET",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,6 +379,6 @@ export function markNotificationAsRead(notificationId: string) {
|
|||||||
return request(
|
return request(
|
||||||
`/api/system/notifications/${notificationId}/read`,
|
`/api/system/notifications/${notificationId}/read`,
|
||||||
undefined,
|
undefined,
|
||||||
"PUT"
|
"PUT",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ const mockTaskDetail: GroupTaskDetail = {
|
|||||||
nickname: `用户${mIndex + 1}`,
|
nickname: `用户${mIndex + 1}`,
|
||||||
wechatId: `wx_${mIndex}`,
|
wechatId: `wx_${mIndex}`,
|
||||||
tags: [`标签${(mIndex % 3) + 1}`],
|
tags: [`标签${(mIndex % 3) + 1}`],
|
||||||
})
|
}),
|
||||||
),
|
),
|
||||||
})),
|
})),
|
||||||
createTime: "2024-11-20 19:04:14",
|
createTime: "2024-11-20 19:04:14",
|
||||||
@@ -169,10 +169,10 @@ const GroupCreationProgress: React.FC<{
|
|||||||
}> = ({ taskDetail, onComplete }) => {
|
}> = ({ taskDetail, onComplete }) => {
|
||||||
const [groups, setGroups] = useState<Group[]>(taskDetail.groups);
|
const [groups, setGroups] = useState<Group[]>(taskDetail.groups);
|
||||||
const [currentGroupIndex, setCurrentGroupIndex] = useState(
|
const [currentGroupIndex, setCurrentGroupIndex] = useState(
|
||||||
taskDetail.currentGroupIndex
|
taskDetail.currentGroupIndex,
|
||||||
);
|
);
|
||||||
const [status, setStatus] = useState<GroupTaskDetail["status"]>(
|
const [status, setStatus] = useState<GroupTaskDetail["status"]>(
|
||||||
taskDetail.status
|
taskDetail.status,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -207,7 +207,7 @@ const GroupCreationProgress: React.FC<{
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
return group;
|
return group;
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -149,8 +149,8 @@ const AutoGroupList: React.FC = () => {
|
|||||||
...task,
|
...task,
|
||||||
status: task.status === "running" ? "paused" : "running",
|
status: task.status === "running" ? "paused" : "running",
|
||||||
}
|
}
|
||||||
: task
|
: task,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
Toast.show({ content: "状态已切换" });
|
Toast.show({ content: "状态已切换" });
|
||||||
};
|
};
|
||||||
@@ -160,7 +160,7 @@ const AutoGroupList: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filteredTasks = tasks.filter(task =>
|
const filteredTasks = tasks.filter(task =>
|
||||||
task.name.toLowerCase().includes(searchTerm.toLowerCase())
|
task.name.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
|
|
||||||
// 获取自动点赞任务列表
|
// 获取自动点赞任务列表
|
||||||
export function fetchAutoLikeTasks(
|
export function fetchAutoLikeTasks(
|
||||||
params = { type: 1, page: 1, limit: 100 }
|
params = { type: 1, page: 1, limit: 100 },
|
||||||
): Promise<LikeTask[]> {
|
): Promise<LikeTask[]> {
|
||||||
return request("/v1/workbench/list", params, "GET");
|
return request("/v1/workbench/list", params, "GET");
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ export function fetchLikeRecords(
|
|||||||
workbenchId: string,
|
workbenchId: string,
|
||||||
page: number = 1,
|
page: number = 1,
|
||||||
limit: number = 20,
|
limit: number = 20,
|
||||||
keyword?: string
|
keyword?: string,
|
||||||
): Promise<PaginatedResponse<LikeRecord>> {
|
): Promise<PaginatedResponse<LikeRecord>> {
|
||||||
const params: any = {
|
const params: any = {
|
||||||
workbenchId,
|
workbenchId,
|
||||||
|
|||||||
@@ -224,7 +224,7 @@ const AutoLike: React.FC = () => {
|
|||||||
|
|
||||||
// 过滤任务
|
// 过滤任务
|
||||||
const filteredTasks = tasks.filter(task =>
|
const filteredTasks = tasks.filter(task =>
|
||||||
task.name.toLowerCase().includes(searchTerm.toLowerCase())
|
task.name.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ const NewAutoLike: React.FC = () => {
|
|||||||
});
|
});
|
||||||
setAutoEnabled(
|
setAutoEnabled(
|
||||||
(taskDetail as any).status === 1 ||
|
(taskDetail as any).status === 1 ||
|
||||||
(taskDetail as any).status === "running"
|
(taskDetail as any).status === "running",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
|
|
||||||
// 获取自动点赞任务列表
|
// 获取自动点赞任务列表
|
||||||
export function fetchAutoLikeTasks(
|
export function fetchAutoLikeTasks(
|
||||||
params = { type: 1, page: 1, limit: 100 }
|
params = { type: 1, page: 1, limit: 100 },
|
||||||
): Promise<LikeTask[]> {
|
): Promise<LikeTask[]> {
|
||||||
return request("/v1/workbench/list", params, "GET");
|
return request("/v1/workbench/list", params, "GET");
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ export function fetchLikeRecords(
|
|||||||
workbenchId: string,
|
workbenchId: string,
|
||||||
page: number = 1,
|
page: number = 1,
|
||||||
limit: number = 20,
|
limit: number = 20,
|
||||||
keyword?: string
|
keyword?: string,
|
||||||
): Promise<PaginatedResponse<LikeRecord>> {
|
): Promise<PaginatedResponse<LikeRecord>> {
|
||||||
const params: any = {
|
const params: any = {
|
||||||
workbenchId,
|
workbenchId,
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ export async function deleteGroupPushTask(id: string): Promise<ApiResponse> {
|
|||||||
|
|
||||||
export async function toggleGroupPushTask(
|
export async function toggleGroupPushTask(
|
||||||
id: string,
|
id: string,
|
||||||
status: string
|
status: string,
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return request(
|
return request(
|
||||||
`/v1/workspace/group-push/tasks/${id}/toggle`,
|
`/v1/workspace/group-push/tasks/${id}/toggle`,
|
||||||
{ status },
|
{ status },
|
||||||
"POST"
|
"POST",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,20 +54,20 @@ export async function copyGroupPushTask(id: string): Promise<ApiResponse> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createGroupPushTask(
|
export async function createGroupPushTask(
|
||||||
taskData: Partial<GroupPushTask>
|
taskData: Partial<GroupPushTask>,
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return request("/v1/workspace/group-push/tasks", taskData, "POST");
|
return request("/v1/workspace/group-push/tasks", taskData, "POST");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateGroupPushTask(
|
export async function updateGroupPushTask(
|
||||||
id: string,
|
id: string,
|
||||||
taskData: Partial<GroupPushTask>
|
taskData: Partial<GroupPushTask>,
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return request(`/v1/workspace/group-push/tasks/${id}`, taskData, "PUT");
|
return request(`/v1/workspace/group-push/tasks/${id}`, taskData, "PUT");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getGroupPushTaskDetail(
|
export async function getGroupPushTaskDetail(
|
||||||
id: string
|
id: string,
|
||||||
): Promise<GroupPushTask> {
|
): Promise<GroupPushTask> {
|
||||||
return request(`/v1/workspace/group-push/tasks/${id}`);
|
return request(`/v1/workspace/group-push/tasks/${id}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ const Detail: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<Progress
|
<Progress
|
||||||
percent={Math.round(
|
percent={Math.round(
|
||||||
(task.pushCount / task.maxPushPerDay) * 100
|
(task.pushCount / task.maxPushPerDay) * 100,
|
||||||
)}
|
)}
|
||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ const BasicSettings: React.FC<BasicSettingsProps> = ({
|
|||||||
onChange={e =>
|
onChange={e =>
|
||||||
handleChange(
|
handleChange(
|
||||||
"dailyPushCount",
|
"dailyPushCount",
|
||||||
Number.parseInt(e.target.value) || 1
|
Number.parseInt(e.target.value) || 1,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
style={{ width: 80, textAlign: "center" }}
|
style={{ width: 80, textAlign: "center" }}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ const ContentSelector: React.FC<ContentSelectorProps> = ({
|
|||||||
const [libraries] = useState<ContentLibrary[]>(mockLibraries);
|
const [libraries] = useState<ContentLibrary[]>(mockLibraries);
|
||||||
|
|
||||||
const filteredLibraries = libraries.filter(library =>
|
const filteredLibraries = libraries.filter(library =>
|
||||||
library.name.toLowerCase().includes(searchTerm.toLowerCase())
|
library.name.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleLibraryToggle = (library: ContentLibrary, checked: boolean) => {
|
const handleLibraryToggle = (library: ContentLibrary, checked: boolean) => {
|
||||||
|
|||||||
@@ -101,7 +101,9 @@ const GroupSelector: React.FC<GroupSelectorProps> = ({
|
|||||||
const filteredGroups = groups.filter(
|
const filteredGroups = groups.filter(
|
||||||
group =>
|
group =>
|
||||||
group.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
group.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
group.serviceAccount.name.toLowerCase().includes(searchTerm.toLowerCase())
|
group.serviceAccount.name
|
||||||
|
.toLowerCase()
|
||||||
|
.includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleGroupToggle = (group: WechatGroup, checked: boolean) => {
|
const handleGroupToggle = (group: WechatGroup, checked: boolean) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import request from "@/api/request";
|
import request from "@/api/request";
|
||||||
export async function createGroupPushTask(
|
export async function createGroupPushTask(
|
||||||
taskData: Partial<GroupPushTask>
|
taskData: Partial<GroupPushTask>,
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return request("/v1/workspace/group-push/tasks", taskData, "POST");
|
return request("/v1/workspace/group-push/tasks", taskData, "POST");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,12 +40,12 @@ export async function deleteGroupPushTask(id: string): Promise<ApiResponse> {
|
|||||||
|
|
||||||
export async function toggleGroupPushTask(
|
export async function toggleGroupPushTask(
|
||||||
id: string,
|
id: string,
|
||||||
status: string
|
status: string,
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return request(
|
return request(
|
||||||
`/v1/workspace/group-push/tasks/${id}/toggle`,
|
`/v1/workspace/group-push/tasks/${id}/toggle`,
|
||||||
{ status },
|
{ status },
|
||||||
"POST"
|
"POST",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,20 +54,20 @@ export async function copyGroupPushTask(id: string): Promise<ApiResponse> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createGroupPushTask(
|
export async function createGroupPushTask(
|
||||||
taskData: Partial<GroupPushTask>
|
taskData: Partial<GroupPushTask>,
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return request("/v1/workspace/group-push/tasks", taskData, "POST");
|
return request("/v1/workspace/group-push/tasks", taskData, "POST");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateGroupPushTask(
|
export async function updateGroupPushTask(
|
||||||
id: string,
|
id: string,
|
||||||
taskData: Partial<GroupPushTask>
|
taskData: Partial<GroupPushTask>,
|
||||||
): Promise<ApiResponse> {
|
): Promise<ApiResponse> {
|
||||||
return request(`/v1/workspace/group-push/tasks/${id}`, taskData, "PUT");
|
return request(`/v1/workspace/group-push/tasks/${id}`, taskData, "PUT");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getGroupPushTaskDetail(
|
export async function getGroupPushTaskDetail(
|
||||||
id: string
|
id: string,
|
||||||
): Promise<GroupPushTask> {
|
): Promise<GroupPushTask> {
|
||||||
return request(`/v1/workspace/group-push/tasks/${id}`);
|
return request(`/v1/workspace/group-push/tasks/${id}`);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ const GroupPush: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filteredTasks = tasks.filter(task =>
|
const filteredTasks = tasks.filter(task =>
|
||||||
task.name.toLowerCase().includes(searchTerm.toLowerCase())
|
task.name.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
const getStatusColor = (status: number) => {
|
const getStatusColor = (status: number) => {
|
||||||
@@ -361,7 +361,7 @@ const GroupPush: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
<Progress
|
<Progress
|
||||||
percent={Math.round(
|
percent={Math.round(
|
||||||
(task.pushCount / task.maxPushPerDay) * 100
|
(task.pushCount / task.maxPushPerDay) * 100,
|
||||||
)}
|
)}
|
||||||
size="small"
|
size="small"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ const MomentsSyncDetail: React.FC = () => {
|
|||||||
await request(
|
await request(
|
||||||
"/v1/workbench/update-status",
|
"/v1/workbench/update-status",
|
||||||
{ id, status: newStatus },
|
{ id, status: newStatus },
|
||||||
"POST"
|
"POST",
|
||||||
);
|
);
|
||||||
setTask({ ...task, status: newStatus });
|
setTask({ ...task, status: newStatus });
|
||||||
message.success(newStatus === 1 ? "任务已开启" : "任务已暂停");
|
message.success(newStatus === 1 ? "任务已开启" : "任务已暂停");
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ const MomentsSync: React.FC = () => {
|
|||||||
const res = await request(
|
const res = await request(
|
||||||
"/v1/workbench/list",
|
"/v1/workbench/list",
|
||||||
{ type: 2, page: 1, limit: 100 },
|
{ type: 2, page: 1, limit: 100 },
|
||||||
"GET"
|
"GET",
|
||||||
);
|
);
|
||||||
setTasks(res.list || []);
|
setTasks(res.list || []);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -96,10 +96,10 @@ const MomentsSync: React.FC = () => {
|
|||||||
await request(
|
await request(
|
||||||
"/v1/workbench/update-status",
|
"/v1/workbench/update-status",
|
||||||
{ id, status: newStatus },
|
{ id, status: newStatus },
|
||||||
"POST"
|
"POST",
|
||||||
);
|
);
|
||||||
setTasks(prev =>
|
setTasks(prev =>
|
||||||
prev.map(t => (t.id === id ? { ...t, status: newStatus } : t))
|
prev.map(t => (t.id === id ? { ...t, status: newStatus } : t)),
|
||||||
);
|
);
|
||||||
message.success("操作成功");
|
message.success("操作成功");
|
||||||
} catch {
|
} catch {
|
||||||
@@ -108,7 +108,7 @@ const MomentsSync: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const filteredTasks = tasks.filter(task =>
|
const filteredTasks = tasks.filter(task =>
|
||||||
task.name.toLowerCase().includes(searchTerm.toLowerCase())
|
task.name.toLowerCase().includes(searchTerm.toLowerCase()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// 菜单
|
// 菜单
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ export const getTrafficDistributionDetail = (id: string) => {
|
|||||||
|
|
||||||
// 更新流量分发
|
// 更新流量分发
|
||||||
export const updateTrafficDistribution = (
|
export const updateTrafficDistribution = (
|
||||||
data: TrafficDistributionFormData
|
data: TrafficDistributionFormData,
|
||||||
) => {
|
) => {
|
||||||
return request("/v1/workbench/update", data, "POST");
|
return request("/v1/workbench/update", data, "POST");
|
||||||
};
|
};
|
||||||
|
|
||||||
// 创建流量分发
|
// 创建流量分发
|
||||||
export const createTrafficDistribution = (
|
export const createTrafficDistribution = (
|
||||||
data: TrafficDistributionFormData
|
data: TrafficDistributionFormData,
|
||||||
) => {
|
) => {
|
||||||
return request("/v1/workbench/create", data, "POST");
|
return request("/v1/workbench/create", data, "POST");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -393,7 +393,7 @@ const TrafficDistributionForm: React.FC = () => {
|
|||||||
setSelectedPools(val =>
|
setSelectedPools(val =>
|
||||||
e.target.checked
|
e.target.checked
|
||||||
? [...val, pool.id]
|
? [...val, pool.id]
|
||||||
: val.filter(v => v !== pool.id)
|
: val.filter(v => v !== pool.id),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export function updateDistributionRule(data: any): Promise<any> {
|
|||||||
// 暂停/启用计划
|
// 暂停/启用计划
|
||||||
export function toggleDistributionRuleStatus(
|
export function toggleDistributionRuleStatus(
|
||||||
id: number,
|
id: number,
|
||||||
status: 0 | 1
|
status: 0 | 1,
|
||||||
): Promise<any> {
|
): Promise<any> {
|
||||||
return request("/v1/workbench/update-status", { id, status }, "POST");
|
return request("/v1/workbench/update-status", { id, status }, "POST");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ const TrafficDistributionList: React.FC = () => {
|
|||||||
// 新增:Switch点击切换计划状态
|
// 新增:Switch点击切换计划状态
|
||||||
const handleSwitchChange = async (
|
const handleSwitchChange = async (
|
||||||
checked: boolean,
|
checked: boolean,
|
||||||
item: DistributionRule
|
item: DistributionRule,
|
||||||
) => {
|
) => {
|
||||||
setMenuLoadingId(item.id);
|
setMenuLoadingId(item.id);
|
||||||
try {
|
try {
|
||||||
@@ -124,8 +124,8 @@ const TrafficDistributionList: React.FC = () => {
|
|||||||
// 本地只更新当前item的status,不刷新全列表
|
// 本地只更新当前item的status,不刷新全列表
|
||||||
setList(prevList =>
|
setList(prevList =>
|
||||||
prevList.map(rule =>
|
prevList.map(rule =>
|
||||||
rule.id === item.id ? { ...rule, status: checked ? 1 : 0 } : rule
|
rule.id === item.id ? { ...rule, status: checked ? 1 : 0 } : rule,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
message.error("操作失败");
|
message.error("操作失败");
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ export const getRouteTitle = (path: string): string => {
|
|||||||
// 检查路由权限
|
// 检查路由权限
|
||||||
export const checkRoutePermission = (
|
export const checkRoutePermission = (
|
||||||
path: string,
|
path: string,
|
||||||
userRole: string = "user"
|
userRole: string = "user",
|
||||||
): boolean => {
|
): boolean => {
|
||||||
const allowedRoutes =
|
const allowedRoutes =
|
||||||
routePermissions[userRole as keyof typeof routePermissions] || [];
|
routePermissions[userRole as keyof typeof routePermissions] || [];
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Object.values(modules).forEach((mod: any) => {
|
|||||||
|
|
||||||
// 权限包装
|
// 权限包装
|
||||||
function wrapWithPermission(
|
function wrapWithPermission(
|
||||||
route: RouteObject & { auth?: boolean; requiredRole?: string }
|
route: RouteObject & { auth?: boolean; requiredRole?: string },
|
||||||
) {
|
) {
|
||||||
if (route.auth) {
|
if (route.auth) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import { persist, PersistOptions } from "zustand/middleware";
|
|||||||
export function createPersistStore<T>(
|
export function createPersistStore<T>(
|
||||||
createState: (set: any, get: any) => T,
|
createState: (set: any, get: any) => T,
|
||||||
name: string,
|
name: string,
|
||||||
partialize?: (state: T) => Partial<T>
|
partialize?: (state: T) => Partial<T>,
|
||||||
) {
|
) {
|
||||||
return create<T>()(
|
return create<T>()(
|
||||||
persist(createState, {
|
persist(createState, {
|
||||||
name,
|
name,
|
||||||
partialize,
|
partialize,
|
||||||
} as PersistOptions<T>)
|
} as PersistOptions<T>),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,5 +70,5 @@ export const useUserStore = createPersistStore<UserState>(
|
|||||||
user: state.user,
|
user: state.user,
|
||||||
token: state.token,
|
token: state.token,
|
||||||
isLoggedIn: state.isLoggedIn,
|
isLoggedIn: state.isLoggedIn,
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const comfirm = (
|
|||||||
title?: string;
|
title?: string;
|
||||||
cancelText?: string;
|
cancelText?: string;
|
||||||
confirmText?: string;
|
confirmText?: string;
|
||||||
}
|
},
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
Modal.show({
|
Modal.show({
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"strict": true,
|
"strict": false,
|
||||||
|
"noImplicitAny": false,
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
|
|||||||
Reference in New Issue
Block a user