CzRger 5 months ago
parent
commit
dfdaa4e8ca

+ 8 - 0
.env.development

@@ -0,0 +1,8 @@
+# 本地环境
+NODE_ENV = development
+
+# 标题
+VITE_TITLE = 测试路由
+
+# 基础路径
+VITE_BASE = 'trb'

+ 8 - 0
.env.production

@@ -0,0 +1,8 @@
+# 生产环境
+NODE_ENV = production
+
+# 标题
+VITE_TITLE = 测试路由
+
+# 基础路径
+VITE_BASE = 'trb'

+ 25 - 0
.gitignore

@@ -0,0 +1,25 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+smart-search-web/

+ 4 - 0
README.md

@@ -0,0 +1,4 @@
+# nodejs: 18.17.1
+# 安装依赖: yarn
+# 启动项目: npm run dev
+# 打包部署: npm run build

+ 12 - 0
index.html

@@ -0,0 +1,12 @@
+<!doctype html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <title><{VITE_TITLE}></title>
+    <link rel="icon" type="image/png" id="logo" href="/src/assets/images/global/logo.png">
+  </head>
+  <body>
+    <div id="app"></div>
+  </body>
+  <script type="module" src="/src/main.ts"></script>
+</html>

+ 41 - 0
package.json

@@ -0,0 +1,41 @@
+{
+  "name": "smart-search-web",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build --mode production",
+    "preview": "vite preview",
+    "serve": "vite --host 0.0.0.0"
+  },
+  "dependencies": {
+    "@antv/g2": "^5.2.2",
+    "@antv/g6": "^5.0.21",
+    "@types/node": "^20.14.12",
+    "axios": "^1.7.2",
+    "default-passive-events": "^2.0.0",
+    "echarts": "^5.5.1",
+    "echarts-wordcloud": "^2.1.0",
+    "element-plus": "^2.3.7",
+    "fast-glob": "^3.3.2",
+    "pinia": "^2.1.7",
+    "rollup-plugin-visualizer": "^5.12.0",
+    "sass": "^1.77.8",
+    "sortablejs": "^1.15.3",
+    "uuid": "^10.0.0",
+    "vite-plugin-compression": "^0.5.1",
+    "vite-plugin-html-env": "^1.2.8",
+    "vite-plugin-svg-icons": "^2.0.1",
+    "vite-plugin-top-level-await": "^1.4.2",
+    "vue": "^3.4.31",
+    "vue-router": "^4.4.0"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^5.0.5",
+    "postcss-px-to-viewport": "^1.1.1",
+    "typescript": "^5.2.2",
+    "vite": "^5.3.4",
+    "vue-tsc": "^2.0.24"
+  }
+}

+ 14 - 0
src/App.vue

@@ -0,0 +1,14 @@
+<template>
+  <div style="overflow: hidden; width: 100%; height: 100%;">
+    <el-config-provider :locale="zhCn">
+      <router-view/>
+    </el-config-provider>
+  </div>
+</template>
+
+<script setup lang="ts">
+import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 41 - 0
src/api/index.ts

@@ -0,0 +1,41 @@
+import HttpService from "./request";
+
+export const handle = ({url, params, method,config,filName}: any) => {
+  const httpService = new HttpService()
+  // @ts-ignore
+  return httpService[method.toLowerCase()](url, params,config,filName)
+}
+
+// @ts-ignore
+const files = import.meta.glob("/src/api/modules/**/*.ts")
+const apiModule: any = {}
+const apiRepeatMap = new Map()
+let num1 = 0
+let num2 = 0
+
+for (const [key, value] of Object.entries(files)) {
+  num1++
+  // @ts-ignore
+  value().then(res => {
+    for (const [apiKey, apiValue] of Object.entries(res)) {
+      if (apiKey !== '__tla') { // 过滤掉内部属性,非业务
+        if (apiRepeatMap.has(apiKey)) {
+          apiRepeatMap.set(apiKey, [...apiRepeatMap.get(apiKey), key])
+        } else {
+          apiRepeatMap.set(apiKey, [key])
+        }
+      }
+    }
+    Object.assign(apiModule, res)
+    num2++
+    if (num1 === num2) {
+      apiRepeatMap.forEach((v, k) => {
+        if (v.length > 1) {
+          console.error(`检测到接口${k}重复定义,路径为:`, v)
+        }
+      })
+    }
+  })
+}
+
+export default apiModule

+ 86 - 0
src/api/interceptors.ts

