Browse Source

feat: 单独抽离ai助手页面

jiaxing.liao 1 month ago
parent
commit
88b38a8d27

+ 1 - 1
.env

@@ -1,2 +1,2 @@
 CHECK_TIMEOUT=5
-BASE_URL=http://a.dev.jbpm.shalu.com/
+BASE_URL=https://design.shalu.com

+ 2 - 29
.umirc.ts

@@ -3,13 +3,13 @@ import { defineConfig } from "umi";
 export default defineConfig({
   base: "/",
   publicPath: process.env.NODE_ENV === "production" ? "./" : "/",
-  outputPath: "marketplace",
+  outputPath: "aiAssistant",
   esbuildMinifyIIFE: true,
   favicons: [],
   styles: ["//at.alicdn.com/t/c/font_4840729_5okrvkvahe7.css"],
   scripts: ["//at.alicdn.com/t/c/font_4840729_qpwqs1eruu.js"],
   model: {},
-  title: "易码工坊",
+  title: "易码工坊-AI助手",
   metas: [
     {
       name: "viewport",
@@ -43,36 +43,9 @@ export default defineConfig({
   routes: [
     {
       path: "/",
-      redirect: "/application",
-    },
-    {
-      path: "/application",
-      component: "application",
-    },
-    {
-      path: "/template",
-      component: "template",
-    },
-    {
-      // type: application or template
-      path: "/detail/:type/:id",
-      component: "detail",
-    },
-    {
-      path: '/management',
-      component: 'management',
-      layout: false
-    },
-    {
-      path: '/ai',
       component: 'ai',
       layout: false
     },
-    {
-      path: '/apply',
-      component: 'apply',
-      layout: false
-    },
     {
       path: '*',
       component: '404',

+ 47 - 0
README.md

@@ -0,0 +1,47 @@
+### 环境:
+- node v20.x
+- pnpm v10.x
+
+### 安装依赖:
+pnpm i
+
+### 运行:
+pnpm run dev
+
+### 构建:
+pnpm run build
+
+### 修改AI助手配置:
+src/pages/ai/index.tsx
+```typescript
+const assistant = {
+  key: "normal_ask",
+  name: "综合问答",
+  icon: logo,
+  description: "基于LLM的智能助手,可以进行各种使用查询、知识问答等~",
+  promptsItems: [
+    {
+      key: "1",
+      icon: <CoffeeOutlined style={{ color: "#964B00" }} />,
+      description: "怎么创建我的应用?",
+    },
+    {
+      key: "2",
+      icon: <SmileOutlined style={{ color: "#FAAD14" }} />,
+      description: "页面设计器如何使用?",
+    },
+    {
+      key: "3",
+      icon: <FireOutlined style={{ color: "#FF4D4F" }} />,
+      description: "如何生成页面SQL?",
+    },
+  ],
+};
+```
+
+### 对话接口基础地址
+.env
+修改BASE_URL
+
+### 对话方法封装
+src/hooks/useChat.ts

File diff suppressed because it is too large
+ 10456 - 7451
pnpm-lock.yaml


+ 0 - 115
src/api/appStore.ts

@@ -1,115 +0,0 @@
-import { request } from "umi";
-import type { commonParams } from "@/api/index";
-
-/**
- * 获取应用管理列表
- * @param commonParams
- * @returns
- */
-export const GetAppList = (data: commonParams) => {
-  return request("/api/appStore/applicationTemplate/list", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 获取应用市场列表
- * @param commonParams
- * @returns
- */
-export const GetAppPublicList = (data: commonParams) => {
-  return request("/api/appStore/public/applicationTemplate/list", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 获取应用详情
- * @param commonParams
- * @returns
- */
-export const GetAppDetail = (data: { id: string }) => {
-  return request("/api/appStore/public/applicationTemplate/detail", {
-    method: "POST",
-    data,
-  });
-};
-
-export type AppItem = {
-  id?: string;
-  name: string;
-  applicationId: string;
-  icon: string;
-  desc: string;
-  industries: string;
-  applicationScenarios: string;
-  tags: string;
-  price: number;
-  detail: string;
-  isOnMarket: boolean;
-  isFree: boolean;
-  version?: string;
-  trialUrl?: string;
-};
-
-/**
- * 新增修改应用
- * @param AddItem
- * @returns
- */
-export const SaveOrUpdateApp = (data: AppItem) => {
-  return request("/api/appStore/applicationTemplate/saveOrUpdate", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 上架应用
- * @param ids
- * @returns
- */
-export const OnMarketApp = (data: { ids: string[] }) => {
-  return request("/api/appStore/applicationTemplate/onMarket", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 下架应用
- * @param ids
- * @returns
- */
-export const OffMarketApp = (data: { ids: string[] }) => {
-  return request("/api/appStore/applicationTemplate/offMarket", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 批量删除应用
- * @param ids
- * @returns
- */
-export const DeleteAppTemplate = (data: { ids: string[] }) => {
-  return request("/api/appStore/applicationTemplate/batchDelete", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 批量物理删除应用
- * @param ids
- * @returns
- */
-export const ForceDeleteAppTemplate = (data: { ids: string[] }) => {
-  return request("/api/appStore/applicationTemplate/forceDelete", {
-    method: "POST",
-    data,
-  });
-};

+ 0 - 67
src/api/apply.ts

@@ -1,67 +0,0 @@
-import { request } from "umi";
-import type { commonParams } from "@/api/index";
-
-/**
- * 获取咨询申请列表
- * @param commonParams
- * @returns
- */
-export const GetApplyList = (data: commonParams) => {
-  return request("/api/appStore/consultationForm/list", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 获取咨询申请详情
- * @param {id: string}
- * @returns
- */
-export const GetApplyDetail = (data: {id: string}) => {
-  return request("/api/appStore/consultationForm/detail", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 提交咨询申请
- * @param ApplyItem
- * @returns
- */
-export const SubmitApply = (data: ApplyItem) => {
-  return request("/api/appStore/public/consultationForm/add", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 处理咨询申请
- * @param ApplyItem
- * @returns
- */
-export const HandleApply = (data: ApplyHandle) => {
-  return request("/api/appStore/consultationForm/process", {
-    method: "POST",
-    data,
-  });
-};
-
-export type ApplyItem = {
-  name: string;
-  tel: string;
-  companyName: string;
-  companySize: string;
-  jobTitle: string;
-  templateId: string;
-  // 0: 应用模版 1: 模块模板
-  type: number;
-}
-
-export type ApplyHandle = {
-  id: string;
-  status: number;
-  processRemark: string;
-}

+ 0 - 114
src/api/templateStore.ts

@@ -1,114 +0,0 @@
-import { request } from "umi";
-import type { commonParams } from "@/api/index";
-
-/**
- * 获取模版管理列表
- * @param commonParams
- * @returns
- */
-export const GetTemplateList = (data: commonParams) => {
-  return request("/api/templateStore/moduleTemplate/list", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 获取模版市场列表
- * @param commonParams
- * @returns
- */
-export const GetTemplatePublicList = (data: commonParams) => {
-  return request("/api/templateStore/public/moduleTemplate/list", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 获取模版详情
- * @param id
- * @returns
- */
-export const GetTemplateDetail = (data: { id: string}) => {
-  return request("/api/templateStore/public/moduleTemplate/detail", {
-    method: "POST",
-    data,
-  });
-};
-
-type AddItem = {
-  "name": string,
-  "applicationId": string,
-  "moduleId": string,
-  "type": number, // 模板类型,系统设计、数据模型、页面设计、页面代码、流程模型、文档模型等
-  "icon": string,
-  "desc": string,
-  "industries": string,
-  "applicationScenarios": string,
-  "tags": string,
-  "price": number,
-  "detail": string,
-  "isOnMarket": boolean,
-  "isFree": boolean
-}
-
-/**
- * 新增修改模版
- * @param AddItem
- * @returns
- */
-export const SaveOrUpdateTemplate = (data: AddItem) => {
-  return request("/api/templateStore/moduleTemplate/saveOrUpdate", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 上架模版
- * @param ids
- * @returns
- */
-export const OnMarketTemplate = (data: {ids: string[]}) => {
-  return request("/api/templateStore/moduleTemplate/onMarket", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 下架模版
- * @param ids
- * @returns
- */
-export const OffMarketTemplate = (data: {ids: string[]}) => {
-  return request("/api/templateStore/moduleTemplate/offMarket", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 批量删除应用
- * @param ids
- * @returns
- */
-export const DeleteTemplate = (data: {ids: string[]}) => {
-  return request("/api/templateStore/moduleTemplate/batchDelete", {
-    method: "POST",
-    data,
-  });
-};
-
-/**
- * 批量物理删除应用
- * @param ids
- * @returns
- */
-export const ForceDeleteTemplate = (data: {ids: string[]}) => {
-  return request("/api/templateStore/moduleTemplate/forceDelete", {
-    method: "POST",
-    data,
-  });
-};

+ 1 - 3
src/app.ts

@@ -53,8 +53,7 @@ export const request: RequestConfig = {
   },
   requestInterceptors: [
     (url, options) => {
-      const baseUrl = process.env.NODE_ENV === 'production' ? '' : '/api'//'http://ab.dev.jbpm.shalu.com' // https://edesign.shalu.com'
-      // const enterpriseCode = sessionStorage.getItem('enterpriseCode');
+      const baseUrl = process.env.NODE_ENV === 'production' ? '' : '/api';
       const enterpriseCode = 'a';
       const token = localStorage.getItem('token_' + enterpriseCode);
  
@@ -75,7 +74,6 @@ export const request: RequestConfig = {
     (response) => {
       const {data = {} as any, config} = response;
       if(data?.error) {
-        // message.error(data.error);
         return Promise.reject(data.error);
       }
       

+ 0 - 84
src/components/Editor.tsx

@@ -1,84 +0,0 @@
-import '@wangeditor/editor/dist/css/style.css' // 引入 css
-
-import React, { useState, useEffect } from 'react'
-import { Editor, Toolbar } from '@wangeditor/editor-for-react'
-import { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
-import { UploadFile, GetFile } from "@/api"
-
-type InsertFnType = (url: string, poster: string) => void
-export default ({
-  html,
-  onChange
-}: {
-  html: string,
-  onChange: (html: string) => void
-}) => {
-  // editor 实例
-  const [editor, setEditor] = useState<IDomEditor | null>(null)
-
-  // 工具栏配置
-  const toolbarConfig: Partial<IToolbarConfig> = {}
-
-  // 自定义插入
-  const customInsert = (res: any, insertFn: InsertFnType) => {
-    console.log('自定义插入:', res);
-    // insertFn(url, alt, href)
-  };
-
-  // 自定义上传
-  const customUpload = async (file: File, insertFn: InsertFnType) => {
-    console.log('自定义上传:', file);
-    const form = new FormData();
-    form.append('file', file);
-    const res = await UploadFile(form);
-    
-    const fileId = res?.result?.[0]?.id;
-    insertFn(`/api/File/Download?fileId=${fileId}`, file.name);
-    return;
-  };
-
-  // 编辑器配置
-  const editorConfig: Partial<IEditorConfig> = {
-    placeholder: '请输入内容...',
-    MENU_CONF: {
-      uploadImage: {
-        customUpload,
-        customInsert
-      },
-      uploadVideo: {
-        customUpload,
-        customInsert
-      }
-    }
-  }
-
-  // 及时销毁 editor
-  useEffect(() => {
-    return () => {
-      if (editor == null) return
-      editor.destroy()
-      setEditor(null)
-    }
-  }, [editor])
-
-  return (
-    <>
-      <div style={{ border: '1px solid #ccc', zIndex: 100 }}>
-        <Toolbar
-          editor={editor}
-          defaultConfig={toolbarConfig}
-          mode="default"
-          style={{ borderBottom: '1px solid #ccc' }}
-        />
-        <Editor
-          defaultConfig={editorConfig}
-          value={html}
-          onCreated={setEditor}
-          onChange={(editor) => onChange?.(editor.getHtml())}
-          mode="default"
-          style={{ height: '500px', overflowY: 'hidden' }}
-        />
-      </div>
-    </>
-  )
-}

+ 0 - 91
src/components/ItemCard.tsx

@@ -1,91 +0,0 @@
-import React from "react";
-import { Button } from "antd";
-import { TagOutlined } from "@ant-design/icons";
-export default function AppItem({
-  data,
-  onClick,
-  extra,
-}: {
-  data: any;
-  onClick: (id: string) => void;
-  extra?: React.ReactNode
-}) {
-  return (
-    <div  
-      className="relative overflow-hidden pb-2 group col-span-1 bg-white border-2 border-solid border-transparent rounded-lg shadow-sm flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg"
-      onClick={() => onClick(data.id)}
-    >
-      {extra}
-      <div className="flex pt-[14px] px-[14px] pb-3 h-[66px] items-center gap-3 grow-0 shrink-0">
-        <div className="relative shrink-0">
-          <span
-            className="flex items-center justify-center relative rounded-lg grow-0 shrink-0 overflow-hidden w-10 h-10 text-[24px]"
-            style={{ background: "rgb(224, 242, 254)" }}
-          >
-            <img className="w-full h-full" src={`/api/File/Download?fileId=${data?.icon}`}/>
-          </span>
-        </div>
-        <div className="grow w-0 py-[1px]">
-          <div className="flex items-center text-sm leading-5 font-semibold text-text-secondary">
-            <div className="truncate" title={data?.name}>
-              {data?.name}
-            </div>
-          </div>
-          {/* <div className="flex items-center text-[10px] leading-[18px] text-text-tertiary font-medium">
-            <div className="truncate">作者 {data?.createByName || '易码工坊'}</div>
-          </div> */}
-        </div>
-      </div>
-      <div className="description-wrapper h-[90px] px-[14px] text-xs leading-normal text-text-tertiary ">
-        <div className="line-clamp-4 group-hover:line-clamp-2">
-          {data?.desc}
-        </div>
-      </div>
-      <div>
-        <div className="flex items-center h-5 px-[14px] text-12px">
-          <div className="flex items-center space-x-1 text-text-tertiary">
-            {/* <svg
-              viewBox="0 0 24 24"
-              xmlns="http://www.w3.org/2000/svg"
-              width="24"
-              height="24"
-              fill="currentColor"
-              className="remixicon shrink-0 w-3 h-3"
-            >
-              <path d="M9 2V4H5L4.999 14H18.999L19 4H15V2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V3C3 2.44772 3.44772 2 4 2H9ZM18.999 16H4.999L5 20H19L18.999 16ZM17 17V19H15V17H17ZM13 2V7H16L12 11L8 7H11V2H13Z"></path>
-            </svg> */}
-            <i className="iconfont icon-liulanliang"/>
-            <div className="system-xs-regular">{data?.viewCount || 0}</div>
-          </div>
-          <div className="mx-2 text-text-quaternary system-xs-regular">·</div>
-          <div className="flex flex-wrap space-x-2 h-4 overflow-hidden">
-            {
-              (data?.tags?.split(",") || []).map((tag: string, index: number) => {
-                return <div
-                key={index}
-                className="flex space-x-1 system-xs-regular max-w-[120px] overflow-hidden"
-                title={`# ${tag}`}
-              >
-                <span className="text-text-quaternary">#</span>
-                <span className="truncate text-text-tertiary">{tag}</span>
-              </div>
-              })
-            }
-          </div>
-        </div>
-      </div>
-      <div className="hidden items-center flex-wrap min-h-[42px] px-[14px] pt-2 pb-[10px] bg-white group-hover:flex absolute bottom-0 left-0 right-0">
-        <div className="flex items-center w-full space-x-2">
-          <Button
-            type="primary"
-            size="small"
-            className="w-full"
-            onClick={() => onClick(data.id)}
-          >
-            查看详情
-          </Button>
-        </div>
-      </div>
-    </div>
-  );
-}

+ 0 - 37
src/constants/index.ts

@@ -1,37 +0,0 @@
-// 行业选项
-export const INDUSTRIE_OPTIONS = [
-  {id: 1, label: '制造业', value: '制造业'},
-  {id: 2, label: '零售行业', value: '零售行业'},
-  {id: 3, label: '互联网科技', value: '互联网科技'},
-  {id: 4, label: '企业服务', value: '企业服务'},
-  {id: 5, label: '建筑工程', value: '建筑工程'},
-  {id: 6, label: '地产物业', value: '地产物业'},
-  {id: 7, label: '医疗健康', value: '医疗健康'},
-  {id: 8, label: '交通运输', value: '交通运输'},
-  {id: 9, label: '能源矿产', value: '能源矿产'},
-  {id: 10, label: '教育培训', value: '教育培训'},
-  {id: 11, label: '政府公益', value: '政府公益'}
-];
-
-// 应用场景
-export const APPLICATION_SCENARIOS_OPTIONS = [
-  {id: 1, label: '进销存/仓库', value: '进销存/仓库'},
-  {id: 2, label: 'CRM/仓库', value: 'CRM/仓库'},
-  {id: 3, label: 'ERP/生产', value: 'ERP/生产'},
-  {id: 4, label: '人事/行政', value: '人事/行政'},
-  {id: 5, label: '项目/任务', value: '项目/任务'},
-  {id: 6, label: '财务/报销', value: '财务/报销'},
-  {id: 7, label: '设备/巡检', value: '设备/巡检'},
-  {id: 8, label: '工单/售后', value: '工单/售后'},
-  {id: 9, label: '采招/供应', value: '采招/供应'}
-];
-
-// 模块模版类型
-export const MODULE_TEMPLATE_TYPE = [
-  {id: 1, label: '系统设计', value: '系统设计'},
-  {id: 2, label: '数据模型', value: '数据模型'},
-  {id: 3, label: '页面设计', value: '页面设计'},
-  {id: 4, label: '页面代码', value: '页面代码'},
-  {id: 5, label: '文档模版', value: '文档模版'},
-  {id: 6, label: '流程模版', value: '流程模版'},
-];

+ 3 - 1
src/hooks/useChat.ts

@@ -59,6 +59,8 @@ const defaultConversation = {
   group: '今日'
 };
 
+const BASE_URL = process.env.BASE_URL || 'https://design.shalu.com';
+
 export function useChat({ app_name, onSuccess, onUpdate, onError }: ChatProps) {
   /**
    * 发送消息加载状态
@@ -204,7 +206,7 @@ export function useChat({ app_name, onSuccess, onUpdate, onError }: ChatProps) {
       try {
         setLoading(true);
         const response = await fetch(
-          "https://design.shalu.com/api/ai/chat-message",
+          BASE_URL + "/api/ai/chat-message",
           {
             method: "POST",
             body: JSON.stringify(message),

+ 3 - 6
src/pages/ai/Assistant.tsx

@@ -39,7 +39,6 @@ import {
 } from "@ant-design/icons";
 import type { GetProp, GetRef } from "antd";
 import type { ConversationsProps } from "@ant-design/x";
-import type { AgentItem } from "./data";
 import MarkdownViewer from "@/components/ai/MarkdownViewer";
 import { ChangeSessionName, DeleteSession, AppParamenters } from "@/api/ai";
 import InfiniteScroll from "react-infinite-scroll-component";
@@ -48,10 +47,6 @@ import { UploadFile } from "@/api";
 import UserBubbleFooter from "./UserBubbleFooter";
 import AIBubbleFooter from "./AIBubbleFooter";
 
-type AssistantProps = {
-  agent?: AgentItem;
-};
-
 // bubbles角色配置
 const roles: GetProp<typeof Bubble.List, "roles"> = {
   assistant: {
@@ -87,7 +82,9 @@ const roles: GetProp<typeof Bubble.List, "roles"> = {
   },
 };
 
-export default (props: AssistantProps) => {
+export default (props: {
+  agent?: any;
+}) => {
   const [senderVal, setSenderVal] = useState("");
   const [supportFile, setSupportFile] = useState(false);
   const [fileLimit, setFileLimit] = useState(0);

+ 0 - 187
src/pages/ai/data.tsx

@@ -1,187 +0,0 @@
-import { SmileOutlined, CoffeeOutlined, FireOutlined } from "@ant-design/icons";
-import type { PromptsProps } from "@ant-design/x";
-
-import icon1 from "@/assets/icon-ai-1.png";
-import icon2 from "@/assets/icon-ai-2.png";
-import icon3 from "@/assets/icon-ai-3.png";
-import icon4 from "@/assets/icon-ai-4.png";
-import icon5 from "@/assets/icon-ai-5.png";
-import icon6 from "@/assets/icon-ai-6.png";
-
-export type AgentItem = {
-  key: string;
-  name: string;
-  icon: string;
-  description?: string;
-  promptsItems?: PromptsProps["items"]
-}
-
-export const assistantList: AgentItem[] = [
-  {
-    key: "normal_ask",
-    name: "综合问答",
-    icon: icon1,
-    description: "基于LLM的智能助手,可以进行各种使用查询、知识问答等~",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <CoffeeOutlined style={{ color: "#964B00" }} />,
-        description: "怎么创建我的应用?",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#FAAD14" }} />,
-        description: "页面设计器如何使用?",
-      },
-      {
-        key: "3",
-        icon: <FireOutlined style={{ color: "#FF4D4F" }} />,
-        description: "如何生成页面SQL?",
-      },
-    ],
-  },
-  {
-    key: "system_design",
-    name: "系统设计",
-    icon: icon2,
-    description: "可以进行各种系统方面的图形创建、使用说明,如: 流程图、系统架构图等等",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何创建流程图?",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何设置画布样式?",
-      },
-    ]
-  },
-  {
-    key: "data_model",
-    name: "数据模型",
-    icon: icon3,
-    description: "关于数据模型的一些问题~",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何创建表格?",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何使用在系统中使用数据模型?",
-      },
-    ]
-  },
-  {
-    key: "page_design",
-    name: "页面设计",
-    icon: icon4,
-    description: "表单设计器方面的使用方法~",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何使用表单设计器?",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何在表单设计器中添加弹窗?",
-      },
-    ]
-  },
-  {
-    key: "workflow_design",
-    name: "流程设计",
-    icon: icon5,
-    description: "不同流程的创建和使用",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何在系统中使用流程图?",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "流程异常如何处理?",
-      },
-    ]
-  },
-  {
-    key: "doc_generate",
-    name: "文档生成",
-    icon: icon6,
-    description: "文档管理方面的一些问题",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "生成一份系统操作手册文档?",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "如何将文档保存为模板?",
-      },
-    ]
-  },
-  {
-    key: "code_generate",
-    name: "代码生成",
-    icon: icon4,
-    description: "我可以帮你生成页面代码、JS代码、后端代码等",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "写一个登陆页面",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "帮我写一个登陆方法?",
-      },
-    ]
-  },
-  {
-    key: "sql_generate",
-    name: "SQL生成",
-    icon: icon3,
-    description: "我可以帮你生成各种各样的查询、创建、更新方法~",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "用户统计",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "视图查询",
-      },
-    ]
-  },
-  {
-    key: "demand_generate",
-    name: "指令生成",
-    icon: icon1,
-    description: "我可以帮你快速创建应用~",
-    promptsItems: [
-      {
-        key: "1",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "创建一个用户管理系统",
-      },
-      {
-        key: "2",
-        icon: <SmileOutlined style={{ color: "#52C41A" }} />,
-        description: "创建一个订单管理系统",
-      },
-    ]
-  },
-];

+ 28 - 115
src/pages/ai/index.tsx

@@ -1,131 +1,44 @@
-import { useState, useEffect } from "react";
+import { useState } from "react";
 import Assistant from "./Assistant";
 import data from "@emoji-mart/data";
 import { init } from "emoji-mart";
-import styles from "./index.less";
 import "./index.less";
-import logo from "@/assets/shalu-new1.png";
-import { assistantList } from "./data";
-import { useModel } from "umi";
-import { Avatar, Button, Dropdown } from "antd";
-import { DownOutlined, UserOutlined } from "@ant-design/icons";
+import { CoffeeOutlined, SmileOutlined, FireOutlined } from "@ant-design/icons";
+import logo from '@/assets/icon-ai-1.png';
 
 init({ data });
 
-export default () => {
-  const [active, setActive] = useState(assistantList[0].key);
-  const { userInfo, handleLogout, checkUserInfo } = useModel("userModel");
-
-  const handleLogin = () => {
-    window.open(
-      `/Views/Account/Index.html?ReturnUrl=${window.location.href}`,
-      "_self"
-    );
-  };
-
-  useEffect(() => {
-    checkUserInfo();
-  }, []);
-
-  const handleToManagement = () => {
-    window.open(`/Views/Home/Index.html`);
-  };
+const assistant = {
+  key: "normal_ask",
+  name: "综合问答",
+  icon: logo,
+  description: "基于LLM的智能助手,可以进行各种使用查询、知识问答等~",
+  promptsItems: [
+    {
+      key: "1",
+      icon: <CoffeeOutlined style={{ color: "#964B00" }} />,
+      description: "怎么创建我的应用?",
+    },
+    {
+      key: "2",
+      icon: <SmileOutlined style={{ color: "#FAAD14" }} />,
+      description: "页面设计器如何使用?",
+    },
+    {
+      key: "3",
+      icon: <FireOutlined style={{ color: "#FF4D4F" }} />,
+      description: "如何生成页面SQL?",
+    },
+  ],
+};
 
+export default () => {
   return (
     <div className="flex h-full bg-gray-100 border-t border-gray-200 overflow-hidden">
-      <div className="w-fit sm:w-[216px] shrink-0 pt-6 px-4 border-gray-200 cursor-pointer">
-        <div className="w-full">
-          <img src={logo} className="h-40px" />
-        </div>
-        <div className="mt-10">
-          <p className="pl-2 mobile:px-0 text-xs text-gray-500 break-all font-medium uppercase">
-            助手类型
-          </p>
-          <div
-            className="mt-3 space-y-2 overflow-y-auto overflow-x-hidden"
-            style={{ height: "calc(-200px + 100vh)" }}
-          >
-            {assistantList.map((item, index) => (
-              <div
-                key={index}
-                className={`flex h-8 items-center justify-between mobile:justify-center px-2 mobile:px-1 rounded-lg text-sm font-normal ${active === item.key ? styles.active : " hover:bg-gray-200"}`}
-                onClick={() => setActive(item.key)}
-              >
-                <div className="flex items-center space-x-2 w-0 grow">
-                  <span
-                    className="flex items-center justify-center relative rounded-lg grow-0 shrink-0 overflow-hidden w-6 h-6 text-base"
-                    style={{ background: "rgb(213, 245, 246)" }}
-                  >
-                    <img className="w-full h-full" src={item.icon} />
-                  </span>
-                  <div
-                    className="overflow-hidden text-ellipsis whitespace-nowrap"
-                    title={item.name}
-                  >
-                    {item.name}
-                  </div>
-                </div>
-                <div className="shrink-0 h-6">
-                  <div className="inline-block" data-state="closed">
-                    <div className="style_btn__bbesM h-6 w-6 rounded-md border-none py-1"></div>
-                  </div>
-                </div>
-              </div>
-            ))}
-          </div>
-          {/* 用户信息 */}
-          <div className="w-full h-30px">
-            {userInfo ? (
-              <Dropdown
-                menu={{
-                  items: [
-                    {
-                      key: "1",
-                      label: <span>管理后台</span>,
-                      onClick: handleToManagement,
-                    },
-                    {
-                      key: "2",
-                      label: <span>退出</span>,
-                      onClick: handleLogout,
-                    },
-                  ],
-                }}
-                trigger={["click"]}
-                placement="bottomRight"
-                arrow
-              >
-                <span>
-                  <Avatar size={32} icon={<UserOutlined />} />
-                  <span className="ml-4px text-12px text-text-secondary cursor-pointer truncate">
-                    {userInfo.account}
-                  </span>
-                  <DownOutlined className="ml-4px text-12px text-text-secondary" />
-                </span>
-              </Dropdown>
-            ) : (
-              <div className="flex items-center gap-12px">
-                <Avatar size={32} icon={<UserOutlined />} />
-                <Button
-                  className="ml-4px"
-                  size="small"
-                  onClick={handleLogin}
-                  shape="round"
-                >
-                  登录
-                </Button>
-              </div>
-            )}
-          </div>
-        </div>
-      </div>
       <div className="grow w-0">
         <div className="h-full py-2 pl-0 pr-2 sm:p-2">
           <div className="h-full flex bg-white rounded-2xl shadow-md overflow-hidden false">
-            <Assistant
-              key={active}
-              agent={assistantList.find((item) => item.key === active)}
-            />
+            <Assistant agent={assistant} />
           </div>
         </div>
       </div>

+ 0 - 176
src/pages/application/index.tsx

@@ -1,176 +0,0 @@
-import { useEffect, useState } from "react";
-import ItemCard from "@/components/ItemCard";
-import { Input, Empty, Spin, Pagination } from "antd";
-import { GetAppPublicList } from "@/api/appStore";
-import { useRequest } from "umi";
-import { INDUSTRIE_OPTIONS, APPLICATION_SCENARIOS_OPTIONS } from "@/constants";
-import noDataImg from "@/assets/no-data.svg";
-import "@/style/index.less";
-
-type SceneItem = {
-  label: string;
-  value: string;
-  icon?: JSX.Element;
-};
-const industrys = [{ label: "全部行业", value: "all" }, ...INDUSTRIE_OPTIONS];
-
-const scenes: SceneItem[] = [
-  {
-    label: "推荐",
-    icon: <i className="iconfont icon-tuijian mr-1" />,
-    value: "recommend",
-  },
-  ...APPLICATION_SCENARIOS_OPTIONS,
-];
-export default function Home() {
-  const [search, setSearch] = useState("");
-  const [industryFilter, setIndustryFilter] = useState("all");
-  const [sceneFilter, setSceneFilter] = useState("recommend");
-  const [currentPage, setCurrentPage] = useState(1);
-  const { data, run, loading } = useRequest(GetAppPublicList, {
-    defaultParams: [
-      {
-        currentPage: 1,
-        pageSize: 20,
-        filters: [
-          { name: "isDel", value: 0 },
-          { name: "isOnMarket", value: 1 },
-        ],
-      },
-    ],
-  });
-
-  useEffect(() => {
-    setCurrentPage(1);
-    run({
-      currentPage: 1,
-      pageSize: 20,
-      filters: [
-        { name: "isDel", value: 0 },
-        { name: "isOnMarket", value: 1 },
-        { name: "name", value: search },
-        {
-          name: "industries",
-          value: industryFilter === "all" ? "" : industryFilter,
-        },
-        {
-          name: "applicationScenarios",
-          value: sceneFilter === "recommend" ? "" : sceneFilter,
-        },
-      ],
-    });
-  }, [industryFilter, sceneFilter, search]);
-
-  const handleChangePage = (page: number) => {
-    setCurrentPage(page);
-    run({
-      currentPage: page,
-      pageSize: 20,
-      filters: [
-        { name: "isDel", value: 0 },
-        { name: "isOnMarket", value: 1 },
-        { name: "name", value: search },
-        {
-          name: "industries",
-          value: industryFilter === "all" ? "" : industryFilter,
-        },
-        {
-          name: "applicationScenarios",
-          value: sceneFilter === "recommend" ? "" : sceneFilter,
-        },
-      ],
-    });
-  };
-
-  const handleToAppDetail = (id: string) => {
-    window.open(`#/detail/application/${id}`, "_blank");
-  };
-
-  return (
-    <div className="flex h-full">
-      <div className="left w-fit sm:w-[216px] shrink-0 pt-6 px-4 border-gray-200 border-0 border-r border-solid border-gray-200">
-        <ul className="flex flex-col gap-y-2">
-          {industrys.map((item) => (
-            <li
-              key={item.value}
-              className={`cursor-pointer text-14px text-secondary gap-2 flex items-center pc:justify-start pc:w-full mobile:justify-center mobile:w-fit h-9 px-3 mobile:px-2 rounded-lg ${industryFilter === item.value ? "bg-white font-semibold !text-primary shadow-xs" : ""}`}
-              onClick={() => setIndustryFilter(item.value)}
-            >
-              <span>{item.label}</span>
-            </li>
-          ))}
-        </ul>
-      </div>
-      <div className="right flex-1 pt-6 px-4 h-full flex flex-col">
-        <div className="shrink-0 pt-6 px-12">
-          <div className="mb-1 text-primary text-xl font-semibold">
-            探索应用模版
-          </div>
-          <div className="text-gray-500 text-sm">
-            使用这些模板应用程序,或根据模板自定义您自己的应用程序。
-          </div>
-        </div>
-        <div className="flex items-center justify-between mt-6 px-12">
-          <div className="flex space-x-1 text-[13px] flex-wrap">
-            {scenes.map((scene) => (
-              <div
-                key={scene.value}
-                className={`cursor-pointer px-3 py-[7px] h-[32px] rounded-lg font-medium leading-[18px] cursor-pointer ${scene.value === sceneFilter ? "bg-white shadow-xs text-primary-600 text-primary" : "border-transparent text-gray-700 hover:bg-gray-200"}`}
-                onClick={() => setSceneFilter(scene.value)}
-              >
-                {scene?.icon}
-                {scene.label}
-              </div>
-            ))}
-          </div>
-          <div>
-            <Input
-              value={search}
-              onChange={(e) => setSearch(e.target.value)}
-              placeholder="搜索"
-              prefix={<i className="iconfont icon-sousuo" />}
-              allowClear
-            ></Input>
-          </div>
-        </div>
-
-        <div className="relative flex flex-1 pb-6 flex-col overflow-auto bg-gray-100 shrink-0 grow mt-4 relative">
-          <nav className="style_appList grid content-start shrink-0 gap-4 px-6 sm:px-12">
-            {(data?.result?.model || []).map((item: any, index: number) => (
-              <ItemCard
-                data={item}
-                key={index}
-                onClick={handleToAppDetail}
-                extra={
-                  item?.isCanUseTrial && (
-                    <div className="absolute bg-#0e53e2 right--30px top--2px text-10px text-#fff text-center w-80px rotate-34deg">
-                      试
-                    </div>
-                  )
-                }
-              />
-            ))}
-          </nav>
-
-          <Pagination
-            className="mt-6"
-            align="center"
-            hideOnSinglePage
-            current={currentPage}
-            pageSize={20}
-            total={data?.result?.totalCount || 0}
-            onChange={handleChangePage}
-          />
-
-          {!data?.result.model.length && !loading && (
-            <Empty description="暂无数据" image={noDataImg} />
-          )}
-
-          <div className="h-200px w-full absolute left-0 top0 flex items-center justify-center pointer-events-none">
-            <Spin spinning={loading} />
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}

+ 0 - 251
src/pages/apply/index.tsx

@@ -1,251 +0,0 @@
-import { useState, useRef, useMemo } from "react";
-import {
-  ActionType,
-  ProColumns,
-  ModalForm,
-  ProDescriptions,
-  ProFormSelect,
-  ProFormTextArea,
-} from "@ant-design/pro-components";
-import { ProTable } from "@ant-design/pro-components";
-import { message, Modal, Skeleton } from "antd";
-import { useRequest } from "umi";
-import { GetApplyList, GetApplyDetail, HandleApply } from "@/api/apply";
-
-const handleStatusEnum = {
-  0: {
-    text: "待审核",
-    status: "default",
-  },
-  1: {
-    text: "跟踪中",
-    status: "processing",
-  },
-  2: {
-    text: "已购买",
-    status: "success",
-  },
-  3: {
-    text: "未购买",
-    status: "error",
-  },
-};
-
-export default () => {
-  const actionRef = useRef<ActionType>();
-  const [openDetail, setOpenDetail] = useState(false);
-  const [openProcess, setOpenProcess] = useState(false);
-  const [processId, setProcessId] = useState<string>("");
-
-  const { data, loading, run } = useRequest(GetApplyDetail, {
-    defaultParams: [{ id: "" }],
-    manual: true,
-  });
-
-  const columns: ProColumns<any>[] = [
-    {
-      title: "客户名称",
-      dataIndex: "name",
-      ellipsis: true,
-    },
-    {
-      title: "联系方式",
-      dataIndex: "tel",
-      ellipsis: true,
-      copyable: true,
-    },
-    {
-      title: "企业名称",
-      dataIndex: "companyName",
-      ellipsis: true,
-    },
-    {
-      title: "模版类型",
-      dataIndex: "type",
-      search: false,
-      renderText: (text) => {
-        return text === 0 ? "应用模版" : "模块模版";
-      },
-    },
-    {
-      title: "处理状态",
-      dataIndex: "status",
-      valueType: "select",
-      valueEnum: handleStatusEnum,
-    },
-    {
-      title: "备注",
-      dataIndex: "processRemark",
-      search: false,
-      ellipsis: true,
-    },
-    {
-      title: "申请时间",
-      dataIndex: "createTime",
-      search: false,
-    },
-    {
-      title: "最后处理时间",
-      dataIndex: "processTime",
-      search: false,
-    },
-    {
-      title: "操作",
-      valueType: "option",
-      key: "option",
-      width: 180,
-      render: (text, record, _,) => [
-        <a key="edit" onClick={() => showDetail(record.id)}>
-          详情
-        </a>,
-        <a
-          target="_blank"
-          rel="noopener noreferrer"
-          key="view"
-          onClick={() => {
-            setProcessId(record.id);
-            setOpenProcess(true);
-          }}
-        >
-          处理
-        </a>,
-      ],
-    },
-  ];
-
-  const showDetail = (id: string) => {
-    setOpenDetail(true);
-    run({ id: id });
-  };
-
-  const handleProcessFinish = async (values: any) => {
-    await HandleApply({
-      ...values,
-      status: Number(values.status),
-      id: processId,
-    });
-    message.success('处理成功');
-    actionRef.current?.reload();
-    return true;
-  }
-
-  return (
-    <div className="p-12px">
-      <ProTable
-        columns={columns}
-        actionRef={actionRef}
-        cardBordered
-        headerTitle="应用/模版申请列表"
-        request={async (params, sort, filter) => {
-          console.log(params, sort, filter);
-          const isOnMarket =
-            params?.isOnMarket === "on"
-              ? 1
-              : params?.isOnMarket === "off"
-                ? 0
-                : undefined;
-          const res = await GetApplyList({
-            currentPage: params.current || 1,
-            pageSize: params.pageSize || 10,
-            orderByProperty: "createTime",
-            Ascending: false,
-            filters: [
-              { name: "name", value: params?.name },
-              { name: "tel", value: params?.tel },
-              { name: "companyName", value: params?.companyName },
-              { name: "status", value: params?.status },
-              { name: "isOnMarket", value: isOnMarket },
-              { name: "isDel", value: 0 },
-            ],
-          });
-          const data = res?.result || {};
-          return {
-            data: data.model || [],
-            success: true,
-            total: data.totalCount || 0,
-          };
-        }}
-        columnsState={{
-          persistenceKey: "shalu-marketplace",
-          persistenceType: "localStorage",
-          defaultValue: {
-            option: { fixed: "right", disable: true },
-          },
-        }}
-        rowKey="id"
-        search={{
-          labelWidth: "auto",
-        }}
-        options={{
-          setting: {
-            listsHeight: 400,
-          },
-        }}
-        pagination={{
-          pageSize: 10,
-        }}
-        dateFormatter="string"
-      />
-
-      {/* 详情弹窗 */}
-      <Modal
-        open={openDetail}
-        width={800}
-        footer={null}
-        onCancel={() => setOpenDetail(false)}
-      >
-        <Skeleton loading={loading}>
-          <ProDescriptions
-            title="基本信息"
-            column={2}
-            dataSource={data?.result || {}}
-          >
-            <ProDescriptions.Item label="申请名称" dataIndex="name" />
-            <ProDescriptions.Item label="联系方式" dataIndex="tel" copyable />
-            <ProDescriptions.Item label="公司名称" dataIndex="companyName" />
-            <ProDescriptions.Item label="公司规模" dataIndex="companySize" />
-            <ProDescriptions.Item label="职位名称" dataIndex="jobTitle" />
-            <ProDescriptions.Item label="申请时间" dataIndex="createTime" />
-          </ProDescriptions>
-          <ProDescriptions
-            className="mt-12px"
-            title="申请产品"
-            column={2}
-            dataSource={data?.result || {}}
-          >
-            <ProDescriptions.Item
-              label="应用类型"
-              dataIndex="type"
-              renderText={(text) => (text === 0 ? "应用模版" : "模块模版")}
-            />
-            <ProDescriptions.Item label="模版名称" dataIndex="name" />
-          </ProDescriptions>
-        </Skeleton>
-      </Modal>
-
-      {/* 处理弹窗 */}
-      <ModalForm
-        open={openProcess}
-        onOpenChange={setOpenProcess}
-        width={440}
-        onFinish={handleProcessFinish}
-      >
-        <ProFormSelect
-          name="status"
-          label="处理结果"
-          rules={[{ required: true, message: "请选择处理结果" }]}
-          valueEnum={{
-            1: handleStatusEnum[1],
-            2: handleStatusEnum[2],
-            3: handleStatusEnum[3],
-          }}
-        />
-        <ProFormTextArea
-          name="processRemark"
-          label="处理备注"
-          rules={[{ required: true, message: "请输入处理备注" }]}
-        />
-      </ModalForm>
-    </div>
-  );
-};

+ 0 - 5
src/pages/detail/index.less

@@ -1,5 +0,0 @@
-.rich {
-  img {
-    max-width: 100%;
-  }
-}

+ 0 - 225
src/pages/detail/index.tsx

@@ -1,225 +0,0 @@
-import {
-  Button,
-  Form,
-  Image,
-  Input,
-  Modal,
-  Select,
-  Skeleton,
-  Breadcrumb,
-  message,
-  notification,
-  Tooltip,
-} from "antd";
-import type { BreadcrumbProps } from "antd";
-import { useMemo, useState } from "react";
-import { useParams, useRequest, history } from "umi";
-import { GetAppDetail } from "@/api/appStore";
-import { GetTemplateDetail } from "@/api/templateStore";
-import styles from "./index.less";
-import { LeftOutlined } from "@ant-design/icons";
-import { SubmitApply } from "@/api/apply";
-
-export default function detail() {
-  const [showAdvisory, setShowAdvisory] = useState(false);
-  const [form] = Form.useForm();
-
-  const { id, type } = useParams();
-
-  const { data, loading } = useRequest<{ result: any }>(
-    type === "application" ? GetAppDetail : GetTemplateDetail,
-    {
-      defaultParams: [
-        {
-          id: id,
-        },
-      ],
-    }
-  );
-
-  const handleToApp = () => {
-    if (data?.result?.trialUrl) {
-      window.open(data?.result?.trialUrl, "_blank");
-    }
-  };
-
-  const handleBack = () => {
-    history.back();
-  };
-
-  // 提交申请
-  const handleSubmit = () => {
-    form.validateFields().then(async (values) => {
-      await SubmitApply({
-        ...values,
-        type: type === "application" ? 0 : 1,
-        templateId: id,
-      });
-      notification.success({
-        message: "您的申请已提交,后续会有专员与您联系!~",
-      });
-      setShowAdvisory(false);
-    });
-  };
-
-  const breadcrumbItems: BreadcrumbProps["items"] = useMemo(() => {
-    return [
-      {
-        key: "all",
-        // title: (
-        //   <a onClick={handleBack}>
-        //     <LeftOutlined />
-        //     <span className="m-l-4px">返回</span>
-        //   </a>
-        // ),
-        title: "全部",
-      },
-      { key: "current", title: data?.result.name },
-    ];
-  }, [data]);
-
-  return (
-    <div className="detail relative mx-auto pt-24px h-full overflow-y-auto">
-      <div className="max-w-[1200px] mx-auto">
-        <Breadcrumb className="mb-24px" items={breadcrumbItems} />
-        <Skeleton avatar active loading={loading}>
-          <div className="flex mb-32px">
-            <div className="w-128px h-128px rounded-20px bg-gray-200 overflow-hidden flex justify-center items-center">
-              <Image
-                className="w-full h-full"
-                preview={false}
-                src={
-                  data?.result?.icon
-                    ? `/api/File/Download?fileId=${data?.result?.icon}`
-                    : ""
-                }
-              />
-            </div>
-            <div className="flex-1 mx-24px">
-              <div className="text-32px font-[600]">{data?.result?.name}</div>
-              <div className="text-secondary text-14px">
-                {data?.result?.desc || "暂无描述"}
-              </div>
-              <div className="mt-12px flex items-center">
-                {/* <div className="block bg-[#dcdde0] rounded-8px text-secondary px-8px py-4px text-12px">
-                  <i className="iconfont icon-qiyexinxi mr-8px" />
-                  <span>{data?.result?.createByName || "易码工坊"}</span>
-                </div> */}
-                <div className="flex items-center px-[14px] leading-24px text-12px">
-                  <div className="flex items-center space-x-1 text-text-tertiary">
-                    {/* <svg
-                      viewBox="0 0 24 24"
-                      xmlns="http://www.w3.org/2000/svg"
-                      width="24"
-                      height="24"
-                      fill="currentColor"
-                      className="remixicon shrink-0 w-3 h-3"
-                    >
-                      <path d="M9 2V4H5L4.999 14H18.999L19 4H15V2H20C20.5523 2 21 2.44772 21 3V21C21 21.5523 20.5523 22 20 22H4C3.44772 22 3 21.5523 3 21V3C3 2.44772 3.44772 2 4 2H9ZM18.999 16H4.999L5 20H19L18.999 16ZM17 17V19H15V17H17ZM13 2V7H16L12 11L8 7H11V2H13Z"></path>
-                    </svg> */}
-                    <i className="iconfont icon-liulanliang"/>
-                    <div className="system-xs-regular">浏览量 {data?.result?.viewCount || 0}</div>
-                  </div>
-                  <div className="mx-2 text-text-quaternary system-xs-regular">
-                    ·
-                  </div>
-                  <div className="flex flex-wrap space-x-2 h-4 overflow-hidden">
-                    {(data?.result.tags?.split(",") || []).map(
-                      (tag: string) => {
-                        return (
-                          <div
-                            className="flex space-x-1 system-xs-regular max-w-[120px] overflow-hidden"
-                            title={`# ${tag}`}
-                          >
-                            <span className="text-text-quaternary">#</span>
-                            <span className="truncate text-text-tertiary">
-                              {tag}
-                            </span>
-                          </div>
-                        );
-                      }
-                    )}
-                  </div>
-                </div>
-              </div>
-            </div>
-            <div className="head-right flex flex-col justify-center items-center">
-              <Tooltip title={!data?.result?.isCanUseTrial ? "暂不支持体验~" : ""}>
-                <Button
-                  type="primary"
-                  className="w-full mb-24px"
-                  onClick={handleToApp}
-                  disabled={!data?.result?.isCanUseTrial}
-                >
-                  在线体验
-                </Button>
-              </Tooltip>
-              <Button className="w-full" onClick={() => setShowAdvisory(true)}>
-                购买咨询
-              </Button>
-            </div>
-          </div>
-        </Skeleton>
-        <div className="inline-block">
-          <div className="text-24px font-[600] mb-8px">方案详情</div>
-          <div className="w-60px h-4px bg-primary rounded-4px mx-auto" />
-        </div>
-
-        <Skeleton active loading={loading}>
-          <div
-            className={
-              "content m-y-32px overflow-hidden relative " + styles.rich
-            }
-          >
-            <div
-              dangerouslySetInnerHTML={{ __html: data?.result?.detail || "" }}
-            />
-          </div>
-        </Skeleton>
-      </div>
-      <Modal
-        title="购买咨询"
-        width={500}
-        open={showAdvisory}
-        onCancel={() => setShowAdvisory(false)}
-        onOk={handleSubmit}
-      >
-        <Form labelCol={{ span: 6 }} autoComplete="off" form={form}>
-          <Form.Item
-            label="如何称呼您?"
-            name="name"
-            rules={[{ required: true, message: "请输入您的称呼!" }]}
-          >
-            <Input placeholder="请输入" maxLength={20} />
-          </Form.Item>
-          <Form.Item
-            label="联系方式"
-            name="tel"
-            rules={[
-              { required: true, message: "请输入您的联系方式!", max: 20 },
-            ]}
-          >
-            <Input placeholder="请输入" maxLength={20} />
-          </Form.Item>
-          <Form.Item label="公司名称" name="companyName">
-            <Input placeholder="请输入" maxLength={100} />
-          </Form.Item>
-          <Form.Item label="企业规模" name="companySize">
-            <Select
-              placeholder="请选择"
-              options={[
-                { label: "1-10人", value: "1-10人" },
-                { label: "11-50人", value: "11-50人" },
-                { label: "51-200人", value: "51-200人" },
-                { label: "200人以上", value: "200人以上" },
-              ]}
-            />
-          </Form.Item>
-          <Form.Item label="您的职务" name="jobTitle">
-            <Input placeholder="请输入" maxLength={20} />
-          </Form.Item>
-        </Form>
-      </Modal>
-    </div>
-  );
-}

+ 0 - 202
src/pages/management/AddAppDrawer.tsx

@@ -1,202 +0,0 @@
-import { PlusOutlined } from "@ant-design/icons";
-import {
-  DrawerForm,
-  ProForm,
-  ProFormSelect,
-  ProFormText,
-  ProFormUploadButton,
-  ProFormTextArea,
-  ProFormMoney,
-} from "@ant-design/pro-components";
-import type { FormInstance } from "@ant-design/pro-components";
-import { Button, Space, message } from "antd";
-import { useState, useRef, useEffect, useMemo } from "react";
-import Editor from "@/components/Editor";
-import { AppItem, SaveOrUpdateApp, GetAppDetail } from "@/api/appStore";
-import { INDUSTRIE_OPTIONS, APPLICATION_SCENARIOS_OPTIONS } from "@/constants";
-import { customUploadRequest } from "@/utils";
-import { useRequest } from "umi";
-
-export default ({
-  onSuccess,
-  editData,
-  onClose,
-}: {
-  onSuccess: () => void;
-  onClose: () => void;
-  editData?: AppItem;
-}) => {
-  const [drawerVisit, setDrawerVisit] = useState(false);
-  const [html, setHtml] = useState("");
-  const formRef = useRef<FormInstance>();
-  const { run } = useRequest(GetAppDetail, {
-    manual: true,
-    onSuccess: (res) => {
-      setHtml(res?.result?.detail || "");
-    },
-  });
-
-  useEffect(() => {
-    setDrawerVisit(!!editData);
-    if(editData?.id) {
-      run({
-        id: editData.id,
-      });
-    }
-  }, [editData]);
-
-  useEffect(() => {
-    if (!drawerVisit) {
-      onClose();
-      formRef.current?.resetFields();
-      setHtml("");
-    }
-  }, [drawerVisit]);
-
-  const initialValues = useMemo(() => {
-    if (editData) {
-      return {
-        ...editData,
-        industries: editData.industries ? JSON.parse(editData.industries) : [],
-        applicationScenarios: editData.applicationScenarios ? JSON.parse(editData.applicationScenarios) : [],
-        icon: editData.icon
-          ? [
-              {
-                uid: editData.icon,
-                name: editData.icon,
-                status: "done",
-                url: `/api/File/Download?fileId=${editData.icon}`,
-              },
-            ]
-          : [],
-      };
-    }
-    return {};
-  }, [editData]);
-
-  return (
-    <>
-      <Space>
-        <Button
-          type="primary"
-          onClick={() => {
-            setDrawerVisit(true);
-          }}
-        >
-          <PlusOutlined />
-          新增应用
-        </Button>
-      </Space>
-
-      <DrawerForm
-        onOpenChange={setDrawerVisit}
-        title={editData ? "编辑应用" : "新增应用"}
-        open={drawerVisit}
-        onFinish={async (values: any) => {
-          await SaveOrUpdateApp({
-            ...values,
-            id: editData?.id,
-            version: editData?.version,
-            icon: values?.icon?.[0]?.response?.id || values?.icon?.[0].uid || "",
-            tags: values.tags?.replaceAll(",", ","),
-            detail: html,
-            isFree: !values?.price,
-          });
-          onSuccess();
-          message.success("提交成功");
-          return true;
-        }}
-        initialValues={initialValues}
-        drawerProps={{
-          maskClosable: false,
-          destroyOnClose: true,
-        }}
-        formRef={formRef}
-        size="small"
-      >
-        <ProForm.Group title="基础信息">
-          <ProFormSelect
-            width="md"
-            name="applicationId"
-            label="应用"
-            placeholder="请输入名称"
-          />
-
-          <ProFormText
-            width="md"
-            name="name"
-            label="应用名称"
-            tooltip="最长为 30 位"
-            placeholder="请输入名称"
-            rules={[
-              { required: true, message: "请输入名称" },
-              { max: 30, message: "名称不能超过30个字符" },
-            ]}
-          />
-          <ProFormTextArea
-            width="md"
-            name="trialUrl"
-            label="试用地址"
-            placeholder="请输入名称"
-          />
-          <ProFormUploadButton
-            fieldProps={{
-              multiple: false,
-              name: "file",
-              listType: "picture-card",
-              accept: "image/*",
-              customRequest: customUploadRequest,
-            }}
-            max={1}
-            name="icon"
-            label="图标"
-            rules={[{ required: true, message: "请上传应用图标" }]}
-          />
-        </ProForm.Group>
-        <ProFormTextArea
-          name="desc"
-          label="应用简介"
-          placeholder="请输入简介,1000字以内"
-        />
-        <ProForm.Group>
-          <ProFormSelect
-            width="md"
-            name="industries"
-            label="所属行业"
-            placeholder="请选择"
-            mode="multiple"
-            options={INDUSTRIE_OPTIONS}
-          />
-          <ProFormSelect
-            width="md"
-            name="applicationScenarios"
-            label="应用场景"
-            placeholder="请选择"
-            mode="multiple"
-            options={APPLICATION_SCENARIOS_OPTIONS}
-          />
-          <ProFormText
-            width="md"
-            name="tags"
-            label="标签"
-            placeholder="多个标签用逗号分隔"
-          />
-          <ProFormMoney
-            width="md"
-            name="price"
-            label="定价"
-            fieldProps={{
-              defaultValue: 0,
-            }}
-            locale="zh-CN"
-            min={0}
-            placeholder="请输入"
-          />
-        </ProForm.Group>
-        <ProForm.Group title="详情信息">
-          <Editor html={html} onChange={setHtml} />
-        </ProForm.Group>
-      </DrawerForm>
-    </>
-  );
-};

+ 0 - 215
src/pages/management/AddTemplateDrawer.tsx

@@ -1,215 +0,0 @@
-import { PlusOutlined } from "@ant-design/icons";
-import {
-  DrawerForm,
-  ProForm,
-  ProFormSelect,
-  ProFormText,
-  ProFormUploadButton,
-  ProFormTextArea,
-  ProFormMoney,
-} from "@ant-design/pro-components";
-import { Button, Space, message } from "antd";
-import type { FormInstance } from "@ant-design/pro-components";
-import { useEffect, useState, useMemo, useRef } from "react";
-import Editor from "@/components/Editor";
-import { customUploadRequest } from "@/utils";
-import { SaveOrUpdateTemplate, GetTemplateDetail } from "@/api/templateStore";
-import {
-  APPLICATION_SCENARIOS_OPTIONS,
-  INDUSTRIE_OPTIONS,
-  MODULE_TEMPLATE_TYPE,
-} from "@/constants";
-import { useRequest } from "umi";
-
-export default ({
-  onSuccess,
-  editData,
-  onClose,
-}: {
-  onSuccess: () => void;
-  onClose: () => void;
-  editData?: any;
-}) => {
-  const [drawerVisit, setDrawerVisit] = useState(false);
-  const [html, setHtml] = useState("");
-  const formRef = useRef<FormInstance>();
-
-  const { run } = useRequest(GetTemplateDetail, {
-    manual: true,
-    onSuccess: (res) => {
-      setHtml(res?.result?.detail || "");
-    },
-  });
-
-  useEffect(() => {
-    setDrawerVisit(!!editData);
-    if(editData?.id) {
-      run({
-        id: editData.id,
-      });
-    }
-  }, [editData]);
-
-  useEffect(() => {
-    if (!drawerVisit) {
-      onClose();
-      setHtml("");
-      formRef.current?.resetFields();
-    }
-  }, [drawerVisit]);
-
-  const initialValues = useMemo(() => {
-    if (editData) {
-      return {
-        ...editData,
-        industries: editData.industries ? JSON.parse(editData.industries) : [],
-        applicationScenarios: editData.applicationScenarios ? JSON.parse(editData.applicationScenarios) : [],
-        icon: editData.icon
-          ? [
-              {
-                uid: editData.icon,
-                name: editData.icon,
-                status: "done",
-                url: `/api/File/Download?fileId=${editData.icon}`,
-              },
-            ]
-          : [],
-      };
-    }
-    return {};
-  }, [editData]);
-
-  return (
-    <>
-      <Space>
-        <Button
-          type="primary"
-          onClick={() => {
-            setDrawerVisit(true);
-          }}
-        >
-          <PlusOutlined />
-          新增模版
-        </Button>
-      </Space>
-
-      <DrawerForm
-        onOpenChange={setDrawerVisit}
-        title="新增模版"
-        open={drawerVisit}
-        initialValues={initialValues}
-        onFinish={async (values: any) => {
-          await SaveOrUpdateTemplate({
-            ...values,
-            id: editData?.id,
-            version: editData?.version,
-            icon: values?.icon?.[0]?.response.id || values?.icon?.[0].uid || "",
-            tags: values.tags?.replaceAll(",", ","),
-            detail: html,
-            isFree: !editData?.price,
-          });
-          onSuccess();
-          message.success("提交成功");
-          return true;
-        }}
-        drawerProps={{
-          maskClosable: false,
-          destroyOnClose: true,
-        }}
-        formRef={formRef}
-        size="small"
-      >
-        <ProForm.Group title="基础信息">
-          <ProFormSelect
-            width="md"
-            name="applicationId"
-            label="所属应用"
-            placeholder="请选择"
-          />
-
-          <ProFormSelect
-            width="md"
-            name="type"
-            label="模版分类"
-            placeholder="请选择"
-            options={MODULE_TEMPLATE_TYPE}
-          />
-
-          <ProFormSelect
-            width="md"
-            name="moduleId"
-            label="选择模版"
-            placeholder="请选择"
-          />
-
-          <ProFormText
-            width="md"
-            name="name"
-            label="模版名称"
-            tooltip="最长为 30 位"
-            placeholder="请输入名称"
-            rules={[
-              { required: true, message: "请输入名称" },
-              { max: 30, message: "名称不能超过30个字符" },
-            ]}
-          />
-
-          <ProFormUploadButton
-            max={1}
-            fieldProps={{
-              multiple: false,
-              name: "file",
-              listType: "picture-card",
-              accept: "image/*",
-              customRequest: customUploadRequest,
-            }}
-            name="icon"
-            label="图标"
-            rules={[{ required: true, message: "请上传应用图标" }]}
-          />
-        </ProForm.Group>
-        <ProFormTextArea
-          name="desc"
-          label="模版简介"
-          placeholder="请输入简介,1000字以内"
-        />
-        <ProForm.Group>
-          <ProFormSelect
-            width="md"
-            name="industries"
-            label="所属行业"
-            placeholder="请选择"
-            mode="multiple"
-            options={INDUSTRIE_OPTIONS}
-          />
-          <ProFormSelect
-            width="md"
-            name="applicationScenarios"
-            label="应用场景"
-            placeholder="请选择"
-            mode="multiple"
-            options={APPLICATION_SCENARIOS_OPTIONS}
-          />
-          <ProFormText
-            width="md"
-            name="tags"
-            label="标签"
-            placeholder="多个标签用逗号分隔"
-          />
-          <ProFormMoney
-            width="md"
-            name="price"
-            label="定价"
-            defaultValue={0}
-            min={0}
-            placeholder="请输入"
-            locale="zh-CN"
-          />
-        </ProForm.Group>
-        <ProForm.Group title="详情信息">
-          <Editor html={html} onChange={setHtml} />
-        </ProForm.Group>
-      </DrawerForm>
-    </>
-  );
-};

+ 0 - 272
src/pages/management/AppTab.tsx

@@ -1,272 +0,0 @@
-import { useState, useRef } from "react";
-import {
-  ActionType,
-  ProColumns,
-  TableDropdown,
-} from "@ant-design/pro-components";
-import { ProTable } from "@ant-design/pro-components";
-import { Popconfirm, Tag, Tooltip, message } from "antd";
-import AddAppDrawer from "./AddAppDrawer";
-import {
-  GetAppList,
-  DeleteAppTemplate,
-  OffMarketApp,
-  OnMarketApp,
-} from "@/api/appStore";
-import type { AppItem } from "@/api/appStore";
-import { history } from "umi";
-
-export default () => {
-  const actionRef = useRef<ActionType>();
-  const [editData, setEditData] = useState<AppItem>();
-  const handleToDetail = (id?: string) => {
-    history.push(`/detail/application/${id}`);
-  };
-
-  const handleOffMarket = async (id?: string) => {
-    if (id) {
-      await OffMarketApp({ ids: [id] });
-      actionRef.current?.reload();
-      message.success("下架成功");
-    }
-  };
-
-  const handleOnMarket = async (id?: string) => {
-    if (id) {
-      await OnMarketApp({ ids: [id] });
-      actionRef.current?.reload();
-      message.success("上架成功");
-    }
-  };
-
-  const handleDelete = async (id?: string) => {
-    if (id) {
-      await DeleteAppTemplate({ ids: [id] });
-      actionRef.current?.reload();
-      message.success("删除成功");
-    }
-  };
-
-  const columns: ProColumns<AppItem>[] = [
-    {
-      title: "图标",
-      dataIndex: "icon",
-      search: false,
-      render: (_, record) => (
-        <img
-          src={`/api/File/Download?fileId=${record.icon}`}
-          alt=""
-          style={{
-            width: 30,
-            height: 30,
-            borderRadius: "50%",
-          }}
-        />
-      ),
-    },
-    {
-      title: "应用名称",
-      dataIndex: "name",
-      copyable: true,
-      ellipsis: true,
-    },
-    {
-      title: "作者",
-      dataIndex: "createByName",
-      ellipsis: true,
-      search: false,
-    },
-    // {
-    //   title: "应用场景",
-    //   dataIndex: "applicationScenarios",
-    //   ellipsis: true,
-    //   search: false,
-    //   renderText: (text) => {
-    //     return (JSON.parse(text || '[]')).map((item: string) => (
-    //       <Tag key={item}>{item}</Tag>
-    //     ));
-    //   },
-    // },
-    // {
-    //   title: "应用行业",
-    //   dataIndex: "industries",
-    //   ellipsis: true,
-    //   search: false,
-    //   renderText: (text) => {
-    //     return (JSON.parse(text || '[]')).map((item: string) => (
-    //       <Tag key={item}>{item}</Tag>
-    //     ));
-    //   },
-    // },
-    {
-      disable: true,
-      title: "标签",
-      dataIndex: "tags",
-      search: false,
-    },
-    {
-      title: "上架状态",
-      dataIndex: "isOnMarket",
-      ellipsis: true,
-      valueType: "select",
-      valueEnum: {
-        on: {
-          text: "已上架",
-          status: "Error",
-        },
-        off: {
-          text: "未上架",
-          status: "Success",
-        },
-      },
-      render: (_, record) => (
-        <Tag color={record.isOnMarket ? "green" : "red"}>
-          {record.isOnMarket ? "已上架" : "未上架"}
-        </Tag>
-      ),
-    },
-    {
-      title: "使用量",
-      dataIndex: "useNum",
-      search: false,
-    },
-    {
-      title: "价格",
-      dataIndex: "price",
-      search: false,
-      renderText: (text) => {
-        return text ? `¥${text}` : "免费";
-      },
-    },
-    {
-      title: "试用地址",
-      dataIndex: "trialUrl",
-      search: false,
-      renderText: (text) =>
-        text ? (
-          <Tooltip title={text}><a target="_blank" rel="noopener noreferrer" href={text}>试用链接</a></Tooltip>
-        ) : (
-          "-"
-        ),
-    },
-    {
-      title: "创建时间",
-      dataIndex: "createTime",
-      search: false,
-    },
-    {
-      title: "更新时间",
-      dataIndex: "updateTime",
-      search: false,
-    },
-    {
-      title: "操作",
-      valueType: "option",
-      key: "option",
-      width: 180,
-      render: (text, record, _, action) => [
-        <a key="edit" onClick={() => setEditData(record)}>
-          编辑
-        </a>,
-        <a
-          target="_blank"
-          rel="noopener noreferrer"
-          key="view"
-          onClick={() => handleToDetail(record.id)}
-        >
-          详情
-        </a>,
-        record.isOnMarket ? (
-          <a
-            target="_blank"
-            rel="noopener noreferrer"
-            key="off"
-            onClick={() => handleOffMarket(record.id)}
-          >
-            下架
-          </a>
-        ) : (
-          <a
-            target="_blank"
-            rel="noopener noreferrer"
-            key="on"
-            onClick={() => handleOnMarket(record.id)}
-          >
-            上架
-          </a>
-        ),
-        <Popconfirm
-          key="delete"
-          title="确定删除吗?"
-          onConfirm={() => handleDelete(record.id)}
-        >
-          <a className="text-red-500" target="_blank" rel="noopener noreferrer">
-            删除
-          </a>
-        </Popconfirm>,
-      ],
-    },
-  ];
-
-  return (
-    <ProTable<AppItem>
-      columns={columns}
-      actionRef={actionRef}
-      cardBordered
-      request={async (params, sort, filter) => {
-        console.log(params, sort, filter);
-        const isOnMarket =
-          params?.isOnMarket === "on"
-            ? 1
-            : params?.isOnMarket === "off"
-              ? 0
-              : undefined;
-        const res = await GetAppList({
-          currentPage: params.current || 1,
-          pageSize: params.pageSize || 10,
-          filters: [
-            { name: "name", value: params?.name },
-            { name: "isFree", value: params?.isFree },
-            { name: "isOnMarket", value: isOnMarket },
-            { name: "isDel", value: 0 },
-          ],
-        });
-        const data = res?.result || {};
-        return {
-          data: data.model || [],
-          success: true,
-          total: data.totalCount || 0,
-        };
-      }}
-      columnsState={{
-        persistenceKey: "shalu-marketplace",
-        persistenceType: "localStorage",
-        defaultValue: {
-          option: { fixed: "right", disable: true },
-        },
-      }}
-      rowKey="id"
-      search={{
-        labelWidth: "auto",
-      }}
-      options={{
-        setting: {
-          listsHeight: 400,
-        },
-      }}
-      pagination={{
-        pageSize: 10,
-      }}
-      dateFormatter="string"
-      headerTitle={
-        <AddAppDrawer
-          editData={editData}
-          onClose={() => setEditData(undefined)}
-          onSuccess={() => {
-            actionRef.current?.reload();
-          }}
-        />
-      }
-    />
-  );
-};

+ 0 - 259
src/pages/management/TemplateTab.tsx

@@ -1,259 +0,0 @@
-import { useRef, useState } from "react";
-import { ActionType, ProColumns } from "@ant-design/pro-components";
-import { ProTable } from "@ant-design/pro-components";
-import { Space, Tag, message, Popconfirm } from "antd";
-import AddTemplateDrawer from "./AddTemplateDrawer";
-import {
-  GetTemplateList,
-  DeleteTemplate,
-  OnMarketTemplate,
-  OffMarketTemplate,
-} from "@/api/templateStore";
-import { history } from "umi";
-import { MODULE_TEMPLATE_TYPE } from "@/constants";
-
-export default () => {
-  const actionRef = useRef<ActionType>();
-  const [editData, setEditData] = useState<any>();
-  const handleToDetail = (id?: string) => {
-    history.push(`/detail/template/${id}`);
-  };
-
-  const handleOffMarket = async (id?: string) => {
-    if (id) {
-      await OffMarketTemplate({ ids: [id] });
-      actionRef.current?.reload();
-      message.success("下架成功");
-    }
-  };
-
-  const handleOnMarket = async (id?: string) => {
-    if (id) {
-      await OnMarketTemplate({ ids: [id] });
-      actionRef.current?.reload();
-      message.success("上架成功");
-    }
-  };
-
-  const handleDelete = async (id?: string) => {
-    if (id) {
-      await DeleteTemplate({ ids: [id] });
-      actionRef.current?.reload();
-      message.success("删除成功");
-    }
-  };
-
-  const columns: ProColumns<any>[] = [
-    {
-      title: "图标",
-      dataIndex: "icon",
-      search: false,
-      render: (_, record) => (
-        <img
-          src={`/api/File/Download?fileId=${record.icon}`}
-          alt=""
-          style={{
-            width: 30,
-            height: 30,
-            borderRadius: "50%",
-          }}
-        />
-      ),
-    },
-    {
-      title: "模版名称",
-      dataIndex: "name",
-      copyable: true,
-      ellipsis: true,
-    },
-    {
-      title: "作者",
-      dataIndex: "createByName",
-      ellipsis: true,
-      search: false,
-    },
-    {
-      title: "模版分类",
-      dataIndex: "type",
-      copyable: true,
-      ellipsis: true,
-      valueType: "select",
-      fieldProps: {
-        options: MODULE_TEMPLATE_TYPE,
-      },
-    },
-    {
-      disable: true,
-      title: "标签",
-      dataIndex: "labels",
-      search: false,
-      renderFormItem: (_, { defaultRender }) => {
-        return defaultRender(_);
-      },
-      render: (_, record) => (
-        <Space>
-          {record.tags?.split(",").map((tag: string) => (
-            <Tag color="green" key={tag}>
-              {tag}
-            </Tag>
-          ))}
-        </Space>
-      ),
-    },
-    {
-      title: "上架状态",
-      dataIndex: "isOnMarket",
-      ellipsis: true,
-      valueType: "select",
-      valueEnum: {
-        on: {
-          text: "已上架",
-          status: "Error",
-        },
-        off: {
-          text: "未上架",
-          status: "Success",
-        },
-      },
-      render: (_, record) => (
-        <Tag color={record.isOnMarket ? "green" : "red"}>
-          {record.isOnMarket ? "已上架" : "未上架"}
-        </Tag>
-      ),
-    },
-    {
-      title: "使用量",
-      dataIndex: "useNum",
-      search: false,
-    },
-    {
-      title: "价格",
-      dataIndex: "price",
-      search: false,
-      renderText: (text) => {
-        return text ? `¥${text}` : "免费";
-      },
-    },
-    {
-      title: "更新时间",
-      dataIndex: "createTime",
-      search: false,
-    },
-    {
-      title: "更新时间",
-      dataIndex: "updateTime",
-      search: false,
-    },
-    {
-      title: "操作",
-      valueType: "option",
-      key: "option",
-      width: 180,
-      render: (text, record, _, action) => [
-        <a key="edit" onClick={() => setEditData(record)}>
-          编辑
-        </a>,
-        <a
-          target="_blank"
-          rel="noopener noreferrer"
-          key="view"
-          onClick={() => handleToDetail(record.id)}
-        >
-          详情
-        </a>,
-        record.isOnMarket ? (
-          <a
-            target="_blank"
-            rel="noopener noreferrer"
-            key="off"
-            onClick={() => handleOffMarket(record.id)}
-          >
-            下架
-          </a>
-        ) : (
-          <a
-            target="_blank"
-            rel="noopener noreferrer"
-            key="on"
-            onClick={() => handleOnMarket(record.id)}
-          >
-            上架
-          </a>
-        ),
-        <Popconfirm
-          key="delete"
-          title="确定删除吗?"
-          onConfirm={() => handleDelete(record.id)}
-        >
-          <a className="text-red-500" target="_blank" rel="noopener noreferrer">
-            删除
-          </a>
-        </Popconfirm>,
-      ],
-    },
-  ];
-
-  return (
-    <ProTable
-      columns={columns}
-      actionRef={actionRef}
-      cardBordered
-      request={async (params, sort, filter) => {
-        const isOnMarket =
-          params?.isOnMarket === "on"
-            ? 1
-            : params?.isOnMarket === "off"
-              ? 0
-              : undefined;
-        const res = await GetTemplateList({
-          currentPage: params.current || 1,
-          pageSize: params.pageSize || 10,
-          filters: [
-            { name: "name", value: params?.name },
-            { name: "isFree", value: params?.isFree },
-            { name: "isOnMarket", value: isOnMarket },
-            { name: "isDel", value: 0 },
-            { name: "type", value: params?.type },
-          ],
-        });
-
-        const data = res?.result || {};
-
-        return {
-          success: true,
-          data: data.model || [],
-          total: data.totalCount || 0,
-        };
-      }}
-      columnsState={{
-        persistenceKey: "shalu-marketplace",
-        persistenceType: "localStorage",
-        defaultValue: {
-          option: { fixed: "right", disable: true },
-        },
-      }}
-      rowKey="id"
-      search={{
-        labelWidth: "auto",
-      }}
-      options={{
-        setting: {
-          listsHeight: 400,
-        },
-      }}
-      pagination={{
-        pageSize: 10,
-      }}
-      dateFormatter="string"
-      headerTitle={
-        <AddTemplateDrawer
-          onClose={() => setEditData(undefined)}
-          onSuccess={() => {
-            actionRef.current?.reload();
-          }}
-          editData={editData}
-        />
-      }
-    />
-  );
-};

+ 0 - 14
src/pages/management/index.tsx

@@ -1,14 +0,0 @@
-import { Tabs } from 'antd'
-import AppTab from './AppTab'
-import TemplateTab from './TemplateTab'
-
-export default () => {
-  return (
-    <div className='p-12px'>
-      <Tabs defaultActiveKey='app' items={[
-        {key: 'app', label: '应用市场', children: <AppTab/>},
-        {key: 'module', label: '模版市场', children: <TemplateTab/>}
-      ]}/>
-    </div>
-  )
-}

+ 0 - 172
src/pages/template/index.tsx

@@ -1,172 +0,0 @@
-import { useState, useEffect } from "react";
-import ItemCard from "@/components/ItemCard";
-import { APPLICATION_SCENARIOS_OPTIONS } from "@/constants";
-import { useRequest } from "umi";
-import { GetTemplatePublicList } from "@/api/templateStore";
-import { Input, Spin, Empty, Pagination } from "antd";
-import { MODULE_TEMPLATE_TYPE } from "@/constants";
-import noDataImg from "@/assets/no-data.svg";
-import '@/style/index.less';
-
-type OptionItem = {
-  label: string;
-  value: string;
-  icon?: JSX.Element;
-};
-
-const scenes: OptionItem[] = [
-  {
-    label: "推荐",
-    icon: <i className="iconfont icon-tuijian mr-1" />,
-    value: "recommend",
-  },
-  ...APPLICATION_SCENARIOS_OPTIONS,
-];
-const categorys: OptionItem[] = [
-  { label: "全部类型", value: "all" },
-  ...MODULE_TEMPLATE_TYPE,
-];
-
-export default function Template() {
-  const [search, setSearch] = useState("");
-  const [industryFilter, setIndustryFilter] = useState("all");
-  const [sceneFilter, setSceneFilter] = useState("recommend");
-  const [currentPage, setCurrentPage] = useState(1);
-  const { data, run, loading } = useRequest(GetTemplatePublicList, {
-    defaultParams: [
-      {
-        currentPage: 1,
-        pageSize: 20,
-        filters: [
-          { name: "isDel", value: 0 },
-          { name: "isOnMarket", value: 1 },
-        ],
-      },
-    ],
-  });
-
-  useEffect(() => {
-    setCurrentPage(1);
-    run({
-      currentPage: 1,
-      pageSize: 20,
-      filters: [
-        { name: "isDel", value: 0 },
-        { name: "isOnMarket", value: 1 },
-        { name: "name", value: search },
-        {
-          name: "industries",
-          value: industryFilter === "all" ? "" : industryFilter,
-        },
-        {
-          name: "applicationScenarios",
-          value: sceneFilter === "recommend" ? "" : sceneFilter,
-        },
-      ],
-    });
-  }, [industryFilter, sceneFilter, search]);
-
-  const handleChangePage = (page: number) => {
-    setCurrentPage(page);
-    run({
-      currentPage: page,
-      pageSize: 20,
-      filters: [
-        { name: "isDel", value: 0 },
-        { name: "isOnMarket", value: 1 },
-        { name: "name", value: search },
-        {
-          name: "industries",
-          value: industryFilter === "all" ? "" : industryFilter,
-        },
-        {
-          name: "applicationScenarios",
-          value: sceneFilter === "recommend" ? "" : sceneFilter,
-        },
-      ],
-    });
-  };
-
-  const handleToAppDetail = (id: string) => {
-    window.open(`#/detail/template/${id}`, "_blank");
-  };
-
-  return (
-    <div className="flex h-full">
-      <div className="left w-fit sm:w-[216px] shrink-0 pt-6 px-4 border-gray-200 border-0 border-r border-solid border-gray-200">
-        <ul className="flex flex-col gap-y-2">
-          {categorys.map((item) => (
-            <li
-              key={item.value}
-              className={`cursor-pointer text-14px text-secondary gap-2 flex items-center pc:justify-start pc:w-full mobile:justify-center mobile:w-fit h-9 px-3 mobile:px-2 rounded-lg ${industryFilter === item.value ? "bg-white font-semibold !text-primary shadow-xs" : ""}`}
-              onClick={() => setIndustryFilter(item.value)}
-            >
-              <span>{item.label}</span>
-            </li>
-          ))}
-        </ul>
-      </div>
-      <div className="right flex-1 pt-6 px-4 h-full flex flex-col">
-        <div className="shrink-0 pt-6 px-12">
-          <div className="mb-1 text-primary text-xl font-semibold">
-            探索模块模版
-          </div>
-          <div className="text-gray-500 text-sm">
-            使用这些内容模块,可以快速完善你的系统功能模块。
-          </div>
-        </div>
-        <div className="flex items-center justify-between mt-6 px-12">
-          <div className="flex space-x-1 text-[13px] flex-wrap">
-            {scenes.map((scene) => (
-              <div
-                key={scene.value}
-                className={`cursor-pointer px-3 py-[7px] h-[32px] rounded-lg font-medium leading-[18px] cursor-pointer ${scene.value === sceneFilter ? "bg-white shadow-xs text-primary-600 text-primary" : "border-transparent text-gray-700 hover:bg-gray-200"}`}
-                onClick={() => setSceneFilter(scene.value)}
-              >
-                {scene.icon}
-                {scene.label}
-              </div>
-            ))}
-          </div>
-          <div>
-            <Input
-              value={search}
-              onChange={(e) => setSearch(e.target.value)}
-              placeholder="搜索"
-              prefix={<i className="iconfont icon-sousuo" />}
-              allowClear
-            ></Input>
-          </div>
-        </div>
-
-        <div className="relative flex flex-1 pb-6 flex-col overflow-auto bg-gray-100 shrink-0 grow mt-4">
-          <nav
-            className="style_appList grid content-start shrink-0 gap-4 px-6 sm:px-12"
-          >
-            {(data?.result?.model || []).map((item: any, index: number) => (
-              <ItemCard data={item} key={index} onClick={handleToAppDetail} />
-            ))}
-          </nav>
-
-          <Pagination
-            className="mt-6"
-            align="center"
-            hideOnSinglePage
-            pageSize={20}
-            current={currentPage}
-            total={data?.result?.totalCount || 0}
-            onChange={handleChangePage}
-          />
-
-          {!data?.result.model.length && !loading && (
-            <Empty description="暂无数据" image={noDataImg} />
-          )}
-
-          <div className="h-200px w-full absolute left-0 top0 flex items-center justify-center pointer-events-none">
-            <Spin spinning={loading} />
-          </div>
-        </div>
-      </div>
-    </div>
-  );
-}