diff --git a/Cunkebao/.eslintrc.js b/Cunkebao/.eslintrc.js new file mode 100644 index 00000000..72eb95a9 --- /dev/null +++ b/Cunkebao/.eslintrc.js @@ -0,0 +1,40 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'react'], + extends: [ + 'eslint:recommended', + 'plugin:react/recommended', + 'plugin:@typescript-eslint/recommended', + 'react-app', + 'react-app/jest', + ], + env: { + browser: true, + es2021: true, + node: true, + }, + settings: { + react: { + version: 'detect', + }, + }, + parserOptions: { + ecmaFeatures: { + jsx: true, + }, + ecmaVersion: 'latest', + sourceType: 'module', + }, + rules: { + 'react/react-in-jsx-scope': 'off', + '@typescript-eslint/no-unused-vars': [ + 'warn', + { argsIgnorePattern: '^_', varsIgnorePattern: '^_' } + ], + 'react/prop-types': 'off', + 'no-console': 'warn', + 'no-debugger': 'warn', + }, + ignorePatterns: ['node_modules/', 'build/', 'dist/'], +}; \ No newline at end of file diff --git a/Cunkebao/src/api/scenarios.ts b/Cunkebao/src/api/scenarios.ts index 88e10dc1..ee3774a1 100644 --- a/Cunkebao/src/api/scenarios.ts +++ b/Cunkebao/src/api/scenarios.ts @@ -308,4 +308,20 @@ export async function createScenarioPlan(data: any) { // 编辑计划 export async function updateScenarioPlan(planId: number | string, data: any) { return await put(`/v1/plan/update?planId=${planId}`, data); -} \ No newline at end of file +} + +/** + * 获取计划小程序二维码 + * @param taskid 任务ID + * @returns base64二维码 + */ +export const getWxMinAppCode = async (taskId: string): Promise<{ code: number; data?: string; msg?: string }> => { + try { + return await get<{ code: number; data?: string; msg?: string }>( + `/v1/plan/getWxMinAppCode?taskId=${ taskId }`, + + ); + } catch (error) { + return { code: 500, msg: '获取小程序二维码失败' }; + } +}; \ No newline at end of file diff --git a/Cunkebao/src/pages/scenarios/ScenarioList.tsx b/Cunkebao/src/pages/scenarios/ScenarioList.tsx index 6c110961..7ab94cb3 100644 --- a/Cunkebao/src/pages/scenarios/ScenarioList.tsx +++ b/Cunkebao/src/pages/scenarios/ScenarioList.tsx @@ -15,6 +15,7 @@ import { Code, Search, RefreshCw, + QrCode, } from "lucide-react"; import { fetchPlanList, @@ -22,6 +23,7 @@ import { copyPlan, deletePlan, type Task, + getWxMinAppCode, } from "@/api/scenarios"; import { useToast } from "@/components/ui/toast"; import "@/components/Layout.css"; @@ -65,6 +67,10 @@ export default function ScenarioDetail() { }); const [searchTerm, setSearchTerm] = useState(""); const [loadingTasks, setLoadingTasks] = useState(false); + // 二维码弹窗相关 + const [showQrDialog, setShowQrDialog] = useState(false); + const [qrLoading, setQrLoading] = useState(false); + const [qrImg, setQrImg] = useState(""); // 获取渠道中文名称 const getChannelName = (channel: string) => { @@ -250,29 +256,6 @@ export default function ScenarioDetail() { } }; - const handleStatusChange = async (taskId: string, newStatus: 1 | 0) => { - try { - // 这里应该调用状态切换API,暂时模拟 - setTasks((prev) => - prev.map((task) => - task.id === taskId ? { ...task, status: newStatus } : task - ) - ); - - toast({ - title: "状态已更新", - description: `计划已${newStatus === 1 ? "启动" : "暂停"}`, - }); - } catch (error) { - console.error("状态切换失败:", error); - toast({ - title: "状态切换失败", - description: "请稍后重试", - variant: "destructive", - }); - } - }; - const handleOpenApiSettings = async (taskId: string) => { try { const response = await fetchPlanDetail(taskId); @@ -310,6 +293,32 @@ export default function ScenarioDetail() { navigate(`/scenarios/new/${scenarioId}`); }; + const handleShowQrCode = async (taskId: string) => { + setShowQrDialog(true); + setQrLoading(true); + setQrImg(""); + try { + const res = await getWxMinAppCode(taskId); + if (res.data) { + setQrImg(res.data); + } else { + toast({ + title: "获取二维码失败", + description: res?.msg || "未知错误", + variant: "destructive", + }); + } + } catch (e) { + toast({ + title: "获取二维码失败", + description: "网络错误", + variant: "destructive", + }); + } finally { + setQrLoading(false); + } + }; + const getStatusColor = (status: number) => { switch (status) { case 1: @@ -463,70 +472,75 @@ export default function ScenarioDetail() { ) : ( -