@@ -0,0 +1,86 @@
+import axios from 'axios';
+import {ElMessage} from "element-plus";
+import {toLogin} from "@/utils/permissions";
+export class Interceptors {
+  public instance: any
+
+  constructor() {
+    this.instance = axios.create({
+      baseURL: '/ssw-api', // api base_url
+      timeout: 1000 * 300})
+    this.initInterceptors()
+  }
+
+  public getInterceptors() {
+    return this.instance
+  }
+
+  public initInterceptors() {
+    // this.instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8'
+    /**
+     * 请求拦截器
+     * 每次请求前,如果存在token则在请求头中携带token
+     */
+    this.instance.interceptors.request.use(
+      (config: any) => {
+        if (!config.headers.Authorization) {
+          const token = localStorage.getItem('ss_token');
+          if (token) {
+            config.headers.Authorization = token;
+          } else {
+            // @ts-ignore
+            delete config.headers.Authorization
+          }
+        }
+        return config;
+      },
+      (error: any) => {
+      }
+    );
+
+    // 响应拦截器
+    this.instance.interceptors.response.use(
+      // 请求成功
+      (res: any) => {
+        if(res.data.code === 200){
+          return Promise.resolve(res.data);
+        } else if (res.data.code === 500) {
+          ElMessage.error(res.data?.msg);
+          return Promise.reject(res.data?.msg)
+        } else {
+          return Promise.resolve(res);
+        }
+      },
+      // 请求失败
+      (error: { response: any; }) => {
+        const { response } = error;
+        if (response) {
+          // 请求已发出,但是不在2xx的范围
+          this.errorHandle(response);
+          return Promise.reject(response.data);
+        } else {
+          ElMessage.warning('网络连接异常,请稍后再试!');
+          // 抛出报错信息,在页面里需要接收
+          return Promise.reject(error);
+        }
+      });
+  }
+
+  private errorHandle(res: any) {
+    console.error('错误接口:' + res.data.path)
+    // 状态码判断
+    switch (res.status) {
+      case 401:
+        ElMessage.warning(res.data.msg);
+        toLogin()
+        break;
+      case 403:
+        break;
+      case 404:
+        ElMessage.error('请求的资源不存在');
+        break;
+      default:
+        ElMessage.warning('连接错误');
+    }
+  }
+}

+ 37 - 0
src/api/modules/manage/dict.ts

@@ -0,0 +1,37 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 查询字典项
+export const dictGetAllSysDictsByValue = (params) => handle({
+  url: `/${suffix}/api/dict/getAllSysDictsByValue`,
+  method: 'get',
+  params
+})
+// 查询所有字典项
+export const dictList = () => handle({
+  url: `/${suffix}/api/dict`,
+  method: 'get',
+})
+// 创建字典项
+export const dictAdd = (params: any) => handle({
+  url: `/${suffix}/api/dict`,
+  method: 'post',
+  params
+})
+// 删除字典项
+export const dictDel = (id: any) => handle({
+  url: `/${suffix}/api/dict/${id}`,
+  method: 'delete',
+})
+// 删除字典项
+export const dictInfo = (id: any) => handle({
+  url: `/${suffix}/api/dict/${id}`,
+  method: 'get',
+})
+// 更新字典项
+export const dictEdit = (params: any) => handle({
+  url: `/${suffix}/api/dict`,
+  method: 'put',
+  params
+})

+ 10 - 0
src/api/modules/manage/global.ts

@@ -0,0 +1,10 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 文件上传
+export const frontUploadFile = (params: any) => handle({
+  url: `/${suffix}/front/uploadFile`,
+  method: 'post',
+  params
+})

+ 10 - 0
src/api/modules/manage/home.ts

@@ -0,0 +1,10 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 统计查询
+export const searchLogsGetStatistics = (params: any) => handle({
+  url: `/${suffix}/search-logs/getStatistics`,
+  method: 'post',
+  params
+})

+ 81 - 0
src/api/modules/manage/index.ts

