代码提交

This commit is contained in:
wong
2026-01-05 09:34:48 +08:00
parent b4c813311b
commit ce1c434ea8
5 changed files with 177 additions and 153 deletions

View File

@@ -10,5 +10,10 @@ export function getWechatStats() {
return request("/v1/dashboard/wechat-stats", {}, "GET"); return request("/v1/dashboard/wechat-stats", {}, "GET");
} }
// 获取常用功能列表
export function getCommonFunctions() {
return request("/v1/workbench/common-functions", {}, "GET");
}
// 你可以根据需要继续添加其他接口 // 你可以根据需要继续添加其他接口
// 例如:场景获客统计、今日数据统计等 // 例如:场景获客统计、今日数据统计等

View File

@@ -52,8 +52,10 @@
margin-bottom: 12px; margin-bottom: 12px;
} }
.icon { .iconImage {
font-size: 20px; width: 75%;
object-fit: contain;
border-radius: 8px;
} }
.featureHeader { .featureHeader {

View File

@@ -1,128 +1,137 @@
import React from "react"; import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { Card, Badge } from "antd-mobile"; import { Card, Badge, SpinLoading, Toast } from "antd-mobile";
import {
LikeOutlined,
SendOutlined,
TeamOutlined,
LinkOutlined,
ClockCircleOutlined,
ContactsOutlined,
BookOutlined,
ApartmentOutlined,
} from "@ant-design/icons";
import Layout from "@/components/Layout/Layout"; import Layout from "@/components/Layout/Layout";
import MeauMobile from "@/components/MeauMobile/MeauMoible"; import MeauMobile from "@/components/MeauMobile/MeauMoible";
import styles from "./index.module.scss"; import styles from "./index.module.scss";
import NavCommon from "@/components/NavCommon"; import NavCommon from "@/components/NavCommon";
import { getCommonFunctions } from "./api";
// 功能key到默认配置的映射用于降级当API没有返回icon时使用
const featureConfig: Record<string, {
bgColor: string;
path: string;
}> = {
"auto_like": {
bgColor: "#fff2f0",
path: "/workspace/auto-like",
},
"moments_sync": {
bgColor: "#f9f0ff",
path: "/workspace/moments-sync",
},
"group_push": {
bgColor: "#fff7e6",
path: "/workspace/group-push",
},
"auto_group": {
bgColor: "#f6ffed",
path: "/workspace/auto-group",
},
"group_create": {
bgColor: "#f6ffed",
path: "/workspace/group-create",
},
"traffic_distribution": {
bgColor: "#e6f7ff",
path: "/workspace/traffic-distribution",
},
"contact_import": {
bgColor: "#f9f0ff",
path: "/workspace/contact-import/list",
},
"ai_knowledge": {
bgColor: "#fff7e6",
path: "/workspace/ai-knowledge",
},
"distribution_management": {
bgColor: "#f9f0ff",
path: "/workspace/distribution-management",
},
};
interface CommonFunction {
id: number;
key: string;
name: string;
description?: string;
icon: React.ReactNode | null;
iconUrl?: string | null;
path: string;
bgColor?: string;
isNew?: boolean;
[key: string]: any;
}
const Workspace: React.FC = () => { const Workspace: React.FC = () => {
// 常用功能 const [commonFeatures, setCommonFeatures] = useState<CommonFunction[]>([]);
const commonFeatures = [ const [loading, setLoading] = useState(true);
{
id: "auto-like", // 从API获取常用功能
name: "自动点赞", useEffect(() => {
description: "智能自动点赞互动", const fetchCommonFunctions = async () => {
icon: ( try {
<LikeOutlined className={styles.icon} style={{ color: "#ff4d4f" }} /> setLoading(true);
), const res = await getCommonFunctions();
path: "/workspace/auto-like", // 处理API返回的数据映射图标和样式
bgColor: "#fff2f0", const features = (res?.list || res || []).map((item: any) => {
isNew: true, const config = featureConfig[item.key];
},
{ // icon是远程图片URL渲染为img标签
id: "moments-sync", const iconElement = item.icon ? (
name: "朋友圈同步", <img
description: "自动同步朋友圈内容", src={item.icon}
icon: ( alt={item.title || ""}
<ClockCircleOutlined className={styles.iconImage}
className={styles.icon} onError={(e) => {
style={{ color: "#722ed1" }} // 图片加载失败时,隐藏图片
/> const target = e.target as HTMLImageElement;
), target.style.display = 'none';
path: "/workspace/moments-sync", }}
bgColor: "#f9f0ff", />
}, ) : null;
{
id: "group-push", return {
name: "群消息推送", id: item.id,
description: "智能群发助手", key: item.key,
icon: ( name: item.title || item.name || "",
<SendOutlined className={styles.icon} style={{ color: "#fa8c16" }} /> description: item.subtitle || item.description || item.desc || "",
), icon: iconElement,
path: "/workspace/group-push", iconUrl: item.icon || null, // 保存原始URL
bgColor: "#fff7e6", path: item.route || item.path || (config?.path) || `/workspace/${item.key?.replace(/_/g, '-')}`,
}, bgColor: item.iconColor || (config?.bgColor) || undefined, // iconColor可以为空
{ isNew: item.isNew || item.is_new || false,
id: "auto-group", };
name: "自动建群", });
description: "智能拉好友建群", setCommonFeatures(features);
icon: ( } catch (e: any) {
<TeamOutlined className={styles.icon} style={{ color: "#52c41a" }} /> Toast.show({
), content: e?.message || "获取常用功能失败",
path: "/workspace/auto-group", position: "top",
bgColor: "#f6ffed", });
}, // 如果接口失败,使用默认数据(从配置映射表生成)
{ const defaultFeatures = Object.keys(featureConfig).map((key, index) => {
id: "group-create", const config = featureConfig[key];
name: "自动建群(新版)", return {
description: "智能拉好友建群", id: index + 1,
icon: ( key,
<TeamOutlined className={styles.icon} style={{ color: "#52c41a" }} /> name: key.replace(/_/g, ' '),
), description: "",
path: "/workspace/group-create", icon: null, // 默认没有图标
bgColor: "#f6ffed", iconUrl: null,
isNew: true, path: config.path,
}, bgColor: config.bgColor,
{ isNew: false,
id: "traffic-distribution", };
name: "流量分发", });
description: "管理流量分发和分配", setCommonFeatures(defaultFeatures);
icon: ( } finally {
<LinkOutlined className={styles.icon} style={{ color: "#1890ff" }} /> setLoading(false);
), }
path: "/workspace/traffic-distribution", };
bgColor: "#e6f7ff",
}, fetchCommonFunctions();
{ }, []);
id: "contact-import",
name: "通讯录导入",
description: "批量导入通讯录联系人",
icon: (
<ContactsOutlined
className={styles.icon}
style={{ color: "#722ed1" }}
/>
),
path: "/workspace/contact-import/list",
bgColor: "#f9f0ff",
isNew: true,
},
{
id: "ai-knowledge",
name: "AI知识库",
description: "管理和配置内容",
icon: (
<BookOutlined className={styles.icon} style={{ color: "#fa8c16" }} />
),
path: "/workspace/ai-knowledge",
bgColor: "#fff7e6",
isNew: true,
},
{
id: "distribution-management",
name: "分销管理",
description: "管理分销客户和渠道",
icon: (
<ApartmentOutlined
className={styles.icon}
style={{ color: "#722ed1" }}
/>
),
path: "/workspace/distribution-management",
bgColor: "#f9f0ff",
isNew: true,
},
];
return ( return (
<Layout <Layout
@@ -133,33 +142,45 @@ const Workspace: React.FC = () => {
{/* 常用功能 */} {/* 常用功能 */}
<div className={styles.section}> <div className={styles.section}>
<h2 className={styles.sectionTitle}></h2> <h2 className={styles.sectionTitle}></h2>
<div className={styles.featuresGrid}> {loading ? (
{commonFeatures.map(feature => ( <div style={{ display: "flex", justifyContent: "center", padding: "40px 0" }}>
<Link <SpinLoading style={{ "--size": "32px" }} />
to={feature.path} </div>
key={feature.id} ) : (
className={styles.featureLink} <div className={styles.featuresGrid}>
> {commonFeatures.length > 0 ? (
<Card className={styles.featureCard}> commonFeatures.map(feature => (
<div <Link
className={styles.featureIcon} to={feature.path}
style={{ backgroundColor: feature.bgColor }} key={feature.key || feature.id}
className={styles.featureLink}
> >
{feature.icon} <Card className={styles.featureCard}>
</div> <div
<div className={styles.featureHeader}> className={styles.featureIcon}
<div className={styles.featureName}>{feature.name}</div> style={{ backgroundColor: feature.bgColor || "transparent" }}
{feature.isNew && ( >
<Badge content="New" className={styles.newBadge} /> {feature.icon}
)} </div>
</div> <div className={styles.featureHeader}>
<div className={styles.featureDescription}> <div className={styles.featureName}>{feature.name}</div>
{feature.description} {feature.isNew && (
</div> <Badge content="New" className={styles.newBadge} />
</Card> )}
</Link> </div>
))} <div className={styles.featureDescription}>
</div> {feature.description}
</div>
</Card>
</Link>
))
) : (
<div style={{ textAlign: "center", padding: "40px 0", color: "#999", width: "100%" }}>
</div>
)}
</div>
)}
</div> </div>
{/* AI智能助手 */} {/* AI智能助手 */}

View File

@@ -119,6 +119,7 @@ Route::group('v1/', function () {
Route::get('group-push-stats', 'app\cunkebao\controller\workbench\WorkbenchController@getGroupPushStats'); // 获取群发统计数据 Route::get('group-push-stats', 'app\cunkebao\controller\workbench\WorkbenchController@getGroupPushStats'); // 获取群发统计数据
Route::get('group-push-history', 'app\cunkebao\controller\workbench\WorkbenchController@getGroupPushHistory'); // 获取推送历史记录列表 Route::get('group-push-history', 'app\cunkebao\controller\workbench\WorkbenchController@getGroupPushHistory'); // 获取推送历史记录列表
Route::get('common-functions', 'app\cunkebao\controller\workbench\CommonFunctionsController@getList'); // 获取常用功能列表
}); });
// 内容库相关 // 内容库相关
@@ -162,11 +163,6 @@ Route::group('v1/', function () {
Route::get('userInfoStats', 'app\cunkebao\controller\StatsController@userInfoStats'); Route::get('userInfoStats', 'app\cunkebao\controller\StatsController@userInfoStats');
}); });
// 常用功能相关
Route::group('common-functions', function () {
Route::get('list', 'app\cunkebao\controller\CommonFunctionsController@getList'); // 获取常用功能列表
});
// 算力相关 // 算力相关
Route::group('tokens', function () { Route::group('tokens', function () {
Route::get('list', 'app\cunkebao\controller\TokensController@getList'); Route::get('list', 'app\cunkebao\controller\TokensController@getList');

View File

@@ -1,6 +1,6 @@
<?php <?php
namespace app\cunkebao\controller; namespace app\cunkebao\controller\workbench;
use app\cunkebao\controller\BaseController; use app\cunkebao\controller\BaseController;
use library\ResponseHelper; use library\ResponseHelper;