@@ -0,0 +1,81 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 带条件分页查询索引信息
+export const sysIndexFindIndexByPage = (params: any) => handle({
+  url: `/${suffix}/sys-index/findIndexByPage`,
+  method: 'get',
+  params
+})
+// 新增||编辑
+export const sysIndexSaveOrUpdate = (params: any) => handle({
+  url: `/${suffix}/sys-index/saveOrUpdate`,
+  method: 'post',
+  params
+})
+// 详情
+export const sysIndexGetDetail = (id: any) => handle({
+  url: `/${suffix}/sys-index/getDetail/${id}`,
+  method: 'get',
+})
+// 关联分类
+export const sysIndexFindAllByIndexId = (id: any) => handle({
+  url: `/${suffix}/sys-index/findAllByIndexId/${id}`,
+  method: 'get',
+})
+// 创建索引关联分类
+export const sysIndexCreate = (params: any) => handle({
+  url: `/${suffix}/sys-index/create`,
+  method: 'post',
+  params
+})
+// 删除索引关联分类
+export const sysIndexDeleteByLinkId = (id: any) => handle({
+  url: `/${suffix}/sys-index/deleteByLinkId/${id}`,
+  method: 'get',
+})
+// 索引id查询字段列表信息
+export const sysIndexFieldList = (params: any) => handle({
+  url: `/${suffix}/sys-index-field/list`,
+  method: 'get',
+  params
+})
+// 新增或修改索引字段信息
+export const sysIndexFieldSaveOrUpdate = (params: any) => handle({
+  url: `/${suffix}/sys-index-field/saveOrUpdate`,
+  method: 'post',
+  params
+})
+// 根据ID删除索引字段信息
+export const sysIndexFieldDeleteById = (id: any) => handle({
+  url: `/${suffix}/sys-index-field/deleteById/${id}`,
+  method: 'get',
+})
+// 删除
+export const sysIndexDeleteIndexById = (id: any) => handle({
+  url: `/${suffix}/sys-index/deleteIndexById/${id}`,
+  method: 'get',
+})
+// 导出
+export const sysIndexExport = (params: any) => handle({
+  url: `/${suffix}/sys-index/export`,
+  method: 'get',
+  params
+})
+// 关联主题-保存
+export const sysIndexSaveThemeInfo = (params: any) => handle({
+  url: `/${suffix}/sys-index/saveThemeInfo`,
+  method: 'post',
+  params
+})
+// 关联主题-查询
+export const sysIndexGetThemeByIndex = (id: any) => handle({
+  url: `/${suffix}/sys-index/getThemeByIndex/${id}`,
+  method: 'get',
+})
+// 创建索引
+export const sysIndexCreateEsIndex = (code: any) => handle({
+  url: `/${suffix}/sys-index/createEsIndex/${code}`,
+  method: 'get',
+})

+ 10 - 0
src/api/modules/manage/log.ts

@@ -0,0 +1,10 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 分页
+export const searchLogsGetLogByPage = (params: any) => handle({
+  url: `/${suffix}/search-logs/getLogByPage`,
+  method: 'get',
+  params
+})

+ 43 - 0
src/api/modules/manage/role.ts

@@ -0,0 +1,43 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 分页
+export const rolesGetByPage = (params: any) => handle({
+  url: `/${suffix}/roles/getByPage`,
+  method: 'get',
+  params
+})
+// 详情
+export const rolesGetRoleById = (id: any) => handle({
+  url: `/${suffix}/roles/getRoleById/${id}`,
+  method: 'get',
+})
+// 新增
+export const rolesCreate = (params: any) => handle({
+  url: `/${suffix}/roles/create`,
+  method: 'post',
+  params
+})
+// 编辑
+export const rolesUpdate = (params: any) => handle({
+  url: `/${suffix}/roles/update`,
+  method: 'post',
+  params
+})
+// 删除
+export const rolesDelete = (id: any) => handle({
+  url: `/${suffix}/roles/delete/${id}`,
+  method: 'get',
+})
+// 授权
+export const rolesDoAuthorization = (params: any) => handle({
+  url: `/${suffix}/roles/doAuthorization`,
+  method: 'post',
+  params
+})
+// 授权查看
+export const rolesFindAllByRoleId = (id: any) => handle({
+  url: `/${suffix}/roles/findAllByRoleId/${id}`,
+  method: 'get',
+})

+ 47 - 0
src/api/modules/manage/service.ts

@@ -0,0 +1,47 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 归属插件
+export const sysPluginGetAllPlugins = () => handle({
+  url: `/${suffix}/sysPlugin/getAllPlugins`,
+  method: 'get',
+})
+// 解析插件
+export const sysPluginGetAllParsePlugins = () => handle({
+  url: `/${suffix}/sysPlugin/getAllParsePlugins`,
+  method: 'get',
+})
+// 新增|编辑
+export const outsideServiceSaveOrUpdate = (params: any) => handle({
+  url: `/${suffix}/api/outsideService/saveOrUpdate`,
+  method: 'post',
+  params
+})
+// 分页查询
+export const outsideServiceFindByPage = (params: any) => handle({
+  url: `/${suffix}/api/outsideService/findByPage`,
+  method: 'get',
+  params
+})
+// 启用|停用
+export const outsideServiceStatusUpdate = (params: any) => handle({
+  url: `/${suffix}/api/outsideService/statusUpdate`,
+  method: 'get',
+  params
+})
+// 详情
+export const outsideServiceFindById = (id: any) => handle({
+  url: `/${suffix}/api/outsideService/findById/${id}`,
+  method: 'get',
+})
+// 删除
+export const outsideServiceDelete = (id: any) => handle({
+  url: `/${suffix}/api/outsideService/delete/${id}`,
+  method: 'get',
+})
+// 主题
+export const outsideServiceTheme = (id: any) => handle({
+  url: `/${suffix}/api/outsideService/theme/${id}`,
+  method: 'get',
+})

+ 88 - 0
src/api/modules/manage/theme.ts

@@ -0,0 +1,88 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 分页列表
+export const sysThemeGetPageTheme = (params: any) => handle({
+  url: `/${suffix}/sysTheme/getPageTheme`,
+  method: 'get',
+  params
+})
+// 新增
+export const sysThemeAdd = (params: any) => handle({
+  url: `/${suffix}/sysTheme/add`,
+  method: 'post',
+  params
+})
+// 编辑
+export const sysThemeUpdate = (params: any) => handle({
+  url: `/${suffix}/sysTheme/update`,
+  method: 'post',
+  params
+})
+// 配置
+export const sysThemeStyleConfig = (params: any) => handle({
+  url: `/${suffix}/sysTheme/styleConfig`,
+  method: 'post',
+  params
+})
+// 详情
+export const sysThemeFind = (id: any) => handle({
+  url: `/${suffix}/sysTheme/find/${id}`,
+  method: 'get',
+})
+// 删除
+export const sysThemeDelete = (id: any) => handle({
+  url: `/${suffix}/sysTheme/delete/${id}`,
+  method: 'get',
+})
+// 列表
+export const sysThemeIndexFindAll = (id: any) => handle({
+  url: `/${suffix}/sysThemeIndex/findAll/${id}`,
+  method: 'get',
+})
+// 索引构成新增
+export const sysThemeIndexAdd = (params: any) => handle({
+  url: `/${suffix}/sysThemeIndex/add`,
+  method: 'post',
+  params
+})
+// 索引构成编辑
+export const sysThemeIndexUpdate = (params: any) => handle({
+  url: `/${suffix}/sysThemeIndex/update`,
+  method: 'post',
+  params
+})
+// 索引构成详情
+export const sysThemeIndexFindById = (id: any) => handle({
+  url: `/${suffix}/sysThemeIndex/findById/${id}`,
+  method: 'get',
+})
+// 索引构成配置列保存
+export const sysThemeIndexSaveIndexFields = (params: any) => handle({
+  url: `/${suffix}/sysThemeIndex/saveIndexFields`,
+  method: 'post',
+  params
+})
+// 索引构成配置列查看
+export const sysThemeIndexGetIndexFields = (params: any) => handle({
+  url: `/${suffix}/sysThemeIndex/getIndexFields`,
+  method: 'get',
+  params
+})
+// 索引构成主配置
+export const sysThemeIndexMainConfig = (params: any) => handle({
+  url: `/${suffix}/sysThemeIndex/mainConfig`,
+  method: 'post',
+  params
+})
+// 索引构成删除
+export const sysThemeIndexDelete = (id: any) => handle({
+  url: `/${suffix}/sysThemeIndex/delete/${id}`,
+  method: 'get',
+})
+// 获取当前主题
+export const sysThemeGetThemeByThemeType = () => handle({
+  url: `/${suffix}/sysTheme/getThemeByThemeType/1`,
+  method: 'get',
+})

+ 53 - 0
src/api/modules/manage/type.ts

@@ -0,0 +1,53 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 查询所有分类
+export const sysLabelGetAllSysLabels = () => handle({
+  url: `/${suffix}/sys/label/getAllSysLabels`,
+  method: 'get',
+})
+// 新增标签
+export const sysLabelSave = (params: any) => handle({
+  url: `/${suffix}/sys/label/save`,
+  method: 'post',
+  params
+})
+// 编辑标签
+export const sysLabelUpdate = (params: any) => handle({
+  url: `/${suffix}/sys/label/update`,
+  method: 'post',
+  params
+})
+// 删除标签
+export const sysLabelDelete = (id: any) => handle({
+  url: `/${suffix}/sys/label/delete/${id}`,
+  method: 'get',
+})
+// 查询详情
+export const sysLabelDetail = (id: any) => handle({
+  url: `/${suffix}/sys/label/detail/${id}`,
+  method: 'get',
+})
+// 查询所有索引
+export const sysLabelGetAllIndexsByKey = (params: any) => handle({
+  url: `/${suffix}/sys/label/getAllIndexsByKey`,
+  method: 'get',
+  params
+})
+// 查询所有标签关联索引
+export const sysLabelGetAllSysLabelTypes = (id: any) => handle({
+  url: `/${suffix}/sys/label/getAllSysLabelTypes/${id}`,
+  method: 'get',
+})
+// 新增索引到指定分类下
+export const sysLabelAddIndexToLabel = (params: any) => handle({
+  url: `/${suffix}/sys/label/addIndexToLabel`,
+  method: 'get',
+  params
+})
+// 新增索引到指定分类下
+export const sysLabelDeleteLink = (id: any) => handle({
+  url: `/${suffix}/sys/label/deleteLink/${id}`,
+  method: 'get',
+})

+ 65 - 0
src/api/modules/manage/user.ts

@@ -0,0 +1,65 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 验证码
+export const captcha = () => handle({
+  url: `/${suffix}/captcha`,
+  method: 'get',
+})
+// 登录
+export const login = (params: any) => handle({
+  url: `/${suffix}/login`,
+  method: 'post',
+  params
+})
+// 验证码
+export const getCurrentUser = () => handle({
+  url: `/${suffix}/getCurrentUser`,
+  method: 'get',
+})
+// 分页列表
+export const usersGetPageUser = (params: any) => handle({
+  url: `/${suffix}/users/getPageUser`,
+  method: 'get',
+  params
+})
+// 详情
+export const usersGetUserById = (id: any) => handle({
+  url: `/${suffix}/users/getUserById/${id}`,
+  method: 'get',
+})
+// 新增
+export const usersRegister = (params: any) => handle({
+  url: `/${suffix}/users/register`,
+  method: 'post',
+  params
+})
+// 编辑
+export const usersUpdate = (params: any) => handle({
+  url: `/${suffix}/users/update`,
+  method: 'post',
+  params
+})
+// 修改密码
+export const usersUpdatePassword = (params: any) => handle({
+  url: `/${suffix}/users/updatePassword`,
+  method: 'post',
+  params
+})
+// 删除
+export const usersDeleteUser = (id: any) => handle({
+  url: `/${suffix}/users/deleteUser/${id}`,
+  method: 'get',
+})
+// 查看授权
+export const usersGetAuthorization = (id: any) => handle({
+  url: `/${suffix}/users/getAuthorization/${id}`,
+  method: 'get',
+})
+// 授权
+export const usersDoAuthorization = (params: any) => handle({
+  url: `/${suffix}/users/doAuthorization`,
+  method: 'post',
+  params
+})

+ 21 - 0
src/api/modules/mock/mock.ts

@@ -0,0 +1,21 @@
+import { handle } from '../../index'
+
+const suffix = 'mock-api'
+
+// 模拟接口
+export const mockGetUserInfo = () => handle({
+  url: `/${suffix}/getUserInfo`,
+  method: 'get',
+})
+export const mockGetConfig = () => handle({
+  url: `/${suffix}/getConfig`,
+  method: 'get',
+})
+export const mockGetSearchHistory = () => handle({
+  url: `/${suffix}/getSearchHistory`,
+  method: 'get',
+})
+export const mockGetSearchArea = () => handle({
+  url: `/${suffix}/getSearchArea`,
+  method: 'get',
+})

+ 36 - 0
src/api/modules/web/list.ts

@@ -0,0 +1,36 @@
+import { handle } from '../../index'
+
+const suffix = 'api'
+
+// 查询所有分类
+export const frontGetAllSysLabelsForQd = () => handle({
+  url: `/${suffix}/front/getAllSysLabelsForQd`,
+  method: 'get',
+})
+
+// 根据索引id获取索引信息级索引字段信息
+export const frontGetIndexAndFieldInfo = (params: any) => handle({
+  url: `/${suffix}/front/getIndexAndFieldInfo`,
+  method: 'get',
+  params
+})
+
+// 搜索记录
+export const searchLogsGetKeyWordByUserId = (params: any) => handle({
+  url: `/${suffix}/search-logs/getKeyWordByUserId`,
+  method: 'get',
+  params
+})
+
+// 档案主题
+export const frontGetThemeByThemeId = (id: any) => handle({
+  url: `/${suffix}/front/getThemeByThemeId/${id}`,
+  method: 'get',
+})
+
+// 保存搜索记录
+export const searchLogsSaveSearchLog = (params: any) => handle({
+  url: `/${suffix}/search-logs/saveSearchLog`,
+  method: 'post',
+  params
+})

+ 97 - 0
src/api/request.ts

@@ -0,0 +1,97 @@
+import { Interceptors } from './interceptors';
+export class HttpRequest {
+  public axios: any
+  constructor() {
+    // 获取axios实例
+    this.axios = new Interceptors().getInterceptors();
+  }
+  public get(url: string, params: String, config: Object = {}) {
+    return new Promise((resolve, reject) => {
+      let paramUrl = url
+      if (params) {
+        paramUrl += `?${params}`
+      }
+      this.axios.get(paramUrl, {
+        ...config
+      }).then((res: any) => {
+        this.resultHandle(res, resolve, reject, url);
+      }).catch((err: { message: any; }) => {
+        console.log(err)
+        reject(err.message);
+      })
+    })
+  }
+
+  public post(url: string, params: Object, config: Object = {}) {
+    return new Promise((resolve, reject) => {
+      this.axios.post(url, params, {
+        ...config   //  导出添加的下载类型
+      }).then((res: any) => {
+        this.resultHandle(res, resolve, reject, url);
+      }).catch((err: { message: any; }) => {
+        reject(err.message);
+      })
+    })
+  }
+
+  public delete(url: string, params: String, config: Object = {}) {
+    return new Promise((resolve, reject) => {
+      let paramUrl = url
+      if (params) {
+        paramUrl += `?${params}`
+      }
+      this.axios.delete(paramUrl, {
+        ...config
+      }).then((res: any) => {
+        this.resultHandle(res, resolve, reject, url);
+      }).catch((err: { message: any; }) => {
+        console.log(err)
+        reject(err.message);
+      })
+    })
+  }
+  public put(url: string, params: Object, config: Object = {}) {
+    return new Promise((resolve, reject) => {
+      this.axios.put(url, params, {
+        ...config   //  导出添加的下载类型
+      }).then((res: any) => {
+        this.resultHandle(res, resolve, reject, url);
+      }).catch((err: { message: any; }) => {
+        reject(err.message);
+      })
+    })
+  }
+
+
+  public resultHandle(res: any, resolve: { (value: unknown): void; (value: unknown): void; (arg0: any): void; },reject: { (value: unknown): void; (value: unknown): void; (arg0: any): void; }, url: string) {
+    if (res) {
+      if (res.code === 200 || (res.size > 0 && res.type)) {   //  增加blob文件判断
+        resolve(res);
+      } else {
+        resolve(res);
+        // this.errorHandle(res, reject, url);
+      }
+    }
+  }
+  public errorHandle(res: any, reject: any, url: string) {
+    console.error('错误接口:' + url)
+    if (res.hasOwnProperty('message')) {
+      // ElMessage.warning(res.message);  // 统一谈服务端提示,我们提示统一由服务端提供
+    } else if (res.hasOwnProperty('msg')) {
+      // ElMessage.warning(res.msg);  // 统一谈服务端提示,我们提示统一由服务端提供
+    }
+    // 状态码判断
+    if (res) {
+      switch (res.code) {
+        case -102:
+          break;
+        case -152:
+          break;
+        default:
+          reject(res);
+      }
+    }
+  }
+}
+
+export default HttpRequest

+ 14 - 0
src/browerPatch.ts

@@ -0,0 +1,14 @@
+// @ts-ignore
+;(function () {
+    if (typeof EventTarget !== 'undefined') {
+        const func = EventTarget.prototype.addEventListener
+        EventTarget.prototype.addEventListener = function (type, fn, capture) {
+            ;(this as any).func = func
+            if (typeof capture !== 'boolean') {
+                capture = capture || {}
+                capture.passive = false
+            }
+            ;(this as any).func(type, fn, capture)
+        }
+    }
+})()

+ 53 - 0
src/components/SvgIcon/index.vue

@@ -0,0 +1,53 @@
+<template>
+  <svg aria-hidden="true" class="svg-icon" :style="`width: ${size}px;height: ${size}px;transform: rotate(${rotate}deg);`">
+    <use :xlink:href="symbolId" :fill="color" />
+  </svg>
+</template>
+
+
+<script lang="ts">
+  import {
+    defineComponent,
+    computed,
+  } from "vue";
+  export default defineComponent({
+    name: "SvgIcon",
+    components: {},
+    props: {
+      prefix: {
+        type: String,
+        default: 'icon'
+      },
+      name: {
+        type: String,
+        required: true
+      },
+      color: {
+        type: String,
+        default: ''
+      },
+      size: {
+        type: [Number, String],
+        default: '18'
+      },
+      rotate: {
+        type: [Number, String],
+        default: 0
+      }
+    },
+    setup(props, { emit }) {
+      const symbolId = computed(() => `#${props.prefix}-${props.name}`)
+      return {
+        symbolId
+      }
+    }
+  })
+</script>
+
+<style scoped>
+.svg-icon {
+  vertical-align: -0.15em;
+  overflow: hidden;
+  fill: currentColor;
+}
+</style>

+ 42 - 0
src/layout/router-view.vue

@@ -0,0 +1,42 @@
+<template>
+  <router-view v-slot="{ Component }">
+<!--    <transition>-->
+      <keep-alive>
+        <component :is="Component" />
+      </keep-alive>
+<!--    </transition>-->
+  </router-view>
+</template>
+
+<script lang="ts">
+import {
+  defineComponent,
+  computed,
+  onMounted,
+  ref,
+  reactive,
+  watch,
+  getCurrentInstance,
+  ComponentInternalInstance,
+  toRefs,
+  nextTick
+} from 'vue'
+import {useRouter, useRoute} from 'vue-router'
+
+export default defineComponent({
+  name: '',
+  components: {},
+  setup() {
+    const router = useRouter();
+    const route = useRoute();
+    const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
+    const state = reactive({})
+    return {
+      ...toRefs(state)
+    }
+  },
+})
+</script>
+
+<style scoped lang="scss">
+</style>

+ 19 - 0
src/main.ts

@@ -0,0 +1,19 @@
+import { createApp } from 'vue'
+import App from './App.vue'
+import router from './router'
+import 'virtual:svg-icons-register'    // 【svg-icons相关】
+import 'default-passive-events'
+import './browerPatch'
+import { createPinia } from 'pinia'
+import ElementPlus, {ElNotification} from 'element-plus'
+import 'element-plus/dist/index.css'
+
+
+const app = createApp(App)
+app.use(createPinia())
+app.use(router)
+app.use(ElementPlus as any)
+app.mount('#app')
+// 设置为 true 以在浏览器开发工具的 performance/timeline 面板中启用对组件初始化、编译、渲染和更新的性能追踪。
+app.config.performance = true
+

+ 21 - 0
src/router/index.ts

@@ -0,0 +1,21 @@
+import {createRouter, createWebHistory} from 'vue-router'
+import staticRouter from './modules/static'
+import Temp404 from '@/views/global/temp/404.vue'
+
+
+const routes = [
+    ...staticRouter,
+    { path: '/:pathMatch(.*)*', name: 'NotFound', component: Temp404 },
+    { path: '', redirect: '/web' },
+]
+
+const router = createRouter({
+    history: createWebHistory(import.meta.env.BASE_URL),
+    routes,
+});
+
+router.beforeEach((to, from , next) => {
+    next()
+})
+
+export default router;

+ 13 - 0
src/router/modules/static.ts

@@ -0,0 +1,13 @@
+// 不需要菜单管理配置的路由
+const staticRouter = [
+  {
+    path: '/a',
+    name: 'login',
+    component: () => import('@/views/global/a.vue'),
+    meta: {
+      title: '登录',
+      noToken: true
+    }
+  },
+]
+export default staticRouter

+ 11 - 0
src/stores/app.ts

@@ -0,0 +1,11 @@
+import {defineStore} from "pinia";
+
+export const useAppStore = defineStore('app', {
+  state: () => ({
+    token: localStorage.getItem('ss_token'),
+  }),
+  getters: {
+  },
+  actions: {
+  },
+})

+ 15 - 0
src/views/global/a.vue

@@ -0,0 +1,15 @@
+<template>
+  <div style="font-size: 400px">
+    aaa
+  </div>
+</template>
+
+<script setup lang="ts">
+import {getCurrentInstance, reactive} from "vue";
+
+const {proxy} = getCurrentInstance()
+const state: any = reactive({})
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 15 - 0
src/views/global/temp/404.vue

@@ -0,0 +1,15 @@
+<template>
+  <div style="font-size: 400px">
+    404
+  </div>
+</template>
+
+<script setup lang="ts">
+import {getCurrentInstance, reactive} from "vue";
+
+const {proxy} = getCurrentInstance()
+const state: any = reactive({})
+</script>
+
+<style lang="scss" scoped>
+</style>

+ 30 - 0
tsconfig.json

@@ -0,0 +1,30 @@
+{
+  "compilerOptions": {
+    "noImplicitAny": false,
+    "allowJs": true,
+    "target": "ESNext",
+    "useDefineForClassFields": true,
+    "module": "ESNext",
+    "moduleResolution": "Node",
+    "strict": true,
+    "jsx": "preserve",
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "esModuleInterop": true,
+    "lib": ["ESNext", "DOM"],
+    "skipLibCheck": true,
+    "noEmit": true,
+    "baseUrl": "./",
+    "paths": {
+      "@/*": [
+        "./src/*"
+      ]
+    },
+    "types": [
+      "vite-plugin-svg-icons/client", // 【svg-icons相关】
+      "node"  // 【svg-icons相关】
+    ]
+  },
+  "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
+  "references": [{ "path": "./tsconfig.node.json" }]
+}

+ 9 - 0
tsconfig.node.json

@@ -0,0 +1,9 @@
+{
+  "compilerOptions": {
+    "composite": true,
+    "module": "ESNext",
+    "moduleResolution": "Node",
+    "allowSyntheticDefaultImports": true
+  },
+  "include": ["vite.config.ts"]
+}

+ 124 - 0
vite.config.ts

@@ -0,0 +1,124 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+import topLevelAwait from 'vite-plugin-top-level-await'
+import { resolve } from 'path'
+import viteCompression from 'vite-plugin-compression';//Gzip
+import { visualizer } from "rollup-plugin-visualizer";
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' // 【svg-icons相关】
+import VitePluginHtmlEnv from 'vite-plugin-html-env'
+import postcsspxtoviewport from 'postcss-px-to-viewport'
+
+const time = new Date().getTime()
+export default defineConfig({
+  define: {
+    'process.env': process.env
+  },
+  plugins: [
+    vue(),
+    viteCompression(),
+    VitePluginHtmlEnv(),
+    visualizer(),
+    createSvgIconsPlugin({
+      // 指定需要缓存的图标文件夹
+      iconDirs: [resolve(process.cwd(), 'src/assets/svg')],
+      // 指定symbolId格式
+      symbolId: 'icon-[dir]-[name]',
+      // svgoOptions: {
+      //   plugins: [
+      //     {
+      //       name: 'removeAttrs',
+      //       params: {
+      //         attrs: ['class', 'data-name', 'fill', 'stroke']
+      //       }
+      //     }
+      //   ]
+      // }
+    }),
+
+    topLevelAwait({
+      promiseExportName: '__tla',
+      promiseImportName: i => `__tla_${i}`
+    })
+  ],
+  // base: '/smart-search-web/',
+  resolve: {
+    alias: {
+      '@': resolve(__dirname, 'src'),
+    },
+  },
+  server: {
+    port: 3853,
+    host: '0.0.0.0',
+    open: true,
+    strictPort: false,
+    proxy: {
+      '/mock-api': {
+        target: 'http://localhost:18061/',
+        changeOrigin: true,
+        rewrite: (path) => {
+          return path.replace(/^\/mock-api/, 'mock-api')
+        }
+      },
+      '/ssw-api/api': {
+        // target: 'http://10.110.45.26:18069/',
+        target: 'http://8.130.72.63:18068/',
+        changeOrigin: true,
+        rewrite: (path) => {
+          return path.replace(/^\/ssw-api\/api/, '')
+          // console.log(path)
+          // return path
+        }
+      },
+      '/ws-api': {
+        target: 'ws://8.130.72.63:18073/',
+        // target: 'ws://10.110.45.26:18069/ws-api',
+        ws: true,
+        changeOrigin: true,
+        rewrite: path => {
+          return path.replace(/^\/ws-api/, '')
+        }
+      },
+    }
+  },
+  css: {
+    postcss: {
+      plugins: [
+        postcsspxtoviewport({
+          unitToConvert: 'px',
+          viewportWidth: 1920,
+          unitPrecision: 5, // 单位转换后保留的精度
+          propList: ['*'], // 能转化为vw的属性列表
+          viewportUnit: 'vw', // 希望使用的视口单位
+          fontViewportUnit: 'vw', // 字体使用的视口单位
+          selectorBlackList: ['ignore-'], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
+          minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
+          mediaQuery: true, // 媒体查询里的单位是否需要转换单位
+          replace: true, //  是否直接更换属性值,而不添加备用属性
+          exclude: [], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
+          include: [], // 如果设置了include,那将只有匹配到的文件才会被转换
+          landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
+          landscapeUnit: 'vw', // 横屏时使用的单位
+          landscapeWidth: 1628, // 横屏时使用的视口宽度
+        }),
+      ]
+    }
+  },
+  build: {
+    outDir: "smart-search-web",
+    rollupOptions: {//分包优化
+      output: {
+        manualChunks(id) {
+          if (id.includes('node_modules')) {
+            return time + id.toString().split('node_modules/')[1].split('/')[0].toString();
+          } else {
+            return time + id.toString();
+          }
+        }
+      }
+    }
+  },
+  publicDir: 'src/out',
+  optimizeDeps: {
+    include: []
+  }
+} as any)

File diff suppressed because it is too large
+ 3951 - 0
yarn.lock