Browse Source

first commit

master
wxc 6 months ago
commit
4c9738d73f
  1. 1
      .browserslistrc
  2. 2
      .env.dev
  3. 3
      .env.prod
  4. 11
      .gitignore
  5. 12
      README.md
  6. 17
      index.html
  7. 44
      package.json
  8. 1
      plugin/assets/401.1738752173979.css
  9. 1
      plugin/assets/401.1738752173979.js
  10. 1
      plugin/assets/VerifySubmit.1738752173979.css
  11. 289
      plugin/assets/VerifySubmit.1738752173979.js
  12. 1
      plugin/assets/_plugin-vue_export-helper.1738752173979.css
  13. 1
      plugin/assets/_plugin-vue_export-helper.1738752173979.js
  14. 0
      plugin/assets/echarts.1738752173979.js
  15. 1
      plugin/assets/index.1738752173979.css
  16. 7
      plugin/assets/index.1738752173979.js
  17. 26
      plugin/assets/vue.1738752173979.js
  18. BIN
      plugin/favicon.png
  19. BIN
      plugin/imgs/401.gif
  20. 19
      plugin/index.html
  21. BIN
      public/favicon.png
  22. BIN
      public/imgs/401.gif
  23. 14
      src/App.vue
  24. 113
      src/api/request.ts
  25. 66
      src/api/system/depart.ts
  26. 67
      src/api/system/dict.ts
  27. 27
      src/api/system/dictContent.ts
  28. 54
      src/api/system/police.ts
  29. 42
      src/api/work/alarm.ts
  30. 27
      src/api/work/dictContent.ts
  31. 21
      src/api/work/fav.ts
  32. 7
      src/api/work/flowNode.ts
  33. 15
      src/api/work/index.ts
  34. 97
      src/api/work/negative.ts
  35. 35
      src/api/work/negativeTask.ts
  36. 28
      src/api/work/news.ts
  37. 22096
      src/assets/data/changsha.json
  38. 494
      src/assets/data/map.js
  39. 20
      src/assets/data/浏阳市.json
  40. 20
      src/assets/icons/completedApprove.svg
  41. 20
      src/assets/icons/delay.svg
  42. 1
      src/assets/icons/doc.svg
  43. 13
      src/assets/icons/ic_01.svg
  44. 13
      src/assets/icons/ic_02.svg
  45. 13
      src/assets/icons/ic_03.svg
  46. 13
      src/assets/icons/ic_04.svg
  47. 14
      src/assets/icons/ic_05.svg
  48. 14
      src/assets/icons/ic_06.svg
  49. 14
      src/assets/icons/ic_07.svg
  50. 13
      src/assets/icons/ic_08.svg
  51. 13
      src/assets/icons/ic_09.svg
  52. 13
      src/assets/icons/ic_10.svg
  53. 11
      src/assets/icons/ic_11.svg
  54. 13
      src/assets/icons/ic_12.svg
  55. 13
      src/assets/icons/ic_13.svg
  56. 13
      src/assets/icons/ic_14.svg
  57. 13
      src/assets/icons/ic_15.svg
  58. 13
      src/assets/icons/ic_16.svg
  59. 13
      src/assets/icons/ic_17.svg
  60. 13
      src/assets/icons/ic_18.svg
  61. 11
      src/assets/icons/ic_19.svg
  62. 10
      src/assets/icons/lock-fill.svg
  63. 1
      src/assets/icons/logout.svg
  64. 1
      src/assets/icons/menu.svg
  65. 1
      src/assets/icons/mp3.svg
  66. 1
      src/assets/icons/mp4.svg
  67. 1
      src/assets/icons/pdf.svg
  68. 1
      src/assets/icons/police.svg
  69. 1
      src/assets/icons/question.svg
  70. 1
      src/assets/icons/rotate-left.svg
  71. 1
      src/assets/icons/rotate-right.svg
  72. 19
      src/assets/icons/sign.svg
  73. 22
      src/assets/icons/verify.svg
  74. 1
      src/assets/icons/xls.svg
  75. 66
      src/components/countdown.vue
  76. 52
      src/components/date-time-range-picker-ext.vue
  77. 41
      src/components/depart-tree-select.vue
  78. 61
      src/components/description-pair.vue
  79. 38
      src/components/dict-select.vue
  80. 31
      src/components/el-form-item-ext.vue
  81. 504
      src/components/file/list.vue
  82. 327
      src/components/file/upload-group.vue
  83. 105
      src/components/file/upload.vue
  84. 19
      src/components/icon/index.ts
  85. 53
      src/components/icon/index.vue
  86. 182
      src/components/icon/picker.vue
  87. 38
      src/components/icon/svg-icon.vue
  88. 43
      src/components/loading.vue
  89. 93
      src/components/negative/description.vue
  90. 52
      src/components/negative/sign-return-description.vue
  91. 258
      src/components/negative/verify-description.vue
  92. 1582
      src/components/negative/verify.vue
  93. 93
      src/components/police-select.vue
  94. 44
      src/components/problem-type-select.vue
  95. 21
      src/enums/appEnums.ts
  96. 136
      src/enums/dictEnums.ts
  97. 9
      src/enums/fileEnums.ts
  98. 36
      src/enums/flowEnums.ts
  99. 5
      src/enums/pageEnum.ts
  100. 28
      src/install/directives/perms.ts
  101. Some files were not shown because too many files have changed in this diff Show More

1
.browserslistrc

@ -0,0 +1 @@
ie >= 11

2
.env.dev

@ -0,0 +1,2 @@
VITE_BASE=/
VITE_PROFILES=dev

3
.env.prod

@ -0,0 +1,3 @@
VITE_BASE=/plugin/
VITE_PROFILES=prod

11
.gitignore vendored

@ -0,0 +1,11 @@
.history/
/node_modules/
/v2/
*.zip
.idea
package-lock.json
pnpm-lock.yaml
auto-imports.d.ts
components.d.ts
vite.config.ts.timestamp-*

12
README.md

@ -0,0 +1,12 @@
# 数字督察
## 安装
```bash
# 使用淘宝源
npm config set registry https://registry.npmmirror.com
npm install
```
## 运行
```bash
npm run start
```

17
index.html

@ -0,0 +1,17 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>数字督察一体化平台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

44
package.json

@ -0,0 +1,44 @@
{
"name": "supervision-plugin-vue",
"private": true,
"version": "1.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build --mode dev",
"build:prod": "vite build --mode prod && WinRAR a -r plugin.zip ./plugin/",
"preview": "vite preview"
},
"engines": {
"nodejs": ">=16.0.0",
"npm": ">=7.0.0"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vue-office/docx": "^1.6.0",
"@vue-office/excel": "^1.7.11",
"crypto-js": "^4.2.0",
"element-plus": "^2.8.8",
"install": "^0.13.0",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"nprogress": "^0.2.0",
"perfect-scrollbar": "^1.5.6",
"pinia": "^2.1.7",
"typescript": "^5.3.3",
"vue": "^3.3.11",
"vue-echarts": "^6.6.8",
"vue-perfect-scrollbar": "^0.2.1",
"vue-router": "^4.2.5"
},
"devDependencies": {
"@univerjs/vite-plugin": "^0.5.0",
"@vitejs/plugin-vue": "^4.5.2",
"mitt": "^3.0.1",
"sass": "^1.69.7",
"unplugin-auto-import": "^0.17.3",
"unplugin-vue-components": "^0.26.0",
"vite": "^5.0.8",
"vite-plugin-svg-icons": "^2.0.1"
}
}

1
plugin/assets/401.1738752173979.css

@ -0,0 +1 @@
.container[data-v-39be6a92]{width:800px;margin:auto;margin-top:10vh}

1
plugin/assets/401.1738752173979.js

@ -0,0 +1 @@
import"./index.1738752173979.js";import{_ as i,E as _,d as m,a as u,b as d}from"./_plugin-vue_export-helper.1738752173979.js";import{x as c,C as o,B as s,v as f,y as n,P as g,Q as x}from"./vue.1738752173979.js";const b="/plugin/imgs/401.gif",k={class:"container"},B={__name:"401",setup(E){const a=x();function l(){m(),a.push("/login")}return(y,t)=>{const r=u,e=d,p=_;return f(),c("div",k,[o(p,null,{default:s(()=>[o(e,{span:12},{default:s(()=>[t[1]||(t[1]=n("h1",{style:{"margin-top":"160px","margin-bottom":"30px"}},"您没有权限!",-1)),t[2]||(t[2]=n("p",{class:"mb-20"},"如有疑问,请联系系统管理员",-1)),t[3]||(t[3]=n("p",{class:"mb-8"},"可选择",-1)),o(r,{type:"primary",link:"",onClick:l},{default:s(()=>t[0]||(t[0]=[g("返回登录")])),_:1})]),_:1}),o(e,{span:12},{default:s(()=>t[4]||(t[4]=[n("img",{src:b},null,-1)])),_:1})]),_:1})])}}},N=i(B,[["__scopeId","data-v-39be6a92"]]);export{N as default};

1
plugin/assets/VerifySubmit.1738752173979.css

File diff suppressed because one or more lines are too long

289
plugin/assets/VerifySubmit.1738752173979.js

File diff suppressed because one or more lines are too long

1
plugin/assets/_plugin-vue_export-helper.1738752173979.css

File diff suppressed because one or more lines are too long

1
plugin/assets/_plugin-vue_export-helper.1738752173979.js

File diff suppressed because one or more lines are too long

0
plugin/assets/echarts.1738752173979.js

1
plugin/assets/index.1738752173979.css

File diff suppressed because one or more lines are too long

7
plugin/assets/index.1738752173979.js

File diff suppressed because one or more lines are too long

26
plugin/assets/vue.1738752173979.js

File diff suppressed because one or more lines are too long

BIN
plugin/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
plugin/imgs/401.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

19
plugin/index.html

@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/plugin/favicon.png" />
<meta name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>数字督察一体化平台</title>
<script type="module" crossorigin src="/plugin/assets/index.1738752173979.js"></script>
<link rel="modulepreload" crossorigin href="/plugin/assets/vue.1738752173979.js">
<link rel="stylesheet" crossorigin href="/plugin/assets/index.1738752173979.css">
</head>
<body>
<div id="app"></div>
</body>
</html>

BIN
public/favicon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
public/imgs/401.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

14
src/App.vue

@ -0,0 +1,14 @@
<template>
<el-config-provider :locale="elConfig.locale" :z-index="elConfig.zIndex" >
<router-view />
</el-config-provider>
</template>
<script setup>
import zhCn from 'element-plus/es/locale/lang/zh-cn'
const elConfig = {
zIndex: 3000,
locale: zhCn
}
</script>

113
src/api/request.ts

@ -0,0 +1,113 @@
import { getToken, deleteToken } from '@/utils/token'
import feedback from '@/utils/feedback'
export const BASE_PATH = '/api/v2'
type Options = {
url: string,
method?: 'GET' | 'POST' | 'PUT' | 'DELETE',
headers?: Record<string, string>,
query?: Record<string, any>,
params?: Record<string, any>,
body?: string | FormData | Record<string, any>,
showErrorMsg: bool
};
function get(options: Options) {
options.method = 'GET';
return ajax(options.url, options)
}
function post(options: Options) {
options.method = 'POST';
return ajax(options.url, options)
}
function put(options: Options) {
options.method = 'PUT';
return ajax(options.url, options)
}
function del(options: Options) {
options.method = 'DELETE';
return ajax(options.url, options)
}
let isRelogin = false;
function ajax(url: string, options: Options) {
const headers: Record<string, string> = {
"Authorization": getToken()
};
let body: string | FormData;
if (options?.params && Object.keys(options.params).length > 0) {
if (options.method === 'GET') {
options.query = options.params;
} else {
body = JSON.stringify(options.params);
}
}
if (options?.query) {
// 解决 query 的值为 undefined 的情况
if (options.query instanceof Object) {
const params = {}
for (let k of Object.keys(options.query)) {
if (options.query[k] === undefined || options.query[k] === null) {
continue;
}
params[k] = options.query[k]
}
url += (url.indexOf('?') > -1 ? '&' : '?') + new URLSearchParams(params).toString();
} else {
url += (url.indexOf('?') > -1 ? '&' : '?') + new URLSearchParams(options.query).toString();
}
}
if (options?.body) {
if (options.body instanceof FormData) {
body = options.body;
} else {
headers["Content-Type"] = "application/json"
if (options.body instanceof String) {
body = options.body;
}
if (options.body instanceof Array || (options.body instanceof Object && Object.keys(options.body).length > 0)) {
body = JSON.stringify(options.body);
}
}
}
return new Promise((resolve, reject) => {
fetch(`${BASE_PATH}${url}`, {
method: options.method,
body: body,
headers: { ...headers, ...options.headers }
}).then(response => {
if (response.status === 413) {
return;
}
return response.json();
}).then(res => {
if (res.code === 200 || res.httpStatusCode===0) {
resolve(res.data)
} else {
let message = res.message;
if (res.code === 401) {
deleteToken()
return
}
feedback.msgError(message)
reject(res)
}
})
})
}
const request = {
get,
post,
put,
del
}
export default request;

66
src/api/system/depart.ts

@ -0,0 +1,66 @@
import request from "@/api/request";
export function departTreeList(query) {
return request.get({
url: '/depart',
query
});
}
export function listDepart(query) {
return request.get({
url: '/depart/list',
query
});
}
export function departTree() {
return request.get({
url: '/depart/tree'
});
}
export function departTreeAll() {
return request.get({
url: '/depart/treeAll'
});
}
export function secondList() {
return request.get({
url: '/depart/second'
});
}
export function listByFirstHost() {
return request.get({
url: '/depart/firstHost'
});
}
export function listChildren(departId) {
return request.get({
url: `/depart/${departId}/children`
});
}
export function addDepart(body) {
return request.post({
url: '/depart',
body
});
}
export function updateDepart(body) {
return request.put({
url: '/depart',
body
});
}
export function delDepart(id) {
return request.del({
url: `/depart/${id}`
});
}

67
src/api/system/dict.ts

@ -0,0 +1,67 @@
import request from "@/api/request";
export function listDictTypes(query) {
return request.get({
url: '/dict',
query
});
}
export function addDictType(body) {
return request.post({
url: '/dict',
body
});
}
export function updateDictType(body) {
return request.put({
url: '/dict',
body
});
}
export function delDictType(id) {
return request.del({
url: '/dict/' + id
});
}
export function listDictDatas(query, dictType) {
return request.get({
url: `/dict/${dictType}/dictData`,
query
});
}
export function addDictData(body, dictType) {
return request.post({
url: `/dict/${dictType}/dictData`,
body
});
}
export function updateDictData(body, dictType) {
return request.put({
url: `/dict/${dictType}/dictData`,
body
});
}
export function delDictData(dictCode, dictType) {
return request.del({
url: `/dict/${dictType}/dictData/${dictCode}`
});
}
export function listDictDataAll(dictType) {
return request.get({
url: `/dict/data/${dictType}`
});
}
export function listDictProblemSourceTree() {
return request.get({
url: `/dict/problemSource`
});
}

27
src/api/system/dictContent.ts

@ -0,0 +1,27 @@
import request from "@/api/request";
export function listDictContentTree() {
return request.get({
url: `/dict/content/tree`
});
}
export function addDictContent(body) {
return request.post({
url: `/dict/content`,
body
});
}
export function updateDictContent(body) {
return request.put({
url: `/dict/content`,
body
});
}
export function delDictContent(id) {
return request.del({
url: `/dict/content/${id}`
});
}

54
src/api/system/police.ts

@ -0,0 +1,54 @@
import request from "@/api/request";
export function listPolice(query) {
return request.get({
url: '/police',
query
});
}
export function addPolice(body) {
return request.post({
url: '/police',
body
});
}
export function updatePolice(body) {
return request.put({
url: '/police',
body
});
}
export function delPolice(id, body) {
return request.del({
url: `/police/${id}`,
body
});
}
export function listPoliceAll(departId) {
return request.get({
url: `/police/${departId}/all`
});
}
export function listPoliceLeader(departId) {
return request.get({
url: `/police/${departId}/leader`
});
}
export function getPoliceAuths(idCode) {
return request.get({
url: `/police/auth/${idCode}`
});
}
export function updatePoliceAuths(idCode, body) {
return request.post({
url: `/police/auth/${idCode}`,
body
});
}

42
src/api/work/alarm.ts

@ -0,0 +1,42 @@
import request from "@/api/request";
export function alarmNotificationPages(query) {
return request.post({
url: `/alarm/notification/pages`,
body: query
});
}
export function alarmNotificationPageByTodo(query) {
return request.post({
url: `/alarm/notification/pages/todo`,
body: query
});
}
export function alarmNotificationReply(data) {
return request.post({
url: `/alarm/notification/reply`,
body: data
});
}
export function alarmNotificationCommit(data) {
return request.post({
url: `/alarm/notification/commit`,
body: data
});
}
export function alarmFiles(id) {
return request.get({
url: `/alarm/notification/files?alarmId=${id}`
});
}
export function alarmDetails(id) {
return request.get({
url: `/alarm/notification/details?alarmId=${id}`
});
}

27
src/api/work/dictContent.ts

@ -0,0 +1,27 @@
import request from "@/api/request";
export function listDictContentTree() {
return request.get({
url: `/dict/content/tree`
});
}
export function addDictContent(body) {
return request.post({
url: `/dict/content`,
body
});
}
export function updateDictContent(body) {
return request.put({
url: `/dict/content`,
body
});
}
export function delDictContent(id) {
return request.del({
url: `/dict/content/${id}`
});
}

21
src/api/work/fav.ts

@ -0,0 +1,21 @@
import request from "@/api/request";
export function listFav(query) {
return request.get({
url: '/negative/fav',
query
});
}
export function addFav(negativeId) {
return request.post({
url: '/negative/fav',
body: {negativeId}
});
}
export function delFav(id) {
return request.del({
url: `/negative/fav/${id}`
});
}

7
src/api/work/flowNode.ts

@ -0,0 +1,7 @@
import request from "@/api/request";
export function listFlowNode() {
return request.get({
url: '/negative/flowNode'
});
}

15
src/api/work/index.ts

@ -0,0 +1,15 @@
import request from "@/api/request";
export function listTodos(query) {
return request.get({
url: '/work/todo',
query
});
}
export function listDones(query) {
return request.get({
url: '/work/done',
query
});
}

97
src/api/work/negative.ts

@ -0,0 +1,97 @@
import request from "@/api/request";
export function listNegative(query) {
return request.get({
url: `/negative`,
query
});
}
export function getNegativeDetails(id, workId) {
const query = workId ? {workId} : null;
return request.get({
url: `/negative/${id}`,
query
});
}
export function getNegativeDetailsByOuter(id) {
return request.get({
url: `/negative/outer/${id}`
});
}
export function addNegative(body) {
return request.post({
url: `/negative`,
body
});
}
export function updateNegative(body) {
return request.put({
url: `/negative`,
body
});
}
export function negativeExecute(id, body) {
return request.post({
url: `/negative/${id}/execute`,
body
});
}
export function generateOriginId(problemSourcesCode, businessTypeCode) {
return request.post({
url: `/negative/${problemSourcesCode}/${businessTypeCode}/generateOriginId`
});
}
export function negativeExport(query) {
return request.post({
url: `/negative/export/excel`,
query
});
}
export function delNegative(id) {
return request.del({
url: `/negative/${id}`
});
}
export function getCompletionInfo(id) {
return request.get({
url: `/negative/completion/${id}`
});
}
export function calculateScore() {
return request.post({
url: `/negative/score/calculate`
});
}
export function transferTodo(id) {
return request.post({
url: `/negative/${id}/transferTodo`
});
}
// 抽检
export function spotCheckNegative(id, body) {
return request.post({
url: `/negative/${id}/spotCheck`,
body
});
}
// 提交办结
export function verifySubmitNegative(id, body) {
return request.post({
url: `/negative/${id}/verifySubmit`,
body
});
}

35
src/api/work/negativeTask.ts

@ -0,0 +1,35 @@
import request from "@/api/request";
export function listNegativeTask(query) {
return request.get({
url: `/negativeTask`,
query
});
}
export function listNegativeTaskImport(query) {
return request.get({
url: `/negativeTask/importList`,
query
});
}
export function importNegative(body) {
return request.post({
url: `/negativeTask/import`,
body
});
}
export function distributeNegative(body) {
return request.post({
url: `/negativeTask/distribute`,
body
});
}
export function listGroupByDepart(id) {
return request.get({
url: `/negativeTask/${id}/byDepart`
});
}

28
src/api/work/news.ts

@ -0,0 +1,28 @@
import request from "@/api/request";
export function listNews(query) {
return request.get({
url: '/news',
query
});
}
export function addNews(body) {
return request.post({
url: '/news',
body
});
}
export function updateNews(body) {
return request.put({
url: '/news',
body
});
}
export function delNews(id) {
return request.del({
url: '/news/' + id
});
}

22096
src/assets/data/changsha.json

File diff suppressed because it is too large Load Diff

494
src/assets/data/map.js

@ -0,0 +1,494 @@
const data = [
{ name: "海门", value: 9 },
{ name: "鄂尔多斯", value: 12 },
{ name: "招远", value: 12 },
{ name: "舟山", value: 12 },
{ name: "齐齐哈尔", value: 14 },
{ name: "盐城", value: 15 },
{ name: "赤峰", value: 16 },
{ name: "青岛", value: 18 },
{ name: "乳山", value: 18 },
{ name: "金昌", value: 19 },
{ name: "泉州", value: 21 },
{ name: "莱西", value: 21 },
{ name: "日照", value: 21 },
{ name: "胶南", value: 22 },
{ name: "南通", value: 23 },
{ name: "拉萨", value: 24 },
{ name: "云浮", value: 24 },
{ name: "梅州", value: 25 },
{ name: "文登", value: 25 },
{ name: "上海", value: 25 },
{ name: "攀枝花", value: 25 },
{ name: "威海", value: 25 },
{ name: "承德", value: 25 },
{ name: "厦门", value: 26 },
{ name: "汕尾", value: 26 },
{ name: "潮州", value: 26 },
{ name: "丹东", value: 27 },
{ name: "太仓", value: 27 },
{ name: "曲靖", value: 27 },
{ name: "烟台", value: 28 },
{ name: "福州", value: 29 },
{ name: "瓦房店", value: 30 },
{ name: "即墨", value: 30 },
{ name: "抚顺", value: 31 },
{ name: "玉溪", value: 31 },
{ name: "张家口", value: 31 },
{ name: "阳泉", value: 31 },
{ name: "莱州", value: 32 },
{ name: "湖州", value: 32 },
{ name: "汕头", value: 32 },
{ name: "昆山", value: 33 },
{ name: "宁波", value: 33 },
{ name: "湛江", value: 33 },
{ name: "揭阳", value: 34 },
{ name: "荣成", value: 34 },
{ name: "连云港", value: 35 },
{ name: "葫芦岛", value: 35 },
{ name: "常熟", value: 36 },
{ name: "东莞", value: 36 },
{ name: "河源", value: 36 },
{ name: "淮安", value: 36 },
{ name: "泰州", value: 36 },
{ name: "南宁", value: 37 },
{ name: "营口", value: 37 },
{ name: "惠州", value: 37 },
{ name: "江阴", value: 37 },
{ name: "蓬莱", value: 37 },
{ name: "韶关", value: 38 },
{ name: "嘉峪关", value: 38 },
{ name: "广州", value: 38 },
{ name: "延安", value: 38 },
{ name: "太原", value: 39 },
{ name: "清远", value: 39 },
{ name: "中山", value: 39 },
{ name: "昆明", value: 39 },
{ name: "寿光", value: 40 },
{ name: "盘锦", value: 40 },
{ name: "长治", value: 41 },
{ name: "深圳", value: 41 },
{ name: "珠海", value: 42 },
{ name: "宿迁", value: 43 },
{ name: "咸阳", value: 43 },
{ name: "铜川", value: 44 },
{ name: "平度", value: 44 },
{ name: "佛山", value: 44 },
{ name: "海口", value: 44 },
{ name: "江门", value: 45 },
{ name: "章丘", value: 45 },
{ name: "肇庆", value: 46 },
{ name: "大连", value: 47 },
{ name: "临汾", value: 47 },
{ name: "吴江", value: 47 },
{ name: "石嘴山", value: 49 },
{ name: "沈阳", value: 50 },
{ name: "苏州", value: 50 },
{ name: "茂名", value: 50 },
{ name: "嘉兴", value: 51 },
{ name: "长春", value: 51 },
{ name: "胶州", value: 52 },
{ name: "银川", value: 52 },
{ name: "张家港", value: 52 },
{ name: "三门峡", value: 53 },
{ name: "锦州", value: 54 },
{ name: "南昌", value: 54 },
{ name: "柳州", value: 54 },
{ name: "三亚", value: 54 },
{ name: "自贡", value: 56 },
{ name: "吉林", value: 56 },
{ name: "阳江", value: 57 },
{ name: "泸州", value: 57 },
{ name: "西宁", value: 57 },
{ name: "宜宾", value: 58 },
{ name: "呼和浩特", value: 58 },
{ name: "成都", value: 58 },
{ name: "大同", value: 58 },
{ name: "镇江", value: 59 },
{ name: "桂林", value: 59 },
{ name: "张家界", value: 59 },
{ name: "宜兴", value: 59 },
{ name: "北海", value: 60 },
{ name: "西安", value: 61 },
{ name: "金坛", value: 62 },
{ name: "东营", value: 62 },
{ name: "牡丹江", value: 63 },
{ name: "遵义", value: 63 },
{ name: "绍兴", value: 63 },
{ name: "扬州", value: 64 },
{ name: "常州", value: 64 },
{ name: "潍坊", value: 65 },
{ name: "重庆", value: 66 },
{ name: "台州", value: 67 },
{ name: "南京", value: 67 },
{ name: "滨州", value: 70 },
{ name: "贵阳", value: 71 },
{ name: "无锡", value: 71 },
{ name: "本溪", value: 71 },
{ name: "克拉玛依", value: 72 },
{ name: "渭南", value: 72 },
{ name: "马鞍山", value: 72 },
{ name: "宝鸡", value: 72 },
{ name: "焦作", value: 75 },
{ name: "句容", value: 75 },
{ name: "北京", value: 79 },
{ name: "徐州", value: 79 },
{ name: "衡水", value: 80 },
{ name: "包头", value: 80 },
{ name: "绵阳", value: 80 },
{ name: "乌鲁木齐", value: 84 },
{ name: "枣庄", value: 84 },
{ name: "杭州", value: 84 },
{ name: "淄博", value: 85 },
{ name: "鞍山", value: 86 },
{ name: "溧阳", value: 86 },
{ name: "库尔勒", value: 86 },
{ name: "安阳", value: 90 },
{ name: "开封", value: 90 },
{ name: "济南", value: 92 },
{ name: "德阳", value: 93 },
{ name: "温州", value: 95 },
{ name: "九江", value: 96 },
{ name: "邯郸", value: 98 },
{ name: "临安", value: 99 },
{ name: "兰州", value: 99 },
{ name: "沧州", value: 100 },
{ name: "临沂", value: 103 },
{ name: "南充", value: 104 },
{ name: "天津", value: 105 },
{ name: "富阳", value: 106 },
{ name: "泰安", value: 112 },
{ name: "诸暨", value: 112 },
{ name: "郑州", value: 113 },
{ name: "哈尔滨", value: 114 },
{ name: "聊城", value: 116 },
{ name: "芜湖", value: 117 },
{ name: "唐山", value: 119 },
{ name: "平顶山", value: 119 },
{ name: "邢台", value: 119 },
{ name: "德州", value: 120 },
{ name: "济宁", value: 120 },
{ name: "荆州", value: 127 },
{ name: "宜昌", value: 130 },
{ name: "义乌", value: 132 },
{ name: "丽水", value: 133 },
{ name: "洛阳", value: 134 },
{ name: "秦皇岛", value: 136 },
{ name: "株洲", value: 143 },
{ name: "石家庄", value: 147 },
{ name: "莱芜", value: 148 },
{ name: "常德", value: 152 },
{ name: "保定", value: 153 },
{ name: "湘潭", value: 154 },
{ name: "金华", value: 157 },
{ name: "岳阳", value: 169 },
{ name: "长沙", value: 175 },
{ name: "衢州", value: 177 },
{ name: "廊坊", value: 193 },
{ name: "菏泽", value: 194 },
{ name: "合肥", value: 229 },
{ name: "武汉", value: 273 },
{ name: "大庆", value: 279 }
];
const geoCoordMap = {
海门: [121.15, 31.89],
鄂尔多斯: [109.781327, 39.608266],
招远: [120.38, 37.35],
舟山: [122.207216, 29.985295],
齐齐哈尔: [123.97, 47.33],
盐城: [120.13, 33.38],
赤峰: [118.87, 42.28],
青岛: [120.33, 36.07],
乳山: [121.52, 36.89],
金昌: [102.188043, 38.520089],
泉州: [118.58, 24.93],
莱西: [120.53, 36.86],
日照: [119.46, 35.42],
胶南: [119.97, 35.88],
南通: [121.05, 32.08],
拉萨: [91.11, 29.97],
云浮: [112.02, 22.93],
梅州: [116.1, 24.55],
文登: [122.05, 37.2],
上海: [121.48, 31.22],
攀枝花: [101.718637, 26.582347],
威海: [122.1, 37.5],
承德: [117.93, 40.97],
厦门: [118.1, 24.46],
汕尾: [115.375279, 22.786211],
潮州: [116.63, 23.68],
丹东: [124.37, 40.13],
太仓: [121.1, 31.45],
曲靖: [103.79, 25.51],
烟台: [121.39, 37.52],
福州: [119.3, 26.08],
瓦房店: [121.979603, 39.627114],
即墨: [120.45, 36.38],
抚顺: [123.97, 41.97],
玉溪: [102.52, 24.35],
张家口: [114.87, 40.82],
阳泉: [113.57, 37.85],
莱州: [119.942327, 37.177017],
湖州: [120.1, 30.86],
汕头: [116.69, 23.39],
昆山: [120.95, 31.39],
宁波: [121.56, 29.86],
湛江: [110.359377, 21.270708],
揭阳: [116.35, 23.55],
荣成: [122.41, 37.16],
连云港: [119.16, 34.59],
葫芦岛: [120.836932, 40.711052],
常熟: [120.74, 31.64],
东莞: [113.75, 23.04],
河源: [114.68, 23.73],
淮安: [119.15, 33.5],
泰州: [119.9, 32.49],
南宁: [108.33, 22.84],
营口: [122.18, 40.65],
惠州: [114.4, 23.09],
江阴: [120.26, 31.91],
蓬莱: [120.75, 37.8],
韶关: [113.62, 24.84],
嘉峪关: [98.289152, 39.77313],
广州: [113.23, 23.16],
延安: [109.47, 36.6],
太原: [112.53, 37.87],
清远: [113.01, 23.7],
中山: [113.38, 22.52],
昆明: [102.73, 25.04],
寿光: [118.73, 36.86],
盘锦: [122.070714, 41.119997],
长治: [113.08, 36.18],
深圳: [114.07, 22.62],
珠海: [113.52, 22.3],
宿迁: [118.3, 33.96],
咸阳: [108.72, 34.36],
铜川: [109.11, 35.09],
平度: [119.97, 36.77],
佛山: [113.11, 23.05],
海口: [110.35, 20.02],
江门: [113.06, 22.61],
章丘: [117.53, 36.72],
肇庆: [112.44, 23.05],
大连: [121.62, 38.92],
临汾: [111.5, 36.08],
吴江: [120.63, 31.16],
石嘴山: [106.39, 39.04],
沈阳: [123.38, 41.8],
苏州: [120.62, 31.32],
茂名: [110.88, 21.68],
嘉兴: [120.76, 30.77],
长春: [125.35, 43.88],
胶州: [120.03336, 36.264622],
银川: [106.27, 38.47],
张家港: [120.555821, 31.875428],
三门峡: [111.19, 34.76],
锦州: [121.15, 41.13],
南昌: [115.89, 28.68],
柳州: [109.4, 24.33],
三亚: [109.511909, 18.252847],
自贡: [104.778442, 29.33903],
吉林: [126.57, 43.87],
阳江: [111.95, 21.85],
泸州: [105.39, 28.91],
西宁: [101.74, 36.56],
宜宾: [104.56, 29.77],
呼和浩特: [111.65, 40.82],
成都: [104.06, 30.67],
大同: [113.3, 40.12],
镇江: [119.44, 32.2],
桂林: [110.28, 25.29],
张家界: [110.479191, 29.117096],
宜兴: [119.82, 31.36],
北海: [109.12, 21.49],
西安: [108.95, 34.27],
金坛: [119.56, 31.74],
东营: [118.49, 37.46],
牡丹江: [129.58, 44.6],
遵义: [106.9, 27.7],
绍兴: [120.58, 30.01],
扬州: [119.42, 32.39],
常州: [119.95, 31.79],
潍坊: [119.1, 36.62],
重庆: [106.54, 29.59],
台州: [121.420757, 28.656386],
南京: [118.78, 32.04],
滨州: [118.03, 37.36],
贵阳: [106.71, 26.57],
无锡: [120.29, 31.59],
本溪: [123.73, 41.3],
克拉玛依: [84.77, 45.59],
渭南: [109.5, 34.52],
马鞍山: [118.48, 31.56],
宝鸡: [107.15, 34.38],
焦作: [113.21, 35.24],
句容: [119.16, 31.95],
北京: [116.46, 39.92],
徐州: [117.2, 34.26],
衡水: [115.72, 37.72],
包头: [110, 40.58],
绵阳: [104.73, 31.48],
乌鲁木齐: [87.68, 43.77],
枣庄: [117.57, 34.86],
杭州: [120.19, 30.26],
淄博: [118.05, 36.78],
鞍山: [122.85, 41.12],
溧阳: [119.48, 31.43],
库尔勒: [86.06, 41.68],
安阳: [114.35, 36.1],
开封: [114.35, 34.79],
济南: [117, 36.65],
德阳: [104.37, 31.13],
温州: [120.65, 28.01],
九江: [115.97, 29.71],
邯郸: [114.47, 36.6],
临安: [119.72, 30.23],
兰州: [103.73, 36.03],
沧州: [116.83, 38.33],
临沂: [118.35, 35.05],
南充: [106.110698, 30.837793],
天津: [117.2, 39.13],
富阳: [119.95, 30.07],
泰安: [117.13, 36.18],
诸暨: [120.23, 29.71],
郑州: [113.65, 34.76],
哈尔滨: [126.63, 45.75],
聊城: [115.97, 36.45],
芜湖: [118.38, 31.33],
唐山: [118.02, 39.63],
平顶山: [113.29, 33.75],
邢台: [114.48, 37.05],
德州: [116.29, 37.45],
济宁: [116.59, 35.38],
荆州: [112.239741, 30.335165],
宜昌: [111.3, 30.7],
义乌: [120.06, 29.32],
丽水: [119.92, 28.45],
洛阳: [112.44, 34.7],
秦皇岛: [119.57, 39.95],
株洲: [113.16, 27.83],
石家庄: [114.48, 38.03],
莱芜: [117.67, 36.19],
常德: [111.69, 29.05],
保定: [115.48, 38.85],
湘潭: [112.91, 27.87],
金华: [119.64, 29.12],
岳阳: [113.09, 29.37],
长沙: [113, 28.21],
衢州: [118.88, 28.97],
廊坊: [116.7, 39.53],
菏泽: [115.480656, 35.23375],
合肥: [117.27, 31.86],
武汉: [114.31, 30.52],
大庆: [125.03, 46.58]
};
function convertData(data) {
const res = [];
for (let i = 0; i < data.length; i++) {
const geoCoord = geoCoordMap[data[i].name];
if (geoCoord) {
res.push({
name: data[i].name,
value: geoCoord.concat(data[i].value)
});
}
}
return res;
}
export default function getData() {
return {
textStyle: {
fontFamily: 'Inter, "Helvetica Neue", Arial, sans-serif',
fontWeight: 300
},
backgroundColor: "#404a59",
title: {
text: "Air quality of major cities in China",
subtext: "data from PM25.in",
sublink: "http://www.pm25.in",
top: "5%",
left: "center",
textStyle: {
color: "#fff"
}
},
tooltip: {
trigger: "item"
},
legend: {
orient: "vertical",
right: "5%",
bottom: "5%",
data: ["PM2.5"],
textStyle: {
color: "#fff"
}
},
geo: {
map: "china",
emphasis: {
label: {
show: false
},
itemStyle: {
areaColor: "#2a333d"
}
},
itemStyle: {
areaColor: "#323c48",
borderColor: "#111"
},
top: "20%",
bottom: "7%"
},
series: [
{
name: "PM2.5",
type: "scatter",
coordinateSystem: "geo",
data: convertData(data),
symbolSize: val => val[2] / 10,
tooltip: {
formatter: function (val) {
return val.name + ": " + val.value[2];
}
},
itemStyle: {
color: "#ddb926"
}
},
{
name: "Top 5",
type: "effectScatter",
coordinateSystem: "geo",
data: convertData(data.sort((a, b) => b.value - a.value).slice(0, 6)),
symbolSize: val => val[2] / 10,
showEffectOn: "render",
rippleEffect: {
brushType: "stroke"
},
emphasis: {
scale: true
},
tooltip: {
formatter: function (val) {
return val.name + ": " + val.value[2];
}
},
label: {
formatter: "{b}",
position: "right",
show: true
},
itemStyle: {
color: "#f4e925",
shadowBlur: 10,
shadowColor: "#333"
},
zlevel: 1
}
]
};
}

20
src/assets/data/浏阳市.json

File diff suppressed because one or more lines are too long

20
src/assets/icons/completedApprove.svg

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_banjieshenpi</title>
<g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1.0首页" transform="translate(-1420, -182)">
<g id="编组-3" transform="translate(325, 169)">
<g id="编组-12" transform="translate(1095, 13)">
<circle id="椭圆形备份-3" fill="#E9EBFD" cx="48" cy="48" r="48"></circle>
<g id="tuandui" transform="translate(27.0128, 21.0307)" fill-rule="nonzero">
<path d="M34.605,49.89 L7.8,49.89 C3.492,49.89 0,46.398 0,42.09 L0,7.8 C0,3.492 3.492,0 7.8,0 L34.605,0 C38.913,0 42.405,3.492 42.405,7.8 L42.405,42.093 C42.405,46.398 38.913,49.89 34.605,49.89 Z" id="路径" fill="#5461C2"></path>
<path d="M30.81,14.16 L11.76,14.16 C10.434,14.16 9.36,13.086 9.36,11.76 C9.36,10.434 10.434,9.36 11.76,9.36 L30.81,9.36 C32.136,9.36 33.21,10.434 33.21,11.76 C33.21,13.086 32.136,14.16 30.81,14.16 Z M25.71,23.676 L11.76,23.676 C10.434,23.676 9.36,22.602 9.36,21.276 C9.36,19.95 10.434,18.876 11.76,18.876 L25.71,18.876 C27.036,18.876 28.11,19.95 28.11,21.276 C28.11,22.602 27.036,23.676 25.71,23.676 Z M20.883,33.189 L11.76,33.189 C10.434,33.189 9.36,32.115 9.36,30.789 C9.36,29.463 10.434,28.389 11.76,28.389 L20.883,28.389 C22.209,28.389 23.283,29.463 23.283,30.789 C23.283,32.115 22.209,33.189 20.883,33.189 L20.883,33.189 Z" id="形状" fill="#FFFFFF"></path>
<path d="M46.287,38.892 L42.687,38.892 C41.643,38.409 40.581,37.398 41.097,35.313 C43.164,33.759 44.433,31.2 44.172,28.359 C43.836,24.732 40.944,21.78 37.323,21.378 C32.637,20.859 28.668,24.516 28.668,29.097 C28.668,31.68 29.931,33.969 31.872,35.382 C31.971,36.609 31.65,38.085 29.874,38.895 L26.826,38.895 C25.107,38.895 23.715,40.29 23.715,42.006 L23.715,46.821 C23.715,48.54 25.11,49.932 26.826,49.932 L46.287,49.932 C48.006,49.932 49.401,48.537 49.401,46.818 L49.401,42.003 C49.401,40.284 48.006,38.892 46.287,38.892 Z" id="路径" fill="#6E7AD4"></path>
<path d="M42.405,42.09 L42.405,38.745 C41.463,38.214 40.626,37.209 41.097,35.31 C41.58,34.947 42.018,34.53 42.405,34.065 L42.405,24.123 C40.98,22.413 38.835,21.327 36.438,21.327 C32.148,21.327 28.668,24.804 28.668,29.097 C28.668,31.68 29.931,33.969 31.872,35.382 C31.971,36.609 31.65,38.085 29.874,38.895 L25.842,38.895 C24.666,38.895 23.712,39.849 23.712,41.025 L23.712,47.805 C23.712,48.846 24.456,49.71 25.443,49.896 L34.605,49.896 C38.913,49.89 42.405,46.398 42.405,42.09 L42.405,42.09 Z" id="路径" fill="#3F4CAA"></path>
<path d="M42.867,45.723 L30.246,45.723 C28.92,45.723 27.846,45.05175 27.846,44.223 C27.846,43.39425 28.92,42.723 30.246,42.723 L42.867,42.723 C44.193,42.723 45.267,43.39425 45.267,44.223 C45.267,45.05175 44.193,45.723 42.867,45.723 Z" id="路径" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

20
src/assets/icons/delay.svg

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_shenqingyanqi</title>
<g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1.0首页" transform="translate(-1092, -182)">
<g id="编组-3" transform="translate(325, 169)">
<g id="编组-11备份" transform="translate(767, 13)">
<circle id="椭圆形备份-3" fill="#E9EBFD" cx="48" cy="48" r="48"></circle>
<g id="daiban" transform="translate(24.0224, 23.0072)" fill-rule="nonzero">
<path d="M37.9970588,48.9588235 L7.80882353,48.9588235 C3.49705882,48.9588235 0,45.4617647 0,41.15 L0,7.80882353 C0,3.49705882 3.49705882,0 7.80882353,0 L37.9970588,0 C42.3088235,0 45.8058824,3.49705882 45.8058824,7.80882353 L45.8058824,41.15 C45.8058824,45.4617647 42.3088235,48.9588235 37.9970588,48.9588235 Z" id="路径" fill="#5461C2"></path>
<path d="M32.5147059,17.0676471 L8.78529412,17.0676471 C7.48529412,17.0676471 6.43235294,16.0147059 6.43235294,14.7147059 C6.43235294,13.4147059 7.48529412,12.3617647 8.78529412,12.3617647 L32.5147059,12.3617647 C33.8147059,12.3617647 34.8676471,13.4147059 34.8676471,14.7147059 C34.8676471,16.0147059 33.8147059,17.0676471 32.5147059,17.0676471 Z M23.5029412,30.4352941 L8.78529412,30.4352941 C7.48529412,30.4352941 6.43235294,29.3823529 6.43235294,28.0823529 C6.43235294,26.7823529 7.48529412,25.7294118 8.78529412,25.7294118 L23.5029412,25.7294118 C24.8029412,25.7294118 25.8558824,26.7823529 25.8558824,28.0823529 C25.8558824,29.3823529 24.8029412,30.4352941 23.5029412,30.4352941 Z" id="形状" fill="#FFFFFF"></path>
<path d="M25.3117647,36.9117647 C25.3117647,43.9420247 31.0109165,49.6411765 38.0411765,49.6411765 C45.0714365,49.6411765 50.7705882,43.9420247 50.7705882,36.9117647 C50.7705882,29.8815047 45.0714365,24.1823529 38.0411765,24.1823529 C31.0109165,24.1823529 25.3117647,29.8815047 25.3117647,36.9117647 Z" id="路径" fill="#6E7AD4"></path>
<path d="M38.0411765,24.1852752 C31.0117647,24.1852752 25.3117647,29.8852941 25.3117647,36.9147059 C25.3117647,42.5058824 28.9176471,47.25 33.9294118,48.9617647 L37.9941176,48.9617647 C42.3058824,48.9617647 45.8029412,45.4647059 45.8029412,41.1529412 L45.8029412,26.8352941 C43.5825974,25.1129689 40.8512133,24.1804274 38.0411765,24.1852752 L38.0411765,24.1852752 Z" id="路径" fill="#3F4CAA"></path>
<path d="M35.0117647,44.5147115 C34.4559797,44.5151864 33.9181042,44.3181739 33.4941176,43.9588235 C33.017209,43.5565111 32.7197931,42.9811151 32.6673844,42.3593833 C32.6149758,41.7376514 32.8118738,41.1205874 33.2147059,40.6441176 L36.6588235,36.5705882 L36.6588235,30.9558824 C36.6588235,29.6558824 37.7117647,28.6029412 39.0117647,28.6029412 C40.3117647,28.6029412 41.3647059,29.6558824 41.3647059,30.9558824 L41.3647059,37.4323529 C41.3647059,37.9882353 41.1676471,38.5264706 40.8088235,38.95 L36.8088235,43.6794118 C36.3631153,44.210302 35.7049443,44.5162276 35.0117647,44.5147115 L35.0117647,44.5147115 Z" id="路径" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

1
src/assets/icons/doc.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709019288260" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3537" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M332.799002 686.081014m-332.799002 0a332.799002 332.799002 0 1 0 665.598003 0 332.799002 332.799002 0 1 0-665.598003 0Z" fill="#CCE4F2" p-id="3538"></path><path d="M883.19735 1024h-639.99808A141.055577 141.055577 0 0 1 102.399693 883.200422v-742.397772A141.055577 141.055577 0 0 1 243.19927 0.003072h516.350451a89.087733 89.087733 0 0 1 63.231811 25.599923l189.695431 189.695431A38.399885 38.399885 0 0 1 1023.996928 243.202342v639.99808a141.055577 141.055577 0 0 1-140.799578 140.799578zM243.19927 76.802842A63.999808 63.999808 0 0 0 179.199462 140.80265v742.397772A63.999808 63.999808 0 0 0 243.19927 947.20023h639.99808a63.999808 63.999808 0 0 0 63.999808-63.999808V259.074295l-179.199462-179.199463a12.799962 12.799962 0 0 0-8.447975-3.07199z" fill="#434260" p-id="3539"></path><path d="M265.983202 399.105875h58.623824c69.375792 0 109.055673 38.399885 109.055673 112.127663s-39.679881 113.919658-107.263678 113.919659h-60.415819z m56.319831 196.863409c48.383855 0 74.495777-28.671914 74.495777-84.735746s-25.599923-83.19975-74.495777-83.19975h-20.479938v167.935496zM468.478595 512.001536c0-72.703782 40.191879-116.479651 98.303705-116.479651S665.598003 438.529756 665.598003 512.001536s-40.447879 118.015646-98.559704 118.015646-98.559704-46.079862-98.559704-118.015646z m160.255519 0c0-53.24784-25.599923-85.247744-61.951814-85.247744S504.830486 458.241697 504.830486 512.001536s24.319927 86.78374 61.695814 86.78374S628.734114 563.201382 628.734114 512.001536zM699.9019 512.001536c0-73.727779 44.799866-118.015646 102.399693-118.015646a87.039739 87.039739 0 0 1 64.255807 28.671914l-19.455941 22.783932a60.15982 60.15982 0 0 0-44.287867-20.22394c-38.911883 0-66.047802 32.511902-66.047802 85.759743s25.599923 86.52774 65.023805 86.52774a65.791803 65.791803 0 0 0 51.199846-24.063927l18.943943 22.527932a89.087733 89.087733 0 0 1-70.399789 32.511903c-59.135823 0.767998-101.631695-41.727875-101.631695-116.479651z" fill="#434260" p-id="3540"></path></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

13
src/assets/icons/ic_01.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.9 KiB

13
src/assets/icons/ic_02.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_02</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-214, -46)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份" transform="translate(214, 46)">
<g id="jingzhong-jingwuting" transform="translate(18, 16)">
<path d="M17.4421875,0.0124515114 L28.2890625,0.0124515114 C29.25,-0.0906734886 29.8546875,0.453076511 29.8546875,1.76557651 L29.8546875,14.070264 L22.6828125,18.6218265 L15.5296875,13.714014 L15.5296875,1.40932651 C15.5296875,0.453076511 16.4859375,-0.0906734886 17.4421875,0.0124515114 Z M22.753125,3.79995151 L21.3703125,6.52807651 L18.3421875,7.00620151 L20.503125,9.16713901 L20.025,12.176514 L22.7578125,10.7937015 L25.4765625,12.176514 L24.9984375,9.16713901 L27.159375,7.00620151 L24.1359375,6.52807651 L22.753125,3.79995151 L22.753125,3.79995151 Z M1.7859375,8.18276401 L13.1109375,8.18276401 L13.1109375,15.073389 L22.7765625,21.7718265 L32.4421875,15.0780765 L32.4421875,8.18745151 L43.884375,8.18745151 C44.840625,8.18745151 45.553125,8.87182651 45.553125,9.82807651 L45.553125,12.064014 C45.553125,13.020264 44.840625,13.873389 43.884375,13.873389 L42.6140625,13.873389 L42.6375,42.289014 L43.884375,42.3124515 C44.840625,42.3124515 45.553125,42.9968265 45.553125,43.9530765 L45.553125,46.189014 C45.553125,47.145264 44.840625,47.998389 43.884375,47.998389 L1.7859375,47.998389 C0.8296875,47.998389 0,47.145264 0,46.189014 L0,43.9530765 C0,42.9968265 0.8296875,42.3124515 1.7859375,42.3124515 L2.9390625,42.3124515 L2.9390625,13.873389 L1.7859375,13.873389 C0.8296875,13.873389 0,13.020264 0,12.064014 L0,9.82807651 C0,8.86713901 0.8296875,8.18276401 1.7859375,8.18276401 Z M14.146875,28.179639 L14.146875,30.935889 L15.6984375,30.935889 L15.6984375,42.3124515 L29.8546875,42.3124515 L29.8546875,30.935889 L31.228125,30.935889 L31.228125,28.1843265 L14.146875,28.1843265 L14.146875,28.179639 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

13
src/assets/icons/ic_03.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_03</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-331, -46)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-2" transform="translate(331, 46)">
<g id="jingzhong-zhian" transform="translate(19, 16)">
<path d="M29.3426886,25.377207 C31.461362,25.9818727 33.6409707,27.2896379 38.0376866,30.0832868 C38.5157943,30.3739013 39.007964,30.6785778 39.5376323,31.0020036 C39.5282577,31.0066909 39.5141957,31.0113783 39.5048211,31.0160656 C39.7391876,31.1660602 39.9688668,31.3160547 40.2172953,31.4707366 C42.9593836,33.1722376 44.5765126,41.4219392 44.5765126,43.7046691 C44.5765126,47.3068826 40.5224778,47.9831051 34.3925572,47.9986796 L33.7511035,47.998027 C30.7238531,47.9848507 27.2287026,47.8359118 23.4882129,47.8060833 C23.2397843,47.8013959 22.9866685,47.8013959 22.7335527,47.8013959 L21.8429599,47.8013959 C21.5898441,47.801396 21.3414156,47.8060833 21.0882997,47.8060833 C9.33247491,47.8998299 0,49.1747838 0,43.7046691 C0.00468735938,41.4219392 1.62181636,33.1722376 4.36390467,31.4707366 C4.60764586,31.3113674 4.84201238,31.1660602 5.07637889,31.0160656 C5.06700422,31.0113783 5.05294223,31.0066909 5.04356756,31.0020036 C5.57323594,30.6785778 6.06540563,30.3739013 6.54351333,30.0832868 C10.9402293,27.2943252 13.1198379,25.98656 15.2385113,25.377207 C15.177576,25.8225035 15.1400774,26.2724872 15.1400774,26.7318456 C15.1400774,30.6879525 17.34781,34.0206444 20.3617635,35.0518571 L21.1398603,30.866071 L23.3991536,30.866071 L24.1772505,35.0659191 C27.2146406,34.0487684 29.4411225,30.7067018 29.4411225,26.7318456 C29.4411225,26.2677998 29.3989366,25.8178161 29.3426886,25.377207 Z M23.8819486,27.7911822 L23.3944663,30.1864081 L21.135173,30.1864081 L20.652378,27.7911822 L23.8819486,27.7911822 Z M22.1335744,9.58090345 C28.4333465,9.58090345 31.8644724,10.5558682 32.6566312,10.808984 C32.6050706,10.8886687 32.5206987,10.9730406 32.4457014,11.0480379 L32.1175882,11.376151 L32.55351,11.376151 C32.5628846,11.4652102 32.5863213,11.5636442 32.6238199,11.6808275 C32.6660059,11.8355094 32.7175665,12.0042533 32.7175665,12.1683098 L32.7175665,12.2479945 L32.7738145,12.3042424 C32.9331838,12.4589243 33.0456797,12.5714203 33.0456797,12.8198488 L33.0456797,13.1245252 L33.176925,13.1667112 C34.6346847,13.6495063 35.4784042,15.107266 35.333097,16.8837643 L35.333097,16.8978263 C35.3330969,17.6712358 34.8971752,18.5243299 34.1050163,19.2930521 C33.3831675,19.9961517 32.426952,20.553944 31.5551086,20.7976852 L31.461362,20.8258092 L31.4285507,20.9148685 C30.5520199,23.277283 28.5177185,24.7491048 26.9662121,25.5600129 C25.1100292,26.5349777 23.1600997,26.9849614 22.142949,26.9849614 C21.1164237,26.9849614 19.1758689,26.539665 17.3149987,25.5600129 C15.7681797,24.7444174 13.7338783,23.277283 12.8573475,20.9101811 L12.8245361,20.8164345 L12.7307895,20.7929979 C11.8167601,20.539882 10.8839813,20.014901 10.1808817,19.3446127 C9.61840209,18.8149444 8.95280119,17.957163 8.95280119,16.8931389 C8.95280119,15.191638 9.86214328,13.7901262 11.2683424,13.3213931 L11.3995876,13.2792072 L11.3995876,12.9745307 C11.3995876,12.7261022 11.5073962,12.6136063 11.6667655,12.4589243 L11.7230135,12.4026764 L11.7236645,12.1691345 C11.7269196,11.9141524 11.7464501,11.6667655 11.8636334,11.432399 L11.8823827,11.390213 L11.8823827,11.0995985 L11.8261347,11.0480379 C11.7558247,10.9730406 11.6667655,10.8886687 11.6152049,10.808984 C12.4073637,10.5558682 15.8384896,9.58090345 22.1335744,9.58090345 Z M22.2929436,11.0246012 C18.8524431,11.0246012 13.8651235,11.7370755 13.8651235,11.7370755 L13.8651235,12.9557813 C13.8651235,12.9557814 17.9618503,15.0885167 22.2929436,15.0885167 C26.6287243,15.0885167 30.7207638,12.9557813 30.7207638,12.9557813 L30.7207638,11.7370755 C30.7207638,11.7370755 25.7334442,11.0246012 22.2929436,11.0246012 Z M22.269507,0 C29.9051683,0 36.0924445,2.82177295 36.0971318,6.29977214 C36.0971318,7.88408981 34.8081159,9.33247495 32.6847552,10.4386849 C30.2942167,9.05592244 26.5209157,8.16064233 22.2741943,8.16064233 C18.0274729,8.16064233 14.2541719,9.05592244 11.8636334,10.4386849 C9.74027269,9.33247495 8.45125683,7.88408981 8.45125683,6.29977214 C8.45125683,2.82177295 14.638533,0 22.269507,0 Z M22.2746754,1.44373949 L22.227321,1.44369778 L22.1879947,1.46302337 C22.1133928,1.49643023 21.8367101,1.59603601 20.694564,2.03430141 L20.610192,2.07648741 L20.59613,2.17492134 C20.539882,2.72333902 20.1039603,2.76552497 20.0477123,2.76552497 L19.9211544,2.76552497 L19.9070924,2.89208287 C19.8930304,2.92020684 19.5696046,6.0325943 22.171073,7.06380698 L22.2601323,7.09193095 C22.269507,7.09661827 22.2788816,7.09661827 22.2882563,7.09193095 L22.3679409,7.06380698 C24.9694093,6.0325943 24.6459835,2.92020684 24.6459835,2.89208287 L24.6319215,2.76552497 L24.5053636,2.76552497 C24.4913016,2.76552497 24.0272559,2.737401 23.9569459,2.16085936 L23.9428839,2.06242538 L23.858512,2.02023942 C22.3116929,1.44369778 22.3116929,1.44369778 22.269507,1.44369778 Z M22.2929436,2.695215 L22.7007414,3.5248725 L23.6194582,3.66080508 L22.9538572,4.30765669 L23.1132264,5.22168614 L22.2929436,4.7904517 L21.4726608,5.22168614 L21.6273427,4.30765669 L20.9617418,3.66080508 L21.8804586,3.5248725 L22.2929436,2.695215 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

13
src/assets/icons/ic_04.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.1 KiB

14
src/assets/icons/ic_05.svg

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_05</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-566, -46)">
<rect x="0" y="0" width="1150" height="757"></rect>
<g id="编组-2备份-4" transform="translate(566, 46)" fill="#FFFFFF" fill-rule="nonzero">
<g id="jingzhong-jiemianxunfang1" transform="translate(17, 17)">
<path d="M23.2734375,20.6390625 C25.3546875,20.6390625 27.0515625,21.8015625 27.5015625,24.20625 L28.9078125,28.434375 C29.034375,28.36875 29.175,28.33125 29.315625,28.3265625 L32.4328125,28.3265625 C32.9109375,28.3265625 33.3,28.715625 33.3046875,29.19375 L33.3046875,29.9484375 C33.3,30.43125 32.9109375,30.815625 32.4328125,30.815625 L31.2796875,31.0125 C31.65,31.7390625 31.865625,32.5734375 31.865625,33.54375 L32.3015625,38.53125 C32.3015625,38.6765625 32.2921875,38.821875 32.2734375,38.971875 C32.2921875,39.065625 32.3015625,39.159375 32.3015625,39.253125 L32.3015625,45.253125 C32.296875,46.1109375 31.603125,46.8 30.75,46.8 L28.3875,46.8 C27.5296875,46.8 26.8359375,46.10625 26.8359375,45.253125 L26.8359375,43.3265625 L6.4921875,43.3265625 L6.4921875,45.253125 C6.4875,46.10625 5.79375,46.7953125 4.940625,46.7953125 L2.578125,46.7953125 C1.7203125,46.7953125 1.0265625,46.1015625 1.0265625,45.2484375 L1.0265625,39.2484375 C1.0265625,39.1546875 1.0359375,39.0609375 1.0546875,38.9671875 C1.0359375,38.8171875 1.0265625,38.671875 1.0265625,38.5265625 L1.4625,33.5390625 C1.453125,32.6625 1.65,31.7953125 2.0484375,31.0125 L0.8671875,30.8109375 C0.3890625,30.8109375 0,30.421875 0,29.94375 L0,29.19375 C0,28.7109375 0.3890625,28.3265625 0.8671875,28.321875 L3.9890625,28.321875 C4.1390625,28.321875 4.2890625,28.3640625 4.4203125,28.44375 L5.83125,24.2015625 C6.215625,22.1953125 7.66875,20.6390625 10.059375,20.6390625 Z M47.325,10.490625 L48,10.4953125 L47.9859375,44.5640625 C47.9859375,45.796875 46.9875,46.8 45.75,46.8 L43.9875,46.8 C42.7546875,46.8 41.7515625,45.8015625 41.7515625,44.5640625 L41.7515625,28.9453125 L40.2328125,28.9453125 L40.2328125,44.5640625 C40.2328125,45.796875 39.234375,46.8 37.996875,46.8 L36.24375,46.8 C35.0109375,46.8 34.0078125,45.8015625 34.0078125,44.5640625 L34.0265625,24.3328125 L46.7671875,24.3328125 L46.7671875,21.703125 L36.9234375,21.703125 L45.178125,10.490625 L47.325,10.490625 Z M7.659375,35.79375 C6.365625,35.775 5.3015625,36.8109375 5.2828125,38.1046875 C5.2640625,39.3984375 6.3,40.4625 7.59375,40.48125 C8.8359375,40.4953125 9.8765625,39.54375 9.965625,38.30625 C10.059375,37.0171875 9.0890625,35.8921875 7.7953125,35.7984375 C7.7484375,35.7984375 7.70625,35.79375 7.659375,35.79375 Z M25.7296875,35.8031093 C24.4359375,35.7984375 23.38125,36.8484375 23.38125,38.1421875 C23.38125,39.4359375 24.4359375,40.4812656 25.7296875,40.4812656 C27.0234375,40.4859375 28.0734375,39.4359375 28.078125,38.1421875 C28.0734375,36.84375 27.0234375,35.7984375 25.7296875,35.8031093 Z M20.00625,36.103125 L13.4203125,36.103125 C13.0359375,36.103125 12.721875,36.4125 12.721875,36.796875 L12.721875,38.75625 C12.721875,39.140625 13.0359375,39.45 13.4203125,39.45 L20.00625,39.45 C20.390625,39.45 20.7046875,39.140625 20.7046875,38.75625 L20.7046875,36.796875 C20.7046875,36.4125 20.390625,36.103125 20.00625,36.103125 Z M24.7546875,23.5546875 L8.5875,23.5546875 C8.25,23.98125 8.0203125,24.0796875 7.9171875,24.6328125 L7.903125,24.6984375 L6.871875,27.440625 L6.4828125,28.9734375 C6.5671875,30.09375 7.9171875,30.975 9.0375,30.975 L24.28125,30.975 C25.4015625,30.975 26.746875,30.09375 26.8359375,28.9734375 L26.4515625,27.4453125 L25.4015625,24.6328125 C25.3125,24.1078125 25.096875,23.9953125 24.7546875,23.5546875 Z M31.9265625,6.6890625 C32.5546875,6.0609375 33.5765625,6.0609375 34.2046875,6.6890625 C34.8328125,7.3171875 34.8328125,8.3390625 34.2046875,8.9671875 L29.728125,13.44375 L34.0265625,16.8375 L34.0265625,14.184375 L34.0078125,14.2078125 L34.0078125,10.490625 L42.6375,10.490625 L34.209375,21.084375 L34.059375,21.290625 L34.05,21.28125 L34.0265625,21.309375 L34.0265625,21.2671875 L26.11875,14.7421875 C25.715625,14.4140625 25.5796875,13.865625 25.715625,13.33125 C25.7625,13.003125 25.9171875,12.6890625 26.165625,12.440625 Z M43.8140625,4.0640625 C43.8140625,4.0640625 44.2734375,9 40.35,9 C37.2140625,9 36.271875,6.5859375 35.990625,5.1328125 L35.246,5.099 L35.8640625,4.0640625 L35.8734375,4.0734375 Z M44.0625,0 L44.0625,2.146875 L44.0390625,2.146875 L44.0390625,3.2203125 L35.0765625,3.2203125 L35.0765625,2.146875 L33.9703125,2.146875 L33.9703125,0 L44.0625,0 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

14
src/assets/icons/ic_06.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.2 KiB

14
src/assets/icons/ic_07.svg

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_07</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-801, -46)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-6" transform="translate(801, 46)">
<g id="jingzhong-tielu" transform="translate(22, 16)">
<polygon id="路径" points="9.80365751 42.8390625 27.4755325 42.8390625 27.4755325 45.9046875 9.80365751 45.9046875"></polygon>
<path d="M33.01147,40.3828125 L33.85522,40.3828125 C35.6786575,40.3828125 37.108345,38.915625 36.9442825,37.2140625 L34.3474075,10.5234375 C34.0567825,7.51875 31.3661575,5.2171875 28.145845,5.2171875 L23.702095,5.2171875 C23.6974075,2.3390625 21.358345,0 18.4755325,0 C15.59272,0 13.2536575,2.3390625 13.2536575,5.221875 L8.64584501,5.221875 C5.41147001,5.221875 2.72084501,7.5375 2.44428251,10.55625 L0.011470012,37.228125 C-0.143217488,38.925 1.28647001,40.3828125 3.10522001,40.3828125 L3.94428251,40.3828125 L0.672407512,45.515625 C0.302095012,46.096875 0.470845012,46.875 1.05678251,47.2453125 L1.92865751,47.803125 C2.50990751,48.1734375 3.28803251,48.0046875 3.65834501,47.41875 L8.13959501,40.3828125 L28.8161575,40.3828125 L33.2974075,47.4140625 C33.66772,48 34.445845,48.1734375 35.0317825,47.7984375 L35.89897,47.2453125 C36.4849075,46.875 36.658345,46.096875 36.283345,45.5109375 L33.01147,40.3828125 Z M7.17397001,11.00625 L29.8474075,11.00625 L29.8474075,21.6234375 L7.17397001,21.6234375 L7.17397001,11.00625 Z M9.70990751,29.1140625 C8.30834501,29.1140625 7.17397001,27.9796875 7.17397001,26.578125 C7.17397001,25.1765625 8.30834501,24.0421875 9.70990751,24.0421875 C11.11147,24.0421875 12.245845,25.1765625 12.245845,26.578125 C12.245845,27.9796875 11.11147,29.1140625 9.70990751,29.1140625 Z M27.4755325,29.1140625 C26.07397,29.1140625 24.939595,27.9796875 24.939595,26.578125 C24.939595,25.1765625 26.07397,24.0421875 27.4755325,24.0421875 C28.877095,24.0421875 30.01147,25.1765625 30.01147,26.578125 C30.01147,27.9796875 28.877095,29.1140625 27.4755325,29.1140625 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

13
src/assets/icons/ic_08.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="80px" height="80px" viewBox="0 0 80 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_08</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-141, -288)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2" transform="translate(141, 288)">
<g id="xingbie" transform="translate(16, 17)">
<path d="M37.3089434,15.959007 C41.2199111,15.959007 44.6131679,18.7037556 45.3841069,22.4791852 L48.9293006,36.3373647 C49.1037466,37.0263526 48.9518098,37.7377467 48.512881,38.303501 C48.0852069,38.8692553 47.4155591,39.1885423 46.7065204,39.2053469 L46.6224413,39.2058814 C46.2591348,39.2081741 44.7885926,39.2172806 43.5946281,39.2221515 C43.1500721,40.544112 42.4860517,42.5382559 41.8895588,44.4259707 C41.5913123,45.3670274 40.7134548,46 39.7286788,46 L34.8948353,46 C33.8988047,46 33.0153199,45.3614258 32.7170734,44.4147677 C32.1205805,42.5326544 31.4621874,40.5889243 31.0176314,39.2725652 C29.6445722,39.2613622 27.9057391,39.227753 27.9057391,39.227753 C27.1967004,39.2109484 26.53268,38.8804583 26.0993785,38.314704 C25.6660771,37.7489497 25.5141402,37.0263526 25.6885862,36.3373647 L29.2619164,22.3503501 C30.0047189,18.7037556 33.3979757,15.959007 37.3089434,15.959007 Z M8.41280096,14.2001273 C16.2234817,11.7298536 24.1241992,17.6562699 24.1185749,25.268746 L24.1185749,33.5141948 C24.1185749,34.4328453 23.3645148,35.1890516 22.4360117,35.1890516 L19.2959829,35.1890516 L19.2959829,45.3670274 C19.2959829,45.7143221 19.0146184,45.9943985 18.6657263,45.9943985 L5.45284557,45.9943985 C5.10395349,45.9943985 4.82258891,45.7143221 4.82258891,45.3670274 L4.82258891,35.1890516 L0.754057076,35.1890516 C0.337637497,35.1890516 0,34.8529599 0,34.4384468 L0,26.0137492 C0,20.6978994 3.32572934,15.8077658 8.41280096,14.2001273 Z M37.7534994,2 C41.6194488,2 44.7651048,5.13125398 44.7651048,8.9795035 C44.7651048,12.827753 41.6194488,15.959007 37.7534994,15.959007 C33.8875501,15.959007 30.7418941,12.827753 30.7418941,8.9795035 C30.7418941,5.13125398 33.8875501,2 37.7534994,2 Z M11.5,0 C15.0838684,0 18,2.91613162 18,6.5 C18,10.0890851 15.0838684,13 11.5,13 C7.91613162,13 5,10.0838684 5,6.5 C5,2.91613162 7.91613162,0 11.5,0 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

13
src/assets/icons/ic_09.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_09</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-590, -288)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-2" transform="translate(590, 288)">
<g id="teshurenyuan" transform="translate(17, 17)">
<path d="M20.6113138,23.8214286 C27.4282323,23.8214286 32.9824561,18.4798955 32.9824561,11.9093842 C32.9824561,5.33887294 27.4282323,0 20.6113138,0 C13.7971166,0 8.24561404,5.34685331 8.24561404,11.9093842 C8.25105668,18.4798955 13.7943952,23.8214286 20.6140351,23.8214286 L20.6113138,23.8214286 Z M20.8269295,34.677577 C20.8242016,31.1823551 22.3060128,27.8439471 24.9164111,25.4642857 L15.7803937,25.4642857 C7.0789009,25.4696799 0,32.3068267 0,40.705594 L0,41.6091223 C0,46 6.96614452,46 15.7803937,46 L25.1474242,46 C26.1292298,46 27.0945345,46 28.0350877,45.9946058 C23.6250344,43.8830264 20.8283646,39.4904935 20.8296797,34.677577 L20.8269295,34.677577 Z M35.4561405,23 C29.0806428,23 23.9122807,28.1487254 23.9122807,34.5 C23.9122807,40.8512746 29.0806428,46 35.4561405,46 C41.8316381,46 47,40.8512745 47,34.5 C47,28.1487255 41.8316381,23 35.4561405,23 Z M32.9824561,27.0844515 C32.9824561,26.1858721 33.9039361,25.4642857 35.0438596,25.4642857 C36.1837831,25.4642857 37.1052632,26.1885951 37.1052632,27.0844515 L37.1052632,36.1655485 C37.1052632,37.0614049 36.1837831,37.7857143 35.0463705,37.7857143 C33.9039361,37.7857143 32.9824561,37.0614049 32.9824561,36.1655485 L32.9824561,27.0844515 L32.9824561,27.0844515 Z M35.4561752,43.5357143 C34.4554324,43.5357143 33.5532802,42.935027 33.1705653,42.0138696 C32.7878504,41.0927122 32.9999806,40.0325837 33.707999,39.3280253 C34.4160174,38.6234668 35.4804201,38.4133006 36.4046719,38.7955675 C37.3289238,39.1778343 37.9309156,40.0772146 37.9298246,41.0741547 C37.9298246,42.4327204 36.8226226,43.5357143 35.4561752,43.5357143 L35.4561752,43.5357143 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

13
src/assets/icons/ic_10.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_10</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-815, -288)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-3" transform="translate(815, 288)">
<g id="chengchangzhi" transform="translate(17, 17)">
<path d="M15.5340727,33.7062001 C14.9008319,31.310516 14.5724602,28.8448779 14.5566988,26.367412 C14.541781,23.2894916 15.0613323,20.2346556 16.0243028,17.2593326 L16.0243028,17.2552287 C16.1049797,17.0113584 16.0344756,16.7429774 15.8442603,16.5698784 C15.3379447,16.1133556 14.8169193,15.6733238 14.2820053,15.2504765 C12.41625,13.7776916 10.5011115,12.6244975 8.59060277,11.8226992 C6.15642739,10.8018557 3.7227664,10.3509403 1.35649275,10.4817519 C1.01701162,10.5005902 0.700348843,10.6582142 0.481191765,10.9174472 C0.262034686,11.1766802 0.15978602,11.5145714 0.198561905,11.8514265 C0.285496757,12.6075689 0.218623804,13.8110358 0.141462683,15.2043078 C0.00925999302,17.6327869 -0.158951194,20.6553047 0.307616218,23.7557965 C0.873464257,27.523171 2.22944192,30.4810525 4.45476797,32.7987265 C6.18780619,34.6034138 8.45685687,35.9848871 11.1991623,36.9051853 C12.940431,37.4894772 14.9054669,37.8973016 17.0726649,38.1267296 C17.0744354,38.1270221 17.0762857,38.1263651 17.0773947,38.1249275 C17.0783548,38.1234898 17.0786657,38.1215378 17.077809,38.1199379 C16.4452631,36.6923994 15.9290159,35.2163834 15.5340727,33.7062001 L15.5340727,33.7062001 Z M45.2292636,3.79856086 C45.0996329,2.74180823 44.9874921,1.82920482 44.9314218,1.13102986 C44.8869832,0.588470011 44.4905221,0.139418121 43.9564681,0.0267480499 C43.4224142,-0.0859220211 42.8775575,0.164538819 42.6165888,0.642666511 C42.5954982,0.680627535 42.3671013,1.03407537 40.9385922,1.79021782 C39.8650241,2.3586071 38.4612066,2.98188596 36.8356795,3.7036583 C33.6201194,5.13130038 29.6185448,6.90726042 26.1478388,9.20595395 C21.9384437,11.9909589 19.3694936,14.963204 18.2923247,18.2914619 C18.2475712,18.4304813 18.2043611,18.5700137 18.1621796,18.7095461 C17.4173179,21.2159992 17.0155658,23.7788809 17.0304835,26.3556132 C17.0438615,28.626166 17.3437163,30.8860146 17.9229802,33.0818952 C18.3081697,34.5566974 18.8205424,35.9955145 19.4543708,37.382263 C19.4550184,37.3841188 19.4567729,37.3853625 19.4587433,37.3853625 C19.4607137,37.3853625 19.4624682,37.3841188 19.4631157,37.382263 C19.553137,35.7319847 19.9096213,32.8418174 21.1868946,29.3350401 C22.3365949,26.170425 24.0048179,23.1489332 26.1432091,20.3459737 C28.8057813,16.8617679 32.2008696,13.7161333 36.2430822,10.9967906 C36.8082978,10.6164406 37.575684,10.7650384 37.9570873,11.3286931 C38.3384907,11.8923477 38.1894814,12.6576147 37.6242659,13.0379648 C33.8063348,15.6080283 30.6062069,18.5674488 28.1077306,21.8377391 C26.1205752,24.4406338 24.5722092,27.2451322 23.507386,30.1737735 C21.7069604,35.1199915 21.9096369,38.6811454 21.9127233,38.7165414 C21.9240403,38.8955738 22.0963667,42.2443512 21.2897761,44.2855254 C21.0202266,44.9672847 21.3828838,45.7526674 22.089165,45.9532452 C22.6971917,46.1248695 23.3370158,45.810933 23.5716869,45.22583 C24.6828067,42.4557017 24.5932998,40.0959628 24.1689138,38.346165 C24.1685957,38.3447754 24.1689391,38.3433172 24.1698442,38.342214 C24.1707493,38.3411108 24.1721146,38.3404864 24.1735435,38.3405222 C27.4245977,38.2107365 30.339744,37.6885161 32.8670271,36.7805295 C35.8737378,35.7001795 38.4051362,34.0509271 40.390234,31.8789413 C42.1181281,29.9875593 43.4663897,27.6632164 44.3923229,24.9679842 C45.1701067,22.7051997 45.6716538,20.1192336 45.8841041,17.28293 C46.259107,12.179225 45.6392462,7.13605251 45.2292636,3.79856086 L45.2292636,3.79856086 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

11
src/assets/icons/ic_11.svg

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_11</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-141, -467)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-5" transform="translate(141, 467)">
<path d="M63.4454965,54.4755503 C65.0979531,52.3242886 65.9958229,49.6830571 65.9989078,46.9642711 C66.0719411,41.6448214 62.4767711,36.8119829 56.8931647,34.7269028 C56.8931647,34.9445608 56.9110785,35.1677641 56.9110785,35.3951266 C57.1122647,44.4494205 49.5870736,52.218562 39.3610264,53.5134189 C42.0948001,57.690299 46.7595188,60.1732853 51.7298445,60.0972256 C52.8354781,60.0985041 53.938107,59.9813906 55.0191013,59.7478638 C56.5348878,59.4220701 61.7519495,64.6583383 63.0348561,63.9305012 C64.6980874,62.9850061 62.3307044,55.9437017 63.4482524,54.4713912 L63.4454965,54.4755503 Z M55.6598656,33.5873178 C55.5781455,31.5424066 55.1290245,29.5292851 54.3342414,27.6453941 C51.564486,20.7510435 44.1826056,16.1025904 35.8430237,16 C24.888021,16 16,24.1697985 16,34.2472235 C16.0080124,38.0228748 17.2581046,41.6896579 19.5552084,44.6753966 C21.1068226,46.7244314 17.8175658,56.5010171 20.1284513,57.8125102 C21.9101895,58.8259368 29.165295,51.5503382 31.2639704,52.0022904 C31.7118164,52.0993354 32.1665524,52.179744 32.6281782,52.2476755 C33.6879245,52.4063612 34.7578245,52.4865234 35.8292438,52.4875151 C36.5929853,52.4860007 37.3561006,52.4434251 38.1153255,52.3599704 C48.3482626,51.0623407 55.8734537,43.2987447 55.6722675,34.2458371 C55.6722675,34.0281791 55.6722675,33.8049758 55.6598656,33.5873178 L55.6598656,33.5873178 Z M32.4931354,45.4129382 C32.7069953,43.7486029 34.188336,42.5507048 35.8499136,42.6984523 C37.5106257,42.6371003 38.9130539,43.9276894 38.9999937,45.5973237 C38.8481652,47.265233 37.4053448,48.5091836 35.7438086,48.4046954 C34.0256187,48.4806835 32.5706568,47.1427968 32.4917575,45.4143246 L32.4931354,45.4129382 Z M39.9976568,22.7030334 L36.8048592,40.2016244 L34.2969215,40.2016244 L31.4444868,22.701647 C31.5090143,21.7510241 31.9914736,20.8788482 32.7604651,20.3226594 C33.5898067,19.7118885 34.6131754,19.4287159 35.6363255,19.5268908 C38.5769514,19.5268908 40.2525845,21.277859 39.9962788,22.7002607 L39.9976568,22.7030334 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

13
src/assets/icons/ic_12.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_12</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-365, -467)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-5" transform="translate(365, 467)">
<g id="heart-broken" transform="translate(16, 21)">
<path d="M22.9769167,4.5040061 L22.0520417,6.04141162 L22.0255,6.02507798 L19.8000834,9.44902095 L26.6519167,13.8979009 L21.7355834,28.5430666 L30.0717084,16.1192784 L30.0757917,16.1192784 L31.8255,13.4262665 L31.61725,14.0489873 L31.8255,13.4262665 L32.2991667,12.6973771 L32.1092917,12.5748746 L32.2991667,12.0072801 L32.1092917,12.572833 L25.4779584,8.26687248 L29.106,2.22954426 C31.1231667,0.984102854 33.4874167,0 35.9312917,0 C44.106125,0 49,4.78576169 49,12.7974207 C49,19.3594677 42.98525,24.8557434 42.7382084,25.10279 L25.7045834,41.5099491 C25.3840731,41.8267953 24.9506712,42.0030978 24.5,42 C24.0500347,42.0025548 23.6174676,41.8262931 23.2974584,41.5099491 L6.23525,25.0476639 C6.01679168,24.8557434 0,19.3594677 0,12.7974207 C0,4.78576169 4.89591668,0 13.07075,0 C16.91725,0 20.5697917,2.4377984 22.9769167,4.5040061 L22.9769167,4.5040061 Z" id="路径"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

13
src/assets/icons/ic_13.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_13</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-592, -467)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-6" transform="translate(592, 467)">
<g id="nianshouru" transform="translate(17, 16)">
<path d="M23.9798053,0 C27.2917418,0 30.4075009,0.628997355 33.3270826,1.89276268 C36.2466643,3.15652801 38.7912009,4.87040154 40.9606924,7.04015388 C43.1301839,9.20990623 44.8438514,11.7547487 46.1074648,14.6746814 C47.3710783,17.5946141 48,20.7107478 48,24.0230825 C48,27.3354172 47.3710783,30.4515509 46.1074648,33.3714835 C44.8438514,36.2914162 43.1301839,38.8362587 40.9606924,41.0060111 C38.7912009,43.1757634 36.2466643,44.8838663 33.3270826,46.1303198 C30.4075009,47.3767733 27.2917418,48 23.9798053,48 C21.0429138,48 18.2675802,47.5037269 15.6538045,46.5169512 C13.0400288,45.5244049 10.6743599,44.1625391 8.55679769,42.4198125 L14.3959611,29.9725896 C15.1114317,31.1324838 15.7807429,32.2115893 16.3923549,33.198365 C16.9058781,34.0524164 17.4194014,34.8660736 17.9271547,35.6335658 C18.440678,36.4010579 18.7984133,36.9204136 19.0003606,37.1974032 C19.3754057,37.6763645 19.7273711,38.1207021 20.0504868,38.530416 C20.3736026,38.9401298 20.8294266,39.1767252 21.406419,39.2459726 C22.1218897,39.3498437 22.6354129,39.2228901 22.9412189,38.8593412 C23.2470249,38.5015629 23.5874504,38.0283722 23.9682654,37.4513104 C24.0721241,37.3128156 24.2683015,36.9550373 24.5567977,36.3779755 C24.8452939,35.7951431 25.1972593,35.0795864 25.6069239,34.225535 C26.0165885,33.3714835 26.4781825,32.4251022 26.9917057,31.3806203 C27.505229,30.3361385 28.0187523,29.2685742 28.5265056,28.1779274 C29.7208799,25.6503967 31.0537324,22.8343352 32.5250631,19.7239721 L37.9545618,22.6439048 L35.7504508,6.81509978 L21.8276235,15.3729262 L27.9264335,17.4734311 L21.4698882,30.7400818 C20.4774612,29.13585 19.6235124,27.7335898 18.9080418,26.5390719 C18.6022358,26.0254869 18.3021998,25.540755 18.0137036,25.0791056 C17.7252074,24.6174561 17.4771006,24.2192835 17.2693833,23.8730464 L16.8077894,23.1055542 C16.9462676,23.3767733 16.9520375,23.4229382 16.8308691,23.2325078 C16.7097007,23.0420774 16.5135233,22.7823996 16.2423368,22.4361625 C15.9711504,22.0956961 15.6595745,21.7552296 15.3191489,21.4089925 C14.9787234,21.0685261 14.6556076,20.8954075 14.3440317,20.8954075 C13.559322,20.8954075 12.9938695,21.0916086 12.6534439,21.4840106 C12.3130184,21.8764126 12.036062,22.3265208 11.8341147,22.8401058 C11.7648756,22.9786006 11.5975478,23.3421496 11.3205914,23.9422938 C11.049405,24.5424381 10.6916697,25.2810772 10.2473855,26.1697523 C9.80310133,27.0584275 9.32419762,28.0509738 8.81067436,29.1416206 L7.17201587,32.3154604 C6.65849261,33.4061072 6.16227912,34.4505891 5.68914533,35.4431354 C5.21024162,36.4356817 4.80057699,37.2724213 4.46015146,37.9533542 C3.02344032,35.9740322 1.92715471,33.8042799 1.15398485,31.4440971 C0.386584926,29.089685 0,26.6140899 0,24.0173119 C0,20.7049772 0.623151821,17.5888435 1.86945546,14.6689108 C3.11575911,11.7489781 4.82365669,9.20413561 6.99314821,7.03438327 C9.16263974,4.86463092 11.7071763,3.15075739 14.626758,1.88699207 C17.5521096,0.634767973 20.6678687,0 23.9798053,0 L23.9798053,0 Z" id="路径" transform="translate(24, 24) scale(1, -1) translate(-24, -24)"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

13
src/assets/icons/ic_14.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_14</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-816, -467)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-7" transform="translate(816, 467)">
<g id="yiliao" transform="translate(17, 16)">
<path d="M38.9159207,7.05666333 L36.2168957,7.05666333 L36.2168957,3.00321689 C36.2168957,1.35153436 34.4521928,0 32.2946956,0 L13.7053044,0 C11.5478072,0 9.78253003,1.35153436 9.78253003,3.00321689 L9.78253003,7.05666333 L7.08350502,7.05666333 C3.18772083,7.05666333 0,10.2669189 0,14.1902432 L0,40.8658418 C0,44.7897444 3.18772083,48 7.08350502,48 L38.9159207,48 C42.8122792,48 46,44.7897444 46,40.8658418 L46,14.1902432 C46,10.2669188 42.8122792,7.05666333 38.9159207,7.05666333 Z M32.7403218,30.035639 C32.7365371,31.3474192 31.6815341,32.4098802 30.3789621,32.4136917 L27.0442306,32.4136917 L27.0442306,35.7737322 C27.0404458,37.0855125 25.9854429,38.1479735 24.6828708,38.151785 L21.318852,38.151785 C20.0162799,38.1479735 18.961277,37.0855125 18.9574923,35.7737322 L18.9574923,32.4136917 L15.6210379,32.4136917 C14.319363,32.4086114 13.2657531,31.3465201 13.2619752,30.035639 L13.2619752,26.6472608 C13.26576,25.3354805 14.3207629,24.2730195 15.623335,24.269208 L18.9597893,24.269208 L18.9597893,20.9109025 C18.963574,19.5991223 20.018577,18.5366613 21.321149,18.5328498 L24.6834451,18.5328498 C25.9857929,18.5369787 27.0404474,19.5993472 27.0442306,20.9109025 L27.0442306,24.2715213 L30.3806849,24.2715213 C31.6816914,24.2762771 32.7352828,25.3370584 32.7403218,26.6472608 L32.7403218,30.035639 Z M32.786837,7.05666333 L13.2148858,7.05666333 L13.2148858,4.68959869 C13.2148858,3.59079028 14.3921201,2.68745405 15.8300688,2.68745405 L30.1699312,2.68745405 C31.6084541,2.68745405 32.7851142,3.58847695 32.7851142,4.68959869 L32.786837,7.05666333 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

13
src/assets/icons/ic_15.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_15</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-141, -666)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-8" transform="translate(141, 666)">
<g id="talk" transform="translate(13, 12)">
<path d="M16.9728115,13 L20.8850622,15.0024379 C25.4254052,15.0024379 26.4782132,21.0513668 26.4782132,21.0513668 L26.4782132,26.6832776 C26.4782132,26.6832776 25.5195611,31.1210662 22.6731554,32.7194908 C22.6731554,32.7194908 22.4706478,33.9783477 22.6328857,33.8968514 C22.7945441,33.8159332 22.0598383,39.400738 27.0022995,40.1324703 C31.9447607,40.8624686 35.6107575,43.9234907 36.5430459,44.8164815 C37.4741754,45.7091833 38,52 38,52 L0.0204012986,52 C0.0204012986,52 0.00467012788,51.7246197 0.000835354391,51.2756342 L0.000183078514,50.9862244 C0.00647263175,49.3917187 0.180186749,46.324478 1.34437831,44.8164815 C2.27608729,43.9234907 6.36795847,40.8624686 11.3107094,40.1324703 C16.2534603,39.400738 14.9937991,33.9127461 15.1554575,33.9953983 C15.3174057,34.0763166 15.114898,32.8174597 15.114898,32.8174597 C15.114898,32.8174597 11.2999901,29.3530022 11.3399702,26.2269565 C11.3519137,25.3191431 11.3569223,24.5022112 11.358016,23.7999079 L11.3581983,23.3489484 C11.3570935,21.9040939 11.3399702,21.0513668 11.3399702,21.0513668 C11.3399702,21.0513668 11.9196809,13 16.9728115,13 Z M41.7124678,0 C49.9675051,0 55,4.65414304 55,10.6910408 C55,16.7270684 49.9675051,21.0688081 41.7124678,21.0688081 C40.7070025,21.0688081 39.7236447,20.9957109 38.7735919,20.8573484 C34.9303139,25.7882164 28.6500313,24.9452785 28.6500313,24.9452785 C32.9308676,22.8889855 33.0330794,19.2590731 32.2705105,18.8065668 C28.9110159,16.8016159 27,14.1083334 27,10.6907508 C26.9997129,4.65385297 33.4574306,0 41.7124678,0 Z" id="形状结合"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

13
src/assets/icons/ic_16.svg

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.9 KiB

13
src/assets/icons/ic_17.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_17</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-592, -666)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-10" transform="translate(592, 666)">
<g id="yichang" transform="translate(17, 14)">
<path d="M24.0001084,0.000283153158 C19.3579947,-0.025981847 14.8920148,1.77592239 11.5681386,5.01654209 C8.32260312,8.22539557 6.49126683,12.5963893 6.4801786,17.1603746 L6.4801786,40.5840919 L41.3280379,40.5840919 L41.3280379,17.1603278 C41.3240176,12.5901402 39.4817267,8.2136846 36.2160311,5.01649521 C32.9498959,1.82164607 28.5689081,0.0228129379 24.0000615,0.000283153158 L24.0001084,0.000283153158 Z M22.5601064,34.9681728 L22.0561058,23.6162417 L13.4641411,23.6162417 L24.7440156,9.38446873 L25.7040169,18.5523662 L33.8640279,18.8403644 L22.4640126,34.9681728 L22.5601064,34.9681728 Z M0.000106523372,45.3840159 C-0.00618668228,44.6860729 0.266591275,44.014512 0.757872713,43.5187182 C1.24915415,43.0229244 1.91819592,42.7440319 2.61617342,42.7440319 L45.3840433,42.7440319 C46.075939,42.7526474 46.7378621,43.027747 47.2320459,43.5120741 C47.7178305,44.0149991 47.9926246,44.6848289 48,45.3840159 C48,46.8287657 46.8288039,48 45.3840433,48 L2.61617342,48 C1.17141287,48 0.000106523372,46.8287657 0.000106523372,45.3840159 L0.000106523372,45.3840159 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

13
src/assets/icons/ic_18.svg

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_18</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-816, -662)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2备份-11" transform="translate(816, 662)">
<g id="renyuanfangwen" transform="translate(11, 16)">
<path d="M43.757586,37.3526544 L33.223136,33.2217727 C33.223136,33.2217727 31.197194,32.4656029 30.444944,31.6510746 C29.923856,31.1273899 29.981912,29.963778 30.444944,28.5093224 C30.907976,26.9966269 36.2909,20.9456077 36.2909,15.4181545 C36.2909,6.86554757 30.73428,0 23.84662,0 C16.95896,0 11.40234,6.92355024 11.40234,15.4181545 C11.40234,20.7126481 16.206356,26.9965083 16.785382,28.1601202 C17.364054,29.3238507 17.248414,31.06915 16.785382,31.5928347 C16.090716,32.4072444 13.485984,33.1638887 13.485984,33.1638887 L3.993828,37.4110129 C1.736606,38.2255412 0,40.3202799 0,42.7055064 L0,43.8111157 C0,46.4293018 2.083644,48 4.688376,48 L43.063038,48 C45.609596,48 47.75106,46.4293018 47.75106,43.8111157 L47.75106,42.7055064 C47.75106,40.3202799 45.956752,38.10918 43.757586,37.3526544 Z M43.082744,16.6338384 C41.983102,16.6338384 41.11474,16.0519138 41.11474,14.8883019 C41.11474,13.7245713 41.982984,13.1430026 43.082744,13.1430026 L57.031996,13.1430026 C58.131638,13.1430026 58.94218,13.7246899 58.94218,14.8883019 C58.94218,16.0519138 58.01588,16.6338384 56.916356,16.6338384 L43.082744,16.6338384 Z M46.034868,25.1802773 C44.93499,25.1802773 44.066746,24.5982341 44.066746,23.4346222 C44.066746,22.2708917 44.93499,21.6893229 46.034868,21.6893229 L57.089934,21.6893229 C58.189576,21.6893229 58.94218,22.2710103 58.94218,23.4346222 C58.94218,24.5982341 58.131638,25.1802773 57.031996,25.1802773 L46.034868,25.1802773 L46.034868,25.1802773 Z M49.681422,33.7267163 C48.581544,33.7267163 47.713182,33.1450289 47.713182,31.981417 C47.713182,30.8178051 48.581426,30.2358805 49.681422,30.2358805 L57.090052,30.2358805 C58.189694,30.2358805 59,30.8178051 59,31.981417 C59,33.1451475 58.131756,33.7267163 57.031996,33.7267163 L49.681422,33.7267163 L49.681422,33.7267163 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

11
src/assets/icons/ic_19.svg

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="81px" height="80px" viewBox="0 0 81 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_08</title>
<g id="灵敏感知_模型超市图标" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="模型图标备份" transform="translate(-365, -288)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-5" transform="translate(365, 288)">
<path d="M56,40 L56,55.7156844 C51.6237181,59.8430562 45.8733097,62.0883085 39.9337877,61.9887516 C33.7192701,62.1795444 27.6663062,59.9372433 23,55.7156844 L23,41.0565166 C26.4703019,42.4762108 30.3583252,43.6978081 35.0496592,45.3486153 C38.0242786,46.605264 41.3613105,46.605264 44.3359299,45.3486153 C47.3885102,44.0609857 51.5014606,41.9479525 56,40 Z M36.2356053,19.3312402 C39.5144409,18.0561821 41.2194354,17.3549002 44.2359641,18.821217 C49.5148894,20.9569392 61.1219673,25.3558895 67.1878131,27.7784998 C71.3375893,29.5217432 70.0639986,30.3505621 68.6046677,31.05535 L68.4289916,31.1393798 C68.0771972,31.306451 67.7267717,31.4681991 67.4501199,31.6355504 L67.548485,40.8159684 L69.8108815,43.3342081 L65.4828186,47 L61.4826392,43.3342081 L63.8761891,40.7522155 L63.8761891,33.1656201 C51.8271072,37.9346684 48.0058508,39.6378999 45.228198,40.8553787 L44.9989887,40.9557661 C44.8854379,41.0054529 44.7733525,41.0544208 44.6622127,41.1028565 C42.2472296,42.3082142 39.399026,42.3786122 36.9241608,41.2941152 C34.2027273,40.2740688 21.087385,35.6519833 14.5297139,32.4643382 C9.97213246,30.5198746 9.67703726,29.0854343 14.5297139,27.3322295 C20.8250782,25.037125 30.6615849,21.3394566 36.2356053,19.3312402 Z" id="形状结合"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

10
src/assets/icons/lock-fill.svg

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="登录页" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g transform="translate(-1194.000000, -493.000000)" fill="#C0C5E2" fill-rule="nonzero" id="mima">
<g transform="translate(1194.000000, 493.000000)">
<path d="M24.7519225,13.3671273 C24.1635627,13.3671273 23.6803339,12.9320399 23.5802727,12.3496015 C23.0978443,9.53707218 20.6507478,7.39056953 17.7142854,7.39056953 C14.777823,7.39056953 12.3307266,9.53734009 11.8482982,12.3496015 C11.7485039,12.931772 11.265275,13.3671273 10.6766484,13.3671273 C9.95487366,13.3671273 9.3739851,12.7230694 9.49085657,12.008015 C10.1392531,8.03864616 13.5800239,5 17.7142854,5 C21.848547,5 25.289051,8.03864616 25.9377143,12.008015 C26.0545858,12.7230694 25.4736972,13.3671273 24.7519225,13.3671273 L24.7519225,13.3671273 Z M26.7083189,14.4998549 L8.83472199,14.4998549 C7.82130225,14.4998549 7,15.3247527 7,16.3420107 L7,27.1578442 C7,28.1753701 7.82156908,29 8.83472199,29 L26.5885123,29 C27.6016652,29 28.4229674,28.175638 28.4235011,27.15838 L28.4285712,16.2276127 C28.4291045,15.2735817 27.6587668,14.4998549 26.7083189,14.4998549 Z M18.9048802,23.7224219 C18.9048802,24.3825545 18.372021,24.9178406 17.7142854,24.9178406 C17.0568167,24.9178406 16.5236907,24.3828224 16.5236907,23.7224219 L16.5236907,21.3318524 C16.5236907,20.6717198 17.0565499,20.1364337 17.7142854,20.1364337 C18.3717542,20.1364337 18.9048802,20.6717198 18.9048802,21.3318524 L18.9048802,23.7224219 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

1
src/assets/icons/logout.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709281824017" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2275" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M835.669333 554.666667h-473.173333A42.453333 42.453333 0 0 1 320 512a42.666667 42.666667 0 0 1 42.474667-42.666667h473.173333l-161.813333-161.834666a42.666667 42.666667 0 0 1 60.330666-60.330667l234.666667 234.666667a42.666667 42.666667 0 0 1 0 60.330666l-234.666667 234.666667a42.666667 42.666667 0 0 1-60.330666-60.330667L835.669333 554.666667zM554.666667 42.666667a42.666667 42.666667 0 1 1 0 85.333333H149.525333C137.578667 128 128 137.578667 128 149.482667v725.034666C128 886.4 137.6 896 149.525333 896H554.666667a42.666667 42.666667 0 1 1 0 85.333333H149.525333A106.816 106.816 0 0 1 42.666667 874.517333V149.482667A106.773333 106.773333 0 0 1 149.525333 42.666667H554.666667z" fill="" p-id="2276"></path></svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

1
src/assets/icons/menu.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1727680990386" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4266" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M491.266 665.192c-19.564 0-38.772-5.075-57.091-15.083-28.51-15.575-326.123-189.452-338.778-196.847l-1.343-0.832c-4.595-3.011-27.595-19.456-29.208-47.466-0.733-12.747 2.874-31.683 24.228-49.5l2.529-2.11L494.208 142.91c6.484-4.038 25.806-14.559 51.127-14.559 18.049 0 35.198 5.16 50.974 15.339 37.943 24.478 331.77 207.44 334.733 209.286l0.589 0.376c4.937 3.232 29.563 20.836 29.465 50.071-0.045 13.561-5.596 33.272-31.782 50.167C899.354 472.92 583.8 631.665 542.97 652.187c-6.25 3.615-25.053 13.005-51.704 13.005z m-361.09-262.72c35.548 20.765 307.381 179.522 333.435 193.756 9.19 5.02 18.494 7.567 27.654 7.567 11.254 0 19.254-3.868 20.804-4.677l1.514-1.049 0.844-0.252c139.635-70.176 353.53-178.712 380.393-195.065-36.099-22.48-295.351-183.954-331.798-207.468-5.77-3.723-11.557-5.533-17.688-5.533-9.917 0-18.06 4.861-18.13 4.91l-1.61 1.124-395.418 206.687z" p-id="4267"></path><path d="M955.967 540.969c0-16.404-14.1-29.71-31.493-29.71-7.566 0-14.505 2.517-19.934 6.715l-0.136-0.203c-21.338 13.42-245.852 124.473-391.554 195.848l-0.863 0.26-1.55 1.043c-3.418 1.821-23.625 11.303-50.297-2.901-27.615-14.705-324.165-183.55-344.872-195.346-5.366-4.004-12.14-6.398-19.513-6.398-17.394 0-31.494 13.306-31.494 29.71 0 12.142 7.727 22.578 18.792 27.185l-0.046 0.075C95.99 574.642 401.3 748.51 430.541 764.08c20.681 11.014 40.76 14.965 58.464 14.965 22.723 0 41.536-6.51 52.688-12.956 41.796-20.476 356.866-174.976 394.766-197.643 11.446-4.449 19.508-15.073 19.508-27.477z" p-id="4268"></path><path d="M955.967 658.824c0-16.409-14.1-29.71-31.493-29.71-7.566 0-14.505 2.517-19.934 6.711l-0.136-0.202c-21.338 13.418-245.852 124.476-391.554 195.85l-0.863 0.26-1.55 1.044c-3.418 1.821-23.625 11.302-50.297-2.902C432.525 815.17 135.975 646.32 115.268 634.53c-5.366-4.004-12.14-6.4-19.513-6.4-17.394 0-31.494 13.303-31.494 29.71 0 12.144 7.727 22.579 18.792 27.187l-0.046 0.074C95.99 692.496 401.3 866.364 430.541 881.934c20.681 11.015 40.76 14.966 58.464 14.966 22.723 0 41.536-6.51 52.688-12.957 41.796-20.476 356.866-174.975 394.766-197.642 11.446-4.449 19.508-15.073 19.508-27.477z" p-id="4269"></path></svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

1
src/assets/icons/mp3.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709019342612" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3819" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M332.799002 686.081014m-332.799002 0a332.799002 332.799002 0 1 0 665.598003 0 332.799002 332.799002 0 1 0-665.598003 0Z" fill="#DFDFF2" p-id="3820"></path><path d="M883.19735 1024h-639.99808A141.055577 141.055577 0 0 1 102.399693 883.200422v-742.397772A141.055577 141.055577 0 0 1 243.19927 0.003072h516.350451a89.087733 89.087733 0 0 1 63.231811 25.599923l189.695431 189.695431A38.399885 38.399885 0 0 1 1023.996928 243.202342v639.99808a141.055577 141.055577 0 0 1-140.799578 140.799578zM243.19927 76.802842A63.999808 63.999808 0 0 0 179.199462 140.80265v742.397772A63.999808 63.999808 0 0 0 243.19927 947.20023h639.99808a63.999808 63.999808 0 0 0 63.999808-63.999808V259.074295l-179.199462-179.199463a12.799962 12.799962 0 0 0-8.447975-3.07199z" fill="#434260" p-id="3821"></path><path d="M274.943175 399.105875h40.959877L358.398925 513.281532c5.119985 15.103955 9.727971 30.463909 15.103954 45.823863h1.535996c5.119985-15.359954 9.471972-30.719908 14.847955-45.823863l40.959877-114.175657h41.215877v226.047322h-34.815896v-111.871665c0-20.223939 2.815992-49.407852 4.607986-69.88779l-18.175945 51.199846L383.998848 603.393262h-22.015934l-39.679881-107.775677-17.919946-51.199846c1.535995 20.479939 4.351987 49.663851 4.351987 69.88779v111.871664h-33.791899zM529.91841 399.105875h68.351795c51.199846 0 86.271741 17.151949 86.271741 68.095795s-35.839892 72.191783-84.991745 72.191784h-34.047898v85.759743H529.91841zM596.222211 512.001536c36.351891 0 53.503839-13.823959 53.50384-43.519869s-18.687944-39.679881-54.527837-39.679881h-29.695911V512.001536zM707.325878 598.017278l17.151949-22.783932a72.959781 72.959781 0 0 0 53.503839 25.599924A37.887886 37.887886 0 0 0 820.989537 563.201382c0-25.599923-15.871952-41.471876-66.8158-41.471875v-25.599923c44.543866 0 59.135823-16.895949 59.135823-39.679881a31.487906 31.487906 0 0 0-34.815895-32.767902 66.047802 66.047802 0 0 0-45.055865 21.503935l-18.431945-22.015934a95.231714 95.231714 0 0 1 64.767806-27.391917c40.447879 0 69.119793 20.991937 69.119792 58.367825a54.527836 54.527836 0 0 1-38.911883 53.24784v1.535995A57.087829 57.087829 0 0 1 856.57343 563.201382c0 40.959877-34.047898 64.767806-76.799769 64.767806a93.695719 93.695719 0 0 1-72.447783-29.95191z" fill="#434260" p-id="3822"></path></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

1
src/assets/icons/mp4.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1712131041791" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10124" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M332.799002 686.081014m-332.799002 0a332.799002 332.799002 0 1 0 665.598003 0 332.799002 332.799002 0 1 0-665.598003 0Z" fill="#D3EFDE" p-id="10125"></path><path d="M883.19735 1024h-639.99808A141.055577 141.055577 0 0 1 102.399693 883.200422v-742.397772A141.055577 141.055577 0 0 1 243.19927 0.003072h516.350451a89.087733 89.087733 0 0 1 63.231811 25.599923l189.695431 189.695431A38.399885 38.399885 0 0 1 1023.996928 243.202342v639.99808a141.055577 141.055577 0 0 1-140.799578 140.799578zM243.19927 76.802842A63.999808 63.999808 0 0 0 179.199462 140.80265v742.397772A63.999808 63.999808 0 0 0 243.19927 947.20023h639.99808a63.999808 63.999808 0 0 0 63.999808-63.999808V259.074295l-179.199462-179.199463a12.799962 12.799962 0 0 0-8.447975-3.07199z" fill="#434260" p-id="10126"></path><path d="M278.527164 399.105875h40.959878L360.958917 512.001536c5.119985 15.103955 9.727971 30.463909 15.103955 45.823863h1.535995c5.119985-15.359954 9.471972-30.719908 14.847956-45.823863l40.959877-114.175657h41.215876v226.047321h-33.535899V512.001536c0-20.223939 2.815992-49.407852 4.607986-69.88779l-18.175946 51.199846-39.423881 107.775677h-22.015934l-40.959877-105.727683-17.919947-51.199846c1.535995 20.479939 4.351987 49.663851 4.351987 69.88779v111.871664h-33.023901zM533.502399 399.105875h68.351795c51.199846 0 86.271741 17.151949 86.271742 68.095795s-35.839892 72.191783-84.991745 72.191784h-34.047898v85.759743h-35.583894zM599.806201 512.001536c36.351891 0 53.503839-13.823959 53.503839-43.519869s-18.687944-39.679881-54.527836-39.679881h-29.695911V512.001536zM868.349395 563.201382h-28.927913v60.927818H806.397581V563.201382h-97.791707v-23.551929l89.855731-141.567575h40.703878V537.601459h28.927913z m-61.951814-25.599923v-59.90382c0-12.287963 0-31.231906 1.791994-43.51987-5.631983 11.263966-11.775965 23.039931-18.175945 34.815896L744.189767 537.601459z" fill="#434260" p-id="10127"></path></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

1
src/assets/icons/pdf.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709031631445" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10118" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M332.799002 686.081014m-332.799002 0a332.799002 332.799002 0 1 0 665.598003 0 332.799002 332.799002 0 1 0-665.598003 0Z" fill="#FFDCEE" p-id="10119"></path><path d="M883.19735 1024h-639.99808A141.055577 141.055577 0 0 1 102.399693 883.200422v-742.397772A141.055577 141.055577 0 0 1 243.19927 0.003072h516.350451a89.087733 89.087733 0 0 1 63.231811 25.599923l189.695431 189.695431A38.399885 38.399885 0 0 1 1023.996928 243.202342v639.99808a141.055577 141.055577 0 0 1-140.799578 140.799578zM243.19927 76.802842A63.999808 63.999808 0 0 0 179.199462 140.80265v742.397772A63.999808 63.999808 0 0 0 243.19927 947.20023h639.99808a63.999808 63.999808 0 0 0 63.999808-63.999808V259.074295l-179.199462-179.199463a12.799962 12.799962 0 0 0-8.447975-3.07199z" fill="#434260" p-id="10120"></path><path d="M299.775101 399.105875h68.351795c51.199846 0 86.271741 17.151949 86.271741 68.095795s-35.839892 72.191783-84.991745 72.191784H335.358994v85.759743h-35.583893zM366.078902 512.001536c36.351891 0 53.503839-13.823959 53.503839-43.519869s-18.687944-39.679881-54.527836-39.679881H335.358994V512.001536zM488.190535 399.105875h58.623825c69.375792 0 109.055673 38.399885 109.055672 112.127663s-39.679881 113.919658-107.263678 113.919659h-60.415819z m56.319831 196.863409c48.383855 0 74.495777-28.671914 74.495777-84.735746s-25.599923-83.19975-74.495777-83.19975h-20.479938v167.935496zM692.733922 399.105875h133.887598v29.695911h-98.303705v69.119792h83.45575v29.695911h-83.45575v97.279708h-35.583893z" fill="#434260" p-id="10121"></path></svg>

After

Width:  |  Height:  |  Size: 1.8 KiB

1
src/assets/icons/police.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1730699260266" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2520" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M99.9 980.6c5.3-79.7 16.4-187.7 41-286.2 4.9-25.5 23.1-47 23.6-47.9 2.2-15.2 187-15.2 187-15.2l30.7-3.2c-4.5 27.3-7.6 68.6 4 103.9 15.1 46.6 39.2 92.8 71.7 120.5l7.1-123.6h62.8l10.7 116c22.7-32.7 49.4-84.7 52.6-151 2.2-51.5 15.1-75.2 26.2-86 76.6 3.1 172.3 17 211 38.5 36.5 20.1 48.1 146.5 81.5 334.1H99.9v0.1z m561.4-706.3s6.2 17 4 33.6c1.4 7.6 2.7 16.1 3.6 26.9 1.8 29.5 16.5 231.6-168.3 250.8 0 0-213.7-4-195-249.5-5.3-7.2-8.4-12.6-8.4-12.6s-1.3-38.5 1.8-48.4c0 0-62.8-21.9-63.7-73-0.9-51.5 126-121.4 245.8-117.4 119.8 4.1 229.7 60.9 248.4 99 19.1 38.1-41 80.3-68.2 90.6z m-130-114.2c0-20.6-18.3-37.6-40.5-37.6-22.3 0-40.6 17-40.6 37.6 0 1.8 0 3.1 0.5 4.9-20-1.8-36.5 0.5-36.9 0 31.2 13 45 22.4 45 22.4 8.9 7.6 20.5 9.4 29.4 9.4 0.9 0 1.4 0.4 2.3 0.4 3.6 0 7.1-0.4 10.7-1.4 1.8 0 3.1-0.5 3.1-0.5 0.5 0 0.5-0.5 0.9-0.5 3.6-0.9 6.2-2.7 9.3-4.5 19.1-9.4 53-25.1 53-25.1-12 0-24.9 0.9-36.9 2.2 0.3-2 0.7-4.7 0.7-7.3z m99.7 76.1H324.7v36.3H631v-36.3z m-87.7 439.4L519.7 711h-39.6l-31.6-26.4 47.6-62.3 47.2 53.3z" fill="#bfbfbf" p-id="2521"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1
src/assets/icons/question.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1726106056602" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2706" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M501.2 750.7c3.1 1.3 6.6 2.2 9.7 2.2 3.1 0 7.1-0.9 9.7-2.2 12.8-5.3 18.6-19.9 12.8-32.8-2.2-5.8-7.1-10.2-12.8-12.8-3.1-1.3-6.6-2.2-9.7-2.2-3.1 0-7.1 0.9-9.7 2.2-6.2 2.7-10.6 7.5-13.3 13.3-2.7 6.2-2.7 13.3 0.4 18.6 2.7 6.6 7.2 11.4 12.9 13.7zM571.2 555c5.3-4.4 10.6-8.4 16.4-12.8l0.4-0.4c19.9-15.5 42.9-33.7 56.7-58 23.5-40.3 17.7-95.2-13.7-133.3-25.7-31.4-69.1-49.6-118.7-49.6-116.4 0-147.4 87.7-147.4 133.3 0 13.3 11.1 24.4 24.4 24.4 12-1.8 24.4-10.6 24.8-23.9 0-8.4 4-84.6 98.7-84.6 16.4 0 57.6 2.7 80.6 31 18.6 22.6 22.1 55.3 8.9 77.5-9.3 16.4-27 30.1-44.7 43.8l-0.4 0.4c-5.3 4-12 8.9-17.7 13.7-32.8 27.4-51.8 70-51.8 113.8 0 13.3 11.1 24.4 24.4 24.4 13.3 0 24.4-11.1 24.4-24.4 0.1-28.8 12.5-56.7 34.7-75.3z" fill="#282828" p-id="2707"></path><path d="M511.9 103.6c-226.1 0-409.3 183.3-409.3 409.3s183.3 409.3 409.3 409.3S921.3 739 921.3 512.9 738 103.6 511.9 103.6z m0 773.3c-201 0-364-163-364-364s163-364 364-364 364 163 364 364-162.9 364-364 364z" p-id="2708"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

1
src/assets/icons/rotate-left.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710476192729" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1635" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M541.226667 66.517333L393.045333 217.685333a21.333333 21.333333 0 0 0 0 29.866667l147.84 150.826667a21.333333 21.333333 0 0 0 28.16 2.090666l2.346667-2.090666 27.050667-27.605334a21.333333 21.333333 0 0 0 0-29.866666l-69.888-71.338667a304.64 304.64 0 1 1-318.421334 352.682667l-1.024-6.826667a176.554667 176.554667 0 0 1-0.64-5.632 21.333333 21.333333 0 0 0-22.314666-19.114667l-42.666667 2.261334a21.333333 21.333333 0 0 0-20.224 22.4l0.085333 1.024 1.194667 10.496A389.973333 389.973333 0 1 0 539.178667 184.746667l59.306666-60.458667a21.333333 21.333333 0 0 0 0-29.866667l-27.093333-27.605333a21.333333 21.333333 0 0 0-30.165333-0.298667z" p-id="1636"></path></svg>

After

Width:  |  Height:  |  Size: 976 B

1
src/assets/icons/rotate-right.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1710476185031" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1494" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M482.773333 66.517333l148.181334 151.168a21.333333 21.333333 0 0 1 0 29.866667l-147.84 150.826667a21.333333 21.333333 0 0 1-28.16 2.090666l-2.346667-2.090666-27.050667-27.605334a21.333333 21.333333 0 0 1 0-29.866666l69.888-71.338667a304.64 304.64 0 1 0 318.421334 352.682667l1.024-6.826667c0.170667-1.408 0.426667-3.285333 0.64-5.632a21.333333 21.333333 0 0 1 22.314666-19.114667l42.666667 2.261334a21.333333 21.333333 0 0 1 20.224 22.4l-0.085333 1.024-1.194667 10.496A389.973333 389.973333 0 1 1 484.821333 184.746667l-59.306666-60.458667a21.333333 21.333333 0 0 1 0-29.866667l27.093333-27.605333a21.333333 21.333333 0 0 1 30.165333-0.298667z" p-id="1495"></path></svg>

After

Width:  |  Height:  |  Size: 978 B

19
src/assets/icons/sign.svg

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_qianshou</title>
<g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1.0首页" transform="translate(-432, -182)">
<g id="编组-3" transform="translate(325, 169)">
<g id="编组-8" transform="translate(107, 13)">
<circle id="椭圆形" fill="#E9EBFD" cx="48" cy="48" r="48"></circle>
<g id="bianji" transform="translate(26.0333, 21.0536)" fill-rule="nonzero">
<path d="M39.363,51.2094513 L7.8,51.2094513 C3.492,51.2094513 0,47.7174513 0,43.4094513 L0,11.8044513 C0,7.49645131 3.492,4.00445131 7.8,4.00445131 L39.363,4.00445131 C43.671,4.00445131 47.163,7.49645131 47.163,11.8044513 L47.163,43.4064513 C47.163,47.7174513 43.671,51.2094513 39.363,51.2094513 Z" id="路径" fill="#6D79D4"></path>
<path d="M28.668,30.3924513 L21.453,32.9724513 C19.584,33.6414513 18.387,32.3964513 19.077,30.5064513 L21.627,23.4954513 C21.837,22.9164513 22.209,22.3404513 22.689,21.8484513 L42.417,1.12745131 C43.701,-0.192548688 45.123,-0.297548688 45.966,0.521451312 L50.577,5.00645131 C51.42,5.82545131 51.36,7.25945131 50.076,8.57945131 L30.402,29.2464513 C29.886,29.7684513 29.277,30.1734513 28.668,30.3924513 L28.668,30.3924513 Z" id="路径" fill="#5461C2"></path>
<path d="M39.699,4.01045131 L22.686,21.8454513 C22.206,22.3374513 21.837,22.9134513 21.624,23.4924513 L19.074,30.5034513 C18.387,32.3964513 19.584,33.6384513 21.45,32.9694513 L28.665,30.3894513 C29.277,30.1704513 29.886,29.7684513 30.399,29.2404513 L47.154,11.6694513 C47.142,7.51445131 43.83,4.13345131 39.699,4.01045131 Z" id="路径" fill="#3F4CAA"></path>
<path d="M32.988,41.9424513 L14.175,41.9424513 C13.014,41.9424513 12.075,41.0034513 12.075,39.8424513 C12.075,38.6814513 13.014,37.7424513 14.175,37.7424513 L32.988,37.7424513 C34.149,37.7424513 35.088,38.6814513 35.088,39.8424513 C35.088,41.0034513 34.149,41.9424513 32.988,41.9424513 Z" id="路径" fill="#E9EBFD"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

22
src/assets/icons/verify.svg

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>ic_zhengzaibanli</title>
<g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="1.0首页" transform="translate(-762, -182)">
<g id="编组-3" transform="translate(325, 169)">
<g id="编组-11" transform="translate(437, 13)">
<circle id="椭圆形备份-3" fill="#E9EBFD" cx="48" cy="48" r="48"></circle>
<g id="daichuli" transform="translate(27.0359, 23.0221)" fill-rule="nonzero">
<path d="M34.605,49.893 L7.8,49.893 C3.492,49.893 0,46.401 0,42.093 L0,7.8 C0,3.492 3.492,0 7.8,0 L34.605,0 C38.913,0 42.405,3.492 42.405,7.8 L42.405,42.093 C42.405,46.401 38.913,49.893 34.605,49.893 Z" id="路径" fill="#5461C2"></path>
<path d="M30.81,14.16 L11.763,14.16 C10.437,14.16 9.363,13.086 9.363,11.76 C9.363,10.434 10.437,9.36 11.763,9.36 L30.813,9.36 C32.139,9.36 33.213,10.434 33.213,11.76 C33.213,13.086 32.136,14.16 30.81,14.16 L30.81,14.16 Z M30.81,23.676 L11.763,23.676 C10.437,23.676 9.363,22.602 9.363,21.276 C9.363,19.95 10.437,18.876 11.763,18.876 L30.813,18.876 C32.139,18.876 33.213,19.95 33.213,21.276 C33.213,22.602 32.136,23.676 30.81,23.676 L30.81,23.676 Z M20.883,33.192 L11.763,33.192 C10.437,33.192 9.363,32.118 9.363,30.792 C9.363,29.466 10.437,28.392 11.763,28.392 L20.883,28.392 C22.209,28.392 23.283,29.466 23.283,30.792 C23.283,32.118 22.209,33.192 20.883,33.192 L20.883,33.192 Z" id="形状" fill="#FFFFFF"></path>
<path d="M26.172,38.598 C26.172,42.5743661 28.2933659,46.2486799 31.7369999,48.2368629 C35.180634,50.225046 39.423366,50.225046 42.8670001,48.2368629 C46.3106341,46.2486799 48.432,42.5743661 48.432,38.598 C48.432,32.4510707 43.4489293,27.468 37.302,27.468 C31.1550707,27.468 26.172,32.4510707 26.172,38.598 L26.172,38.598 Z" id="路径" fill="#6E7AD4"></path>
<path d="M37.302,27.4469998 C31.155,27.4469998 26.172,32.43 26.172,38.577 C26.172,44.436 30.699,49.233 36.447,49.671 C39.867,48.846 42.411,45.765 42.411,42.09 L42.411,28.686 C40.8311603,27.8715212 39.0794333,27.4467043 37.302,27.4469998 L37.302,27.4469998 Z" id="路径" fill="#3F4CAA"></path>
<path d="M29.073,38.598 C29.073,39.7627685 30.0172315,40.707 31.182,40.707 C32.3467685,40.707 33.291,39.7627685 33.291,38.598 C33.291,37.4332315 32.3467685,36.489 31.182,36.489 C30.0172315,36.489 29.073,37.4332315 29.073,38.598 Z" id="路径" fill="#FFFFFF"></path>
<path d="M35.217,38.598 C35.217,39.7627685 36.1612315,40.707 37.326,40.707 C38.4907685,40.707 39.435,39.7627685 39.435,38.598 C39.435,37.4332315 38.4907685,36.489 37.326,36.489 C36.1612315,36.489 35.217,37.4332315 35.217,38.598 Z" id="路径" fill="#FFFFFF"></path>
<path d="M41.361,38.598 C41.361,39.7627685 42.3052315,40.707 43.47,40.707 C44.6347685,40.707 45.579,39.7627685 45.579,38.598 C45.579,37.4332315 44.6347685,36.489 43.47,36.489 C42.3052315,36.489 41.361,37.4332315 41.361,38.598 Z" id="路径" fill="#FFFFFF"></path>
</g>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

1
src/assets/icons/xls.svg

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1709019841451" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3960" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M332.799002 686.081014m-332.799002 0a332.799002 332.799002 0 1 0 665.598003 0 332.799002 332.799002 0 1 0-665.598003 0Z" fill="#DFDFF2" p-id="3961"></path><path d="M883.19735 1024h-639.99808A141.055577 141.055577 0 0 1 102.399693 883.200422v-742.397772A141.055577 141.055577 0 0 1 243.19927 0.003072h516.350451a89.087733 89.087733 0 0 1 63.231811 25.599923l189.695431 189.695431A38.399885 38.399885 0 0 1 1023.996928 243.202342v639.99808a141.055577 141.055577 0 0 1-140.799578 140.799578zM243.19927 76.802842A63.999808 63.999808 0 0 0 179.199462 140.80265v742.397772A63.999808 63.999808 0 0 0 243.19927 947.20023h639.99808a63.999808 63.999808 0 0 0 63.999808-63.999808V259.074295l-179.199462-179.199463a12.799962 12.799962 0 0 0-8.447975-3.07199z" fill="#434260" p-id="3962"></path><path d="M370.686888 508.417547l-60.927817-109.311672h39.679881l27.391918 52.735841c5.631983 10.495969 10.495969 20.479939 17.151948 34.047898h1.535995c5.887982-13.567959 10.239969-23.551929 15.359954-34.047898l25.599924-52.735841h37.375887l-60.671818 111.103666 65.023805 114.943656h-38.399884L409.598771 568.833365l-18.687944-36.863889c-6.399981 13.823959-12.031964 25.599923-17.407948 36.863889l-28.927913 56.063832h-38.655884zM513.790459 399.105875h35.583893v195.839412h95.487713v30.20791h-131.071606zM660.734018 595.969284l20.991937-25.599923a87.551737 87.551737 0 0 0 60.159819 25.599923c27.391918 0 42.751872-12.799962 42.751872-31.999904s-15.359954-27.135919-36.351891-36.351891L716.79785 516.353523a65.023805 65.023805 0 0 1-46.079862-59.135823 67.071799 67.071799 0 0 1 74.239777-62.207813 96.76771 96.76771 0 0 1 68.351795 28.671914l-18.687944 22.783932a71.935784 71.935784 0 0 0-49.663851-20.22394c-23.039931 0-38.143886 11.007967-38.143885 29.183913s18.175945 25.599923 36.60789 34.047898l30.975907 13.31196a62.975811 62.975811 0 0 1 46.079862 60.415818c0 36.351891-29.95191 65.791803-79.615762 65.791803a112.639662 112.639662 0 0 1-80.127759-33.023901z" fill="#434260" p-id="3963"></path></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

66
src/components/countdown.vue

@ -0,0 +1,66 @@
<template>
<div v-if="timeVal > 0" class="success">
<span class="mr-4">剩余</span>
<span class="text">{{
formatTimeText(timeVal)
}}</span>
</div>
<div v-if="timeVal < 0" class="error">
<span class="mr-4">超时</span>
<span class="text">{{
formatTimeText(-timeVal)
}}</span>
</div>
</template>
<script setup>
import { formatTimeText } from "@/utils/util";
const props = defineProps({
time: {
type: Number,
default: 0
}
})
const timeVal = ref(props.time)
watch(() => props.time, (val) => {
timeVal.value = val;
startTimeInterval()
})
let timer = 0;
startTimeInterval()
function startTimeInterval() {
if (timeVal.value < 3600 && timeVal.value > -3600) {
clearInterval(timer)
timer = setInterval(() => {
timeVal.value -= 1;
}, 1000);
} else {
clearInterval(timer)
}
}
</script>
<style lang="scss" scoped>
.success {
padding: 0 8px;
height: 24px;
line-height: 24px;
text-align: center;
.text {
color: #128009;
}
}
.error {
background-color: #ff0000;
color: #fff;
padding: 0 8px;
height: 24px;
line-height: 24px;
border-radius: 20px;
text-align: center;
}
</style>

52
src/components/date-time-range-picker-ext.vue

@ -0,0 +1,52 @@
<template>
<el-date-picker
type="datetimerange"
start-placeholder="开始时间"
end-placeholder="结束时间"
value-format="YYYY-MM-DD HH:mm:ss"
:shortcuts="shortcuts"
:unlink-panels="true"
/>
</template>
<script setup>
const shortcuts = [
{
text: "今天",
value: () => {
const end = new Date();
const start = new Date();
start.setHours(0, 0, 0, 0);
return [start, end];
},
},
{
text: "近一周",
value: () => {
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 7);
return [start, end];
},
},
{
text: "近一个月",
value: () => {
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 1)
return [start, end];
},
},
{
text: "近三个月",
value: () => {
const end = new Date();
const start = new Date();
start.setMonth(start.getMonth() - 3)
return [start, end];
},
},
];
</script>
<style lang="scss" scoped>
</style>

41
src/components/depart-tree-select.vue

@ -0,0 +1,41 @@
<template>
<el-tree-select :data="data" :props="{label: 'shortName', value: 'id'}" node-key="id" :default-expanded-keys="['12630']" clearable filterable check-strictly />
</template>
<script setup>
import useCatchStore from '@/stores/modules/catch'
import { ROOT_DEPART_ID } from '@/enums/appEnums';
const data = ref([])
const props = defineProps({
showRoot: {
type: Boolean,
default: false
},
auth: {
type: Boolean,
default: true
}
})
const catchSotre = useCatchStore();
const departs = props.auth ? catchSotre.getDeparts() : catchSotre.getDepartsAll();
onMounted(() => {
getData()
})
watch(departs, () => {
getData()
})
function getData() {
if (!props.showRoot && departs.length && departs[0].id === ROOT_DEPART_ID) {
data.value = departs[0].children
} else {
data.value = departs
}
}
</script>
<style lang="scss" scoped>
</style>

61
src/components/description-pair.vue

@ -0,0 +1,61 @@
<template>
<div class="text-center description-value" :size="size">
<span v-if="value1">{{ value1 }}</span>
<span class="separator" v-if="value1">/</span>
<span class="value2">{{ value2 }}</span>
</div>
<div class="text-center description-label" :size="size">
<span v-if="value1">{{ label }}{{ label1 }}</span>
<span v-if="value1">/</span>
<span>{{ label }}{{ label2 }}</span>
</div>
</template>
<script setup>
defineProps({
label: {
type: String,
default: "",
},
label1: {
type: String,
default: "",
},
value1: {
type: Number,
default: "",
},
label2: {
type: String,
default: "",
},
value2: {
type: Number,
default: "",
},
size: {
type: String,
default: "",
}
});
</script>
<style lang="scss" scoped>
.description-value {
margin-bottom: 16px;
font-size: 18px;
color: var(--primary-color);
&[size=large] {
font-size: 28px;
}
.separator {
margin: 0 10px;
color: #666666;
}
.value2 {
color: #FF2B2B;
}
}
.description-label {
font-size: 16px;
color: #666666;
}
</style>

38
src/components/dict-select.vue

@ -0,0 +1,38 @@
<template>
<template v-if="select.includes(name)">
<el-select clearable>
<el-option
v-for="item in data[name]"
:key="item.id"
:label="item.dictLabel"
:value="item.dictValue"
/>
</el-select>
</template>
<template v-else-if="selectTree.includes(name)">
<el-tree-select :data="data" :props="{value: 'id'}" node-key="id" clearable filterable @node-click="(nodeData, node) => change(nodeData)" />
</template>
</template>
<script setup>
import useCatchStore from '@/stores/modules/catch'
const props = defineProps({
name: {
type: String,
required: true,
},
});
const emit = defineEmits(['change'])
const select = ["businessType", "suspectProblem", "processingStatus"];
const selectTree = ["problemSources"];
const catchStore = useCatchStore();
const data = select.includes(props.name) ? catchStore.getDicts([props.name]) : catchStore.getDictProblemSources()
function change(nodeData) {
emit('change', nodeData)
}
</script>
<style lang="scss" scoped>
</style>

31
src/components/el-form-item-ext.vue

@ -0,0 +1,31 @@
<template>
<el-form-item>
<template #label>
<div class="flex v-center gap-4">
<el-tooltip
effect="dark"
:content="content"
raw-content
placement="top"
>
<icon name="local-icon-question" :size="18" />
</el-tooltip>
<span>{{ label }}</span>
</div>
</template>
<slot></slot>
</el-form-item>
</template>
<script setup>
defineProps({
label: {
type: String,
default: "",
},
content: {
type: String,
},
});
</script>
<style lang="scss" scoped>
</style>

504
src/components/file/list.vue

@ -0,0 +1,504 @@
<template>
<div class="flex gap-12 wrap file-container">
<div v-for="(item, index) in files" :key="index" class="item pointer">
<template v-if="item.loading">
<el-progress
type="circle"
:percentage="item.percent"
:width="80"
color="var(--primary-color)"
></el-progress>
</template>
<template v-else-if="getFileType(item.fileName) === FileType.IMG">
<div
class="img-box"
:style="{
backgroundImage: `url(${BASE_PATH}/file/stream/${item.filePath})`,
}"
@click="filePreview(item)"
></div>
<a
class="remove-btn"
@click="remove(index)"
v-if="removeEnable"
>
<icon name="el-icon-CircleCloseFilled" :size="20" />
</a>
</template>
<div
class="item flex end v-center column text-center"
:title="item.fileName"
@click="filePreview(item)"
v-else
>
<icon :name="getIconName(item.fileName)" :size="40" />
<span class="filename">{{ item.fileName }}</span>
<a
class="remove-btn"
@click.stop="remove(index)"
v-if="removeEnable"
>
<icon name="el-icon-CircleCloseFilled" :size="16" />
</a>
</div>
</div>
</div>
<div class="file-preview-wrapper flex overlay" v-if="preview">
<el-scrollbar height="100vh">
<div class="file-list">
<section
v-for="(item, index) in files"
:key="index"
class="flex gap v-center pointer"
:active="files.indexOf(activeFile) === index"
@click="filePreview(item)"
>
<icon :name="getIconName(item.fileName)" :size="24" />
<span>{{ item.fileName }}</span>
</section>
</div>
</el-scrollbar>
<div class="file-content flex center v-center" @click="preview = false">
<div
class="img-container flex center"
v-if="getFileType(activeFile.fileName) === FileType.IMG"
@wheel="wheel"
>
<img
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
ref="imgRef"
@click.stop
:style="{
transform: `rotate(${rotate}deg) scale(${scale}) translate(${translateX}px, ${translateY}px)`,
}"
@mousedown="mousedown"
@mousemove="mousemove"
@mouseup="mouseup"
draggable="false"
/>
<button
class="rotate-left-btn pointer"
@click.stop.prevent="rotateLeft"
size="small"
title="左旋转"
>
<icon name="local-icon-rotate-left" :size="28" />
</button>
<button
class="rotate-right-btn pointer"
@click.stop.prevent="rotateRight"
size="small"
title="右旋转"
>
<icon name="local-icon-rotate-right" :size="28" />
</button>
</div>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.PDF"
>
<iframe
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
style="height: 100vh; width: 900px"
></iframe>
</template>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.MP3"
>
<audio controls style="width: 50vw">
<source
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
type="audio/mp3"
/>
</audio>
</template>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.MP4"
>
<video controls @click.stop style="max-height: 100vh">
<source
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
type="video/mp4"
/>
</video>
</template>
<template
v-else-if="getFileType(activeFile.fileName) === FileType.WORD"
>
<vue-office-docx
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
style="height: 100vh; width: 900px"
@error="fileRrror = true"
v-if="!fileRrror"
@click.stop
/>
<div v-else class="error flex column text-center">
<span style="padding: 20px"
>文件预览解析错误如有需要请下载到本地预览</span
>
</div>
</template>
<template
v-else-if="
getFileType(activeFile.fileName) === FileType.EXCEL &&
activeFile.fileName.toLocaleLowerCase().endsWith('.xlsx')
"
>
<vue-office-excel
:src="`${BASE_PATH}/file/stream/${activeFile.filePath}`"
style="height: 100vh; width: 60vw"
@error="fileRrror = true"
v-if="!fileRrror"
@click.stop
/>
<div v-else class="error flex column text-center">
<span style="padding: 20px"
>文件预览解析错误如有需要请下载到本地预览</span
>
</div>
</template>
<template v-else>
<div style="background: #fff">
<el-result
icon="error"
title="不支持预览"
sub-title="该文件格式暂不支持预览,请下载预览"
style="background: #fff; width: 600px; height: 400px"
@click.stop
>
<template #extra>
<el-button
type="primary"
text
size="large"
@click="download"
>下载文件</el-button
>
</template>
</el-result>
</div>
</template>
<div class="file-number" @click.stop>
<span
>{{ files.indexOf(activeFile) + 1 }} /
{{ files.length }}</span
>
</div>
<button
class="left-btn pointer"
@click.stop.prevent="prev"
v-if="files.length > 1"
>
<icon name="el-icon-ArrowLeftBold" :size="28" />
</button>
<button
class="right-btn pointer"
@click.stop.prevent="next"
v-if="files.length > 1"
>
<icon name="el-icon-ArrowRightBold" :size="28" />
</button>
</div>
<div class="close-btn"></div>
<button class="close-btn pointer" @click="preview = false">
<icon name="el-icon-Close" :size="28" />
</button>
<el-button class="download-btn" @click="download" type="primary" plain>
<template #icon>
<icon name="el-icon-Download" :size="20" />
</template>
下载文件
</el-button>
</div>
</template>
<script setup>
import { BASE_PATH } from "@/api/request";
import { FileType } from "@/enums/fileEnums";
import { getFileType, getIconName } from "@/utils/util";
import "@vue-office/docx/lib/index.css";
import "@vue-office/excel/lib/index.css";
import VueOfficeDocx from "@vue-office/docx";
import VueOfficeExcel from "@vue-office/excel";
const props = defineProps({
files: {
type: Array,
default: () => [],
},
removeEnable: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(["update:files"]);
const preview = ref(false);
const activeFile = ref({});
const rotate = ref(0);
const scale = ref(0);
const translateX = ref(0);
const translateY = ref(0);
let moveFlag = false;
let initialX = 0;
let initialY = 0;
const fileRrror = ref(false);
function filePreview(file) {
preview.value = true;
activeFile.value = file;
rotate.value = 0;
scale.value = 1;
translateX.value = 0;
translateY.value = 0;
moveFlag = false;
}
function remove(index) {
const files = [...props.files];
files.splice(index, 1);
emit("update:files", files);
}
function download() {
window.open(`${BASE_PATH}/file/stream/${activeFile.value.filePath}`);
}
function prev() {
const index = props.files.indexOf(activeFile.value);
if (index === 0) {
filePreview(props.files[props.files.length - 1]);
} else {
filePreview(props.files[index - 1]);
}
}
function next() {
const index = props.files.indexOf(activeFile.value);
if (index === props.files.length - 1) {
filePreview(props.files[0]);
} else {
filePreview(props.files[index + 1]);
}
}
function wheel(event) {
if (event.deltaY > 0 && scale.value > 0.5) {
scale.value -= 0.1;
}
if (event.deltaY < 0) {
scale.value += 0.1;
}
}
function mousedown() {
moveFlag = true;
initialX = event.clientX;
initialY = event.clientY;
}
function mousemove(event) {
if (!moveFlag) {
return;
}
if (rotate.value % 360 === 0) {
translateX.value += event.clientX - initialX;
translateY.value += event.clientY - initialY;
}
if (rotate.value === 90) {
translateY.value -= event.clientX - initialX;
translateX.value += event.clientY - initialY;
}
if (rotate.value === 180) {
translateX.value -= event.clientX - initialX;
translateY.value -= event.clientY - initialY;
}
if (rotate.value === 270) {
translateY.value += event.clientX - initialX;
translateX.value -= event.clientY - initialY;
}
initialX = event.clientX;
initialY = event.clientY;
}
function mouseup(event) {
moveFlag = false;
}
function rotateLeft() {
if (rotate.value === 360) {
rotate.value = 0;
} else {
rotate.value += 90;
}
}
function rotateRight() {
if (rotate.value === 0) {
rotate.value = 270;
} else {
rotate.value -= 90;
}
}
</script>
<style lang="scss" scoped>
.file-container {
min-height: 80px;
margin: 2px;
.item {
width: 80px;
height: 80px;
margin-bottom: 12px;
border-radius: 2px;
color: var(--primary-color);
position: relative;
&:hover {
background-color: #ededed;
span.filename {
font-weight: 700;
}
}
span.filename {
line-height: 1.2;
font-size: 12px;
width: 100%;
white-space: nowrap;
text-overflow: ellipsis;
margin-top: 10px;
overflow: hidden;
}
.img-box {
width: 80px;
height: 80px;
background-size: cover;
background-position: center;
border-radius: 2px;
&:hover {
outline: 2px solid #ff9800;
}
}
.remove-btn {
position: absolute;
top: -8px;
right: -8px;
display: block;
border-radius: 50%;
height: 16px;
background-color: #fff;
color: #666;
&:hover {
color: red;
cursor: pointer;
}
}
}
}
.file-preview-wrapper {
.file-list {
width: 15vw;
height: 100vh;
padding: 16px 8px;
background-color: #fff;
box-sizing: border-box;
section {
padding: 8px 16px;
border: 2px solid transparent;
background-color: #fff;
&:hover {
color: var(--primary-color);
font-weight: 700;
}
&[active="true"] {
border-color: var(--primary-color);
}
span {
width: calc(100% - 32px);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
}
.file-content {
width: 86vw;
position: relative;
.img-container {
height: 100vh;
img {
max-height: 100%;
display: block;
&:hover {
cursor: pointer;
}
}
}
.error {
background-color: #fff;
img {
width: 500px;
}
}
}
.close-btn {
position: absolute;
top: 12px;
right: 8px;
background-color: transparent;
border: none;
color: #fff;
&:hover {
color: red;
}
}
.rotate-left-btn {
position: absolute;
top: 12px;
right: 118px;
background-color: transparent;
border: none;
color: #fff;
}
.rotate-right-btn {
position: absolute;
top: 12px;
right: 68px;
background-color: transparent;
border: none;
color: #fff;
}
.left-btn {
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
background-color: transparent;
border: none;
color: #fff;
}
.right-btn {
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
background-color: transparent;
border: none;
color: #fff;
}
.download-btn {
position: absolute;
bottom: 20px;
right: 20px;
}
.file-number {
position: absolute;
top: 16px;
left: 18px;
color: #fff;
}
}
</style>

327
src/components/file/upload-group.vue

@ -0,0 +1,327 @@
<template>
<el-button @click="show = true"
>上传
<template #icon>
<icon name="el-icon-upload-filled" />
</template>
</el-button>
<el-dialog
title="上传佐证材料"
v-model="show"
width="60vw"
:close-on-click-modal="false"
top="2vh"
>
<el-upload
drag
multiple
:action="`${BASE_PATH}/file/upload`"
:headers="{ Authorization: getToken() }"
:before-upload="beforeUpload"
@progress="uploadProgress"
@success="handleSuccess"
@error="handleError"
:show-file-list="false"
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">
<div>将文件拖拽到此处或<em>点击上传</em></div>
<div class="text-small">文件类型支持图片/录音/MP4/PDF/WORD/EXCEL/压缩文件文件大小限制为 100MB</div>
<div class="text-small">如遇到无法正常上传的情况请将文件压缩之后再上传</div>
</div>
</el-upload>
<h4>未分类文件</h4>
<div style="min-height: 60px">
<div
class="flex between mb-10"
v-for="(item, index) in fileList.filter(
(item) => !item.fileClassId
)"
:key="index"
>
<div class="flex gap v-center">
<div v-if="!item.loading">
<template
v-if="getFileType(item.fileName) === FileType.IMG"
>
<div
class="img-box"
:style="{
backgroundImage: `url(${BASE_PATH}/file/stream/${item.filePath})`,
}"
@click="filePreview(item)"
></div>
</template>
<template v-else>
<icon
:name="getIconName(item.fileName)"
:size="40"
/>
</template>
</div>
<el-progress
type="circle"
:percentage="item.percent"
:width="40"
color="var(--primary-color)"
v-else
></el-progress>
<span>{{ item.fileName }}</span>
</div>
<div class="flex gap v-center">
<el-select
style="width: 200px"
v-model="item.classId"
clearable
v-if="fileClasss.length"
>
<el-option
v-for="item in fileClasss"
:value="item.id"
:label="item.classTitle"
:key="item"
/>
</el-select>
<el-button
type="primary"
plain
@click="handleUpdateFileClass(item)"
:disabled="!item.classId"
v-if="fileClasss.length"
>修改文件分类</el-button
>
<el-button type="danger" @click="remove(item)"
>删除文件</el-button
>
</div>
</div>
</div>
<div v-if="fileClasss.length">
<h4>已分类文件</h4>
<el-scrollbar max-height="400px">
<el-row :gutter="20">
<el-col
:span="12"
v-for="item in fileClasss"
:key="item"
class="file-class-item"
>
<header class="text-primary">
{{ item.classTitle }}
</header>
<div style="min-height: 60px">
<div
class="flex between mb-8 file-list-item file-list-item_active"
v-for="(item, index) in fileList.filter(
(file) => file.fileClassId === item.id
)"
:key="index"
>
<div class="flex gap v-center">
<div v-if="!item.loading">
<template
v-if="
getFileType(item.fileName) ===
FileType.IMG
"
>
<div
class="img-box"
:style="{
backgroundImage: `url(${BASE_PATH}/file/stream/${item.filePath})`,
}"
@click="filePreview(item)"
></div>
</template>
<template v-else>
<icon
:name="
getIconName(item.fileName)
"
:size="40"
/>
</template>
</div>
<el-progress
type="circle"
:percentage="item.percent"
:width="40"
color="var(--primary-color)"
v-else
></el-progress>
<span>{{ item.fileName }}</span>
</div>
<div class="flex gap v-center">
<el-button
type="info"
plain
@click="cancelFileClass(item)"
size="small"
>取消分类</el-button
>
<el-button
type="danger"
@click="remove(item)"
size="small"
>删除文件</el-button
>
</div>
</div>
</div>
</el-col>
</el-row>
</el-scrollbar>
</div>
<footer class="flex end mt-20">
<el-button type="primary" size="large" @click="handleSubmit"
>确认佐证材料</el-button
>
</footer>
</el-dialog>
</template>
<script setup>
import { getToken } from "@/utils/token";
import { BASE_PATH } from "@/api/request";
import feedback from "@/utils/feedback";
import { getIconName, getFileType } from "@/utils/util";
import { ProblemSources } from "@/enums/dictEnums";
import { FileType } from "@/enums/fileEnums";
const props = defineProps({
files: {
type: Array,
default: () => [],
},
problemSourcesCode: {
type: String,
default: "",
},
});
const emit = defineEmits(["update:files"]);
const show = ref(false);
const fileList = ref(props.files);
watch(() => props.files, (val => {
fileList.value = val
}))
const fileClasss = ref([]);
if (props.problemSourcesCode === ProblemSources.JWDC) {
fileClasss.value = [
{
id: 6,
classTitle: "处理反馈表",
classRemarks: "",
},
{
id: 1,
classTitle: "容错免责样本申请表",
classRemarks: "",
},
{
id: 2,
classTitle:
"针对群众不满意原因,提供无过错的音视频、微信或短信截图等证明资料",
classRemarks: "",
},
{
id: 3,
classTitle: "110、122接处警开始、结束及处置过程中的视频截图",
classRemarks: "",
},
{
id: 4,
classTitle: "自动回访不满意后所对的回访录音",
classRemarks: "",
},
{
id: 5,
classTitle: "单位/个人所做其他工作",
classRemarks: "",
},
];
}
function beforeUpload(file) {
fileList.value.push({
uid: file.uid,
percent: 0,
loading: true,
fileName: file.name,
});
}
function uploadProgress(progressEvent, file) {
const filterFiles = fileList.value.filter((item) => file.uid === item.uid);
if (filterFiles.length) {
filterFiles[0].percent = parseInt(progressEvent.percent);
}
}
function handleSuccess(data, file) {
if (data.code !== 200) {
feedback.msgError("上传失败!若重复上传失败请联系系统管理员");
fileList.value.splice(fileList.value.findIndex((item) => file.uid === item.uid), 1)
return;
}
const filterFiles = fileList.value.filter((item) => file.uid === item.uid);
if (filterFiles.length) {
filterFiles[0].fileName = data.data.fileName;
filterFiles[0].filePath = data.data.filePath;
filterFiles[0].loading = false;
}
}
function handleError(e) {
console.log(e);
feedback.msgError("上传失败!若重复上传失败请联系系统管理员");
}
function handleUpdateFileClass(item) {
item.fileClassId = item.classId;
}
function cancelFileClass(item) {
item.fileClassId = null;
}
function handleSubmit() {
emit(
"update:files",
fileList.value.filter((item) => item.filePath)
);
show.value = false;
}
function remove(item) {
fileList.value.splice(fileList.value.indexOf(item), 1);
}
</script>
<style lang="scss" scoped>
h4 {
margin-top: 20px;
margin-bottom: 10px;
}
.file-class-item {
margin-bottom: 20px;
header {
padding: 4px 0;
}
}
.file-list-item {
padding: 10px;
}
.file-list-item_active {
background: #f1f3ff;
}
.img-box {
width: 40px;
height: 40px;
background-position: center;
background-size: cover;
}
</style>

105
src/components/file/upload.vue

@ -0,0 +1,105 @@
<template>
<div>
<el-upload
:action="`${BASE_PATH}/file/upload`"
:headers="{ Authorization: getToken() }"
multiple
:before-upload="beforeUpload"
@progress="uploadProgress"
@success="handleSuccess"
@error="handleError"
:show-file-list="false"
class="mb-16"
>
<el-button
>上传
<template #icon>
<icon name="el-icon-upload-filled" />
</template>
</el-button>
<template #tip>
<div class="el-upload__tip">
{{ tips }}
</div>
</template>
</el-upload>
<file-list v-model:files="files" :removeEnable="true" />
</div>
</template>
<script setup>
import feedback from "@/utils/feedback";
import { getToken } from "@/utils/token";
import { BASE_PATH } from "@/api/request";
const props = defineProps({
files: {
type: Array,
default: () => [],
},
tips: {
type: String,
default: ''
}
});
const emit = defineEmits(["update:files"]);
const files = ref(props.files);
watch(
() => props.files,
(newValue) => {
if (newValue) {
files.value = newValue;
} else {
files.value = [];
}
}
);
watch(files, () => {
emit("update:files", files.value);
});
function beforeUpload(file) {
// 1024 * 1024 * 100 100MB
if (file.size >= 104857600) {
feedback.msgError('文件大小不能超过100MB');
return false;
}
files.value.push({
uid: file.uid,
percent: 0,
loading: true,
});
}
function uploadProgress(progressEvent, file) {
const filterFiles = files.value.filter((item) => file.uid === item.uid);
if (filterFiles.length) {
filterFiles[0].percent = parseInt(progressEvent.percent);
}
}
function handleSuccess(data, file) {
const filterFiles = files.value.filter((item) => file.uid === item.uid);
if (data.code !== 200) {
feedback.msgError(data.message);
files.value.splice(files.value.indexOf(filterFiles[0]), 1);
return;
}
if (filterFiles.length) {
filterFiles[0].fileName = data.data.fileName;
filterFiles[0].filePath = data.data.filePath;
filterFiles[0].loading = false;
console.log("file", filterFiles[0]);
}
emit("update:files", files.value);
}
function handleError(e, file) {
console.log(e, file);
feedback.msgError("上传失败!");
}
</script>

19
src/components/icon/index.ts

@ -0,0 +1,19 @@
import * as ElementPlusIcons from '@element-plus/icons-vue'
//@ts-ignore
import localIconsName from 'virtual:svg-icons-names'
export const LOCAL_ICON_PREFIX = 'local-icon-'
export const EL_ICON_PREFIX = 'el-icon-'
const elIconsName: string[] = []
for (const [, component] of Object.entries(ElementPlusIcons)) {
elIconsName.push(`${EL_ICON_PREFIX}${component.name}`)
}
export function getElementPlusIconNames() {
return elIconsName
}
export function getLocalIconNames() {
return localIconsName
}

53
src/components/icon/index.vue

@ -0,0 +1,53 @@
<script lang="ts">
import { createVNode } from 'vue'
import { ElIcon } from 'element-plus'
import { EL_ICON_PREFIX, LOCAL_ICON_PREFIX } from './index'
import svgIcon from './svg-icon.vue'
export default defineComponent({
name: 'Icon',
props: {
name: {
type: String,
required: true
},
size: {
type: [String, Number],
default: '14px'
},
color: {
type: String,
default: 'inherit'
}
},
setup(props) {
if (props.name && props.name.indexOf(EL_ICON_PREFIX) === 0) {
// el-icon
return () =>
createVNode(
ElIcon,
{
size: props.size,
color: props.color
},
() => [createVNode(resolveComponent(props.name.replace(EL_ICON_PREFIX, '')))]
)
}
if (props.name.indexOf(LOCAL_ICON_PREFIX) === 0) {
// icon
return () =>
h(
'i',
{
class: ['local-icon']
},
createVNode(svgIcon, { ...props })
)
}
}
})
</script>
<style scoped>
.local-icon {
display: flex;
}
</style>

182
src/components/icon/picker.vue

@ -0,0 +1,182 @@
<template>
<div class="icon-select">
<el-popover
trigger="contextmenu"
v-model:visible="state.popoverVisible"
:width="state.popoverWidth"
>
<div
@mouseover.stop="state.mouseoverSelect = true"
@mouseout.stop="state.mouseoverSelect = false"
>
<div>
<div class="flex between">
<div class="mb-3">请选择图标</div>
<div>
<span
v-for="(item, index) in iconTabsMap"
:key="index"
class="cursor-pointer text-sm ml-2"
:class="{
'text-primary': index == tabIndex
}"
@click="tabIndex = index"
>
{{ item.name }}
</span>
</div>
</div>
<div class="h-280">
<el-scrollbar>
<div class="flex flex-wrap">
<div v-for="item in iconNamesFliter" :key="item" class="m-1">
<el-button @click="handleSelect(item)">
<icon :name="item" :size="18" />
</el-button>
</div>
</div>
</el-scrollbar>
</div>
</div>
</div>
<template #reference>
<el-input
ref="inputRef"
v-model.trim="state.inputValue"
placeholder="搜索图标"
:autofocus="false"
:disabled="disabled"
@focus="handleFocus"
@blur="handleBlur"
clearable
>
<template #prepend>
<div class="flex items-center" v-if="modelValue">
<el-tooltip class="flex-1 w-20" :content="modelValue" placement="top">
<icon
class="mr-1"
:key="modelValue"
:name="modelValue"
:size="16"
/>
</el-tooltip>
</div>
<template v-else></template>
</template>
<template #append>
<el-button>
<icon name="el-icon-Close" :size="18" @click="handleClear" />
</el-button>
</template>
</el-input>
</template>
</el-popover>
</div>
</template>
<script lang="ts" setup>
import { getElementPlusIconNames, getLocalIconNames } from './index'
interface Props {
modelValue: string
disabled?: boolean
}
withDefaults(defineProps<Props>(), {
modelValue: '',
disabled: false
})
const emits = defineEmits<{
(e: 'update:modelValue', value: string): void
(e: 'change', value: string): void
}>()
const tabIndex = ref(0)
const iconTabsMap = [
{
name: 'element图标',
icons: getElementPlusIconNames()
},
{
name: '本地图标',
icons: getLocalIconNames()
}
]
const inputRef = shallowRef<InstanceType<typeof ElInput>>()
const state = reactive({
inputValue: '',
popoverVisible: false,
popoverWidth: 0,
mouseoverSelect: false,
inputFocus: false
})
// input
const handleFocus = () => {
state.inputFocus = state.popoverVisible = true
}
// input
const handleBlur = () => {
state.inputFocus = false
state.popoverVisible = state.mouseoverSelect
}
//
const handleSelect = (icon: string) => {
state.mouseoverSelect = state.popoverVisible = false
emits('update:modelValue', icon)
emits('change', icon)
}
//
const handleClear = () => {
emits('update:modelValue', '')
emits('change', '')
}
//
const iconNamesFliter = computed(() => {
const iconNames = iconTabsMap[tabIndex.value]?.icons ?? []
if (!state.inputValue) {
return iconNames
}
const inputValue = state.inputValue.toLowerCase()
return iconNames.filter((icon: string) => {
if (icon.toLowerCase().indexOf(inputValue) !== -1) {
return icon
}
})
})
// input
const getInputWidth = () => {
nextTick(() => {
const inputWidth = inputRef.value?.$el.offsetWidth
state.popoverWidth = inputWidth < 300 ? 300 : inputWidth
})
}
//body
// useEventListener(document.body, 'click', () => {
// state.popoverVisible = state.inputFocus || state.mouseoverSelect ? true : false
// })
watch(
() => state.popoverVisible,
async (value) => {
await nextTick()
if (value) {
inputRef.value?.focus()
} else {
inputRef.value?.blur()
}
}
)
onMounted(() => {
getInputWidth()
})
</script>

38
src/components/icon/svg-icon.vue

@ -0,0 +1,38 @@
<template>
<svg aria-hidden="true" :style="styles">
<use :xlink:href="symbolId" fill="currentColor" />
</svg>
</template>
<script lang="ts">
import { addUnit } from '@/utils/util'
import type { CSSProperties } from 'vue'
export default defineComponent({
props: {
name: {
type: String,
required: true
},
size: {
type: [Number, String],
default: 16
},
color: {
type: String,
default: 'inherit'
}
},
setup(props) {
const symbolId = computed(() => `#${props.name}`)
const styles = computed<CSSProperties>(() => {
return {
width: addUnit(props.size),
height: addUnit(props.size),
color: props.color
}
})
return { symbolId, styles }
}
})
</script>

43
src/components/loading.vue

@ -0,0 +1,43 @@
<template>
<div class="loading-wrapper flex center v-center" v-show="loading">
<div class="loading-box flex column v-center center">
<icon name="el-icon-Loading" :size="100" />
<div class="mt-8 loading-text">{{ loadingText }}</div>
</div>
</div>
</template>
<script setup>
defineProps({
loading: {
type: Boolean,
defalut: true
},
loadingText: {
type: String,
defalut: ''
}
})
</script>
<style lang="scss" scoped>
.loading-wrapper {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99999;
}
.loading-box {
width: 162px;
height: 162px;
background: #9D9DA0;
border-radius: 16px;
color: #ccc;
font-size: 16px;
}
.loading-text {
color: #fff;
}
</style>

93
src/components/negative/description.vue

@ -0,0 +1,93 @@
<template>
<div class="info-container">
<h3>问题信息</h3>
<div class="row">
<div class="col col-6">
<label>样本源头编号</label>
<span>{{ negative.originId }}</span>
</div>
<div class="col col-6">
<label>问题发现时间</label>
<span>{{ negative.discoveryTime }}</span>
</div>
<div class="col col-6" v-if="negative.happenTime">
<label>问题发生时间</label>
<span>{{ negative.happenTime }}</span>
</div>
<div class="col col-6">
<label>问题来源</label>
<span>{{ negative.problemSources }}</span>
</div>
</div>
<div class="row">
<div class="col col-6" v-if="negative.responderName">
<label>投诉反映人</label>
<span>{{ negative.responderName }}</span>
</div>
<div class="col col-6" v-if="negative.contactPhone">
<label>联系电话</label>
<span>{{ negative.contactPhone }}</span>
</div>
</div>
<div class="row">
<div class="col col-6" v-if="negative.specialSupervision">
<label>专项督察</label>
<span>{{ getDictLable(dict.specialSupervision, negative.specialSupervision) }}</span>
</div>
<div class="col col-6" v-if="negative.reportNumber">
<label>警情期数</label>
<span>{{ negative.reportNumber }}</span>
</div>
<div class="col col-6">
<label>业务类别</label>
<span>{{ negative.businessTypeName }}</span>
</div>
<div class="col col-6">
<label>涉及警种</label>
<span>{{ negative.policeTypeName || '/' }}</span>
</div>
<div class="col col-12">
<label>涉嫌问题</label>
<span>{{ getInvolveProblem(negative.involveProblem, dict.suspectProblem) || '/' }}</span>
</div>
</div>
<div class="row">
<div class="col col-12" v-if="negative.caseNumber">
<label>案件/警情编号</label>
<span>{{ negative.caseNumber }}</span>
</div>
<div class="col col-12">
<label>涉及单位</label>
<span>{{ negative.involveDepartName || '/' }}</span>
</div>
</div>
<div>
<div class="text-primary mt-10">事情简要描述</div>
<div class="content">{{ negative.thingDesc }}</div>
</div>
<div v-if="negative.thingFiles?.length">
<div class="text-primary mt-10 mb-10">附件</div>
<file-list :files="negative.thingFiles" />
</div>
</div>
</template>
<script setup>
import { getDictLable, getInvolveProblem } from "@/utils/util";
const negative = inject('negative')
import useCatchStore from "@/stores/modules/catch";
const catchSotre = useCatchStore();
const dict = catchSotre.getDicts([
"specialSupervision", "suspectProblem"
]);
</script>
<style lang="scss" scoped>
.info-container {
background: #F9FAFF;
box-shadow: 0px 2px 4px 0px rgba(133,150,248,0.47);
padding: 20px;
margin: 0 2px 4px 2px;
h3 {
margin-top: 0;
}
}
</style>

52
src/components/negative/sign-return-description.vue

@ -0,0 +1,52 @@
<template>
<div v-for="(item, index) in signReturns" :key="index">
<template v-if="index === 0 || expandFlag">
<div class="box">
<div class="flex mb-10">
<div class="flex v-center gap">
<icon
name="el-icon-Warning"
:size="20"
class="danger"
/>
<span class="danger">问题已退回</span>
<span>{{ item.handlerDepartName }}</span>
<span>{{ item.handlerName }}</span>
</div>
</div>
<div class="col">
<label class="mt-8">退回理由</label>
<div class="content">{{ item.comments }}</div>
</div>
<el-button type="primary" size="small" plain class="expand-btn" @click="expandFlag = !expandFlag" v-if="index === 0"
>{{ !expandFlag ? '展开' : '收起' }}</el-button
>
</div>
</template>
</div>
</template>
<script setup>
const signReturns = inject("signReturns");
const expandFlag = ref(false);
</script>
<style lang="scss" scoped>
.box {
border: 1px solid #ffe3e3;
padding: 16px;
margin-bottom: 12px;
position: relative;
.danger {
color: #ff1414;
font-weight: bold;
}
.content {
background-color: #feeded;
width: calc(100% - 100px);
}
}
.expand-btn {
position: absolute;
bottom: -12px;
right: 16px;
}
</style>

258
src/components/negative/verify-description.vue

@ -0,0 +1,258 @@
<template>
<el-collapse v-model="activeNames">
<el-collapse-item
title="核查办理"
name="verify"
v-if="negative.checkStatus"
>
<div class="row">
<div class="col col-6">
<label>核查情况</label>
<span>{{ negative.checkStatusName }}</span>
</div>
<div class="col col-6" v-if="negative.isRectifyName">
<label>是否整改</label>
<span>{{ negative.isRectifyName }}</span>
</div>
<div class="col col-6" v-if="negative.accountabilityTarget">
<label>追责对象</label>
<span>{{
getDictLable(
dict.accountabilityTarget,
negative.accountabilityTarget
)
}}</span>
</div>
<div class="col col-6" v-if="negative.rectifyRestrictionDays">
<label>整改限制</label>
<span>{{ `${negative.rectifyRestrictionDays}` }}</span>
</div>
</div>
<div class="row" v-if="negative.checkStatusDesc">
<div class="col col-24">
<label>问题核查情况</label>
<span>{{ negative.checkStatusDesc }}</span>
</div>
</div>
<div class="row" v-if="negative.rectifyDesc">
<div class="col col-24">
<label>问题整改情况</label>
<span>{{ negative.rectifyDesc }}</span>
</div>
</div>
</el-collapse-item>
<el-collapse-item
v-for="(blame, index) in negative.blames.filter(
(item) => item.type === BlameType.PERSONAL
)"
:key="index"
:title="`涉及人员${index + 1}`"
:name="`involved${index}`"
>
<div class="row">
<div class="col col-6">
<label>涉及人员姓名</label>
<span>{{ blame.blameName }} {{ blame.blameEmpNo }}</span>
</div>
<div class="col col-6">
<label>身份证</label>
<span>{{ blame.blameIdCode }}</span>
</div>
<div class="col col-6">
<label>人员属性</label>
<span>{{
getDictLable(dict.personType, blame.ivPersonTypeCode)
}}</span>
</div>
</div>
<div
class="row"
v-for="(problem, index) in blame.problems"
:key="index"
>
<div class="col col-24">
<label>问题类型{{ index + 1 }}</label>
<span
>{{ problem.oneLevelContent }} /
{{ problem.twoLevelContent }} /
{{ problem.threeLevelContent }}
{{ problem.threeLevelContent === '其他' && problem.threeLevelContentOther ? `(${problem.threeLevelContentOther})` : ''}}
</span
>
</div>
</div>
<div class="row">
<div class="col col-6" v-if="blame.responsibilityTypeName">
<label>责任类别</label>
<span>{{ blame.responsibilityTypeName }}</span>
</div>
<div class="col col-6" v-if="blame.subjectiveAspectCode">
<label>主观方面</label>
<span>{{ blame.subjectiveAspectName }}</span>
</div>
<div class="col col-6" v-if="blame.handleResultCode">
<label>处置结果</label>
<span>{{ blame.handleResultName }}</span>
</div>
<div class="col col-6" v-if="blame.superviseMeasuresCode">
<label>督察措施</label>
<span>{{ blame.superviseMeasuresName }}</span>
</div>
<div class="col col-6" v-if="blame.protectRightsName">
<label>维权容错</label>
<span>{{ blame.protectRightsName }}</span>
</div>
</div>
<div v-perms="['negative:score']">
<div
class="row"
v-for="item in negative.scorePolices.filter(
(item) => blame.blameIdCode === item.idCode
)"
:key="item"
>
<div class="col col-6">
<label>问题分值</label>
<span
style="color: var(--danger-color)"
class="text-bold"
>{{ item.score }}</span
>
</div>
<div class="col col-6">
<label>公式</label>
<span>{{ item.expression }}</span>
</div>
</div>
</div>
<div class="row" style="background: #f5f5f5">
<div class="col col-6">
<label>涉及领导姓名</label>
<span>{{ blame.leadName }} {{ blame.leadEmpNo }}</span>
</div>
<div class="col col-6">
<label>身份证</label>
<span>{{ blame.leadIdCode }}</span>
</div>
<div class="col col-6" v-if="blame.leadResponsibilityTypeName">
<label>责任类别</label>
<span>{{ blame.leadResponsibilityTypeName }}</span>
</div>
<div class="col col-6" v-if="blame.leadMeasuresCode">
<label>督察措施</label>
<span>{{ blame.leadMeasuresName }}</span>
</div>
<div class="col col-6" v-if="blame.leadHandleResultCode">
<label>处置结果</label>
<span>{{ blame.leadHandleResultName }}</span>
</div>
<div class="col col-6" v-if="blame.leadProtectRightsName">
<label>维权容错</label>
<span>{{ blame.leadProtectRightsName }}</span>
</div>
</div>
</el-collapse-item>
<el-collapse-item
v-for="(blame, index) in negative.blames.filter(
(item) => item.type === BlameType.DEPARTMENT
)"
:key="index"
:title="`涉及单位`"
:name="`involved_department`"
>
<div class="row">
<div class="col col-6">
<label>班子成员姓名</label>
<span>{{ blame.blameName }}</span>
</div>
<div class="col col-6">
<label>身份证号码</label>
<span>{{ blame.blameIdCode }}</span>
</div>
<div class="col col-6">
<label>人员属性</label>
<span>{{
getDictLable(dict.personType, blame.ivPersonTypeCode)
}}</span>
</div>
</div>
<div
class="row"
v-for="(problem, index) in blame.problems"
:key="index"
>
<div class="col col-24">
<label>问题类型{{ index + 1 }}</label>
<span
>{{ problem.oneLevelContent }} /
{{ problem.twoLevelContent }} /
{{ problem.threeLevelContent }}
{{ problem.threeLevelContent === '其他' && problem.threeLevelContentOther ? `(${problem.threeLevelContentOther})` : ''}}
</span
>
</div>
</div>
<div class="row">
<div class="col col-6" v-if="blame.subjectiveAspectCode">
<label>主观方面</label>
<span>{{ blame.subjectiveAspectName }}</span>
</div>
<div class="col col-6">
<label>责任类别</label>
<span>{{ blame.responsibilityTypeName }}</span>
</div>
<div class="col col-6" v-if="blame.handleResultCode">
<label>处置结果</label>
<span>{{ blame.handleResultName }}</span>
</div>
</div>
</el-collapse-item>
<el-collapse-item
title="办结佐证材料"
name="completionAttachment"
v-if="negative.files.length"
>
<file-list :files="negative.files" />
</el-collapse-item>
</el-collapse>
</template>
<script setup>
import { BlameType } from "@/enums/dictEnums";
import { ProcessingStatus } from "@/enums/flowEnums";
import { getDictLable } from "@/utils/util";
import useCatchStore from "@/stores/modules/catch";
const dict = useCatchStore().getDicts([
"accountabilityTarget",
"personType",
"verifySituation",
"verifyFileSituation",
]);
const activeNames = ref([
"verify",
"involved_department",
"completionAttachment",
"completed",
]);
const negative = inject("negative");
for (
let i = 0;
i <
negative.value.blames.filter((item) => item.type === BlameType.PERSONAL)
.length;
i++
) {
activeNames.value.push("involved" + i);
}
</script>
<style lang="scss" scoped>
.el-collapse {
--el-collapse-header-text-color: var(--primary-color);
--el-collapse-header-font-size: 16px;
}
</style>

1582
src/components/negative/verify.vue

File diff suppressed because it is too large Load Diff

93
src/components/police-select.vue

@ -0,0 +1,93 @@
<template>
<div class="flex gap">
<template v-if="props.hostLevel === HostLevel.FIRST">
<depart-tree-select v-model="departId" :auth="false" />
</template>
<el-select-v2
v-model="value"
:options="polices"
placeholder="请选择"
style="width: 240px"
:props="{ label: 'name', value: 'empNo' }"
filterable
clearable
@change="onChange"
>
<template #default="{ item }">
<span class="mr-8">{{ item.name }}</span>
<span style="color: #999; font-size: 12px" class="mr-8">{{
item.empNo
}}</span>
<el-tag size="small" v-if="item.position">{{
item.position
}}</el-tag>
</template>
</el-select-v2>
</div>
</template>
<script setup>
import { listPoliceAll, listPoliceLeader } from "@/api/system/police";
import { HostLevel } from "@/enums/dictEnums";
const props = defineProps({
modelValue: {
type: String,
},
hostLevel: {
type: String,
default: HostLevel.THREE,
},
departId: {
type: String,
required: true,
},
isLeader: {
type: Boolean,
default: false,
},
disabldKeys: {
type: Array,
default: [],
},
});
const emit = defineEmits("update:modelValue", "change");
const value = ref(props.modelValue);
const departId = ref(props.departId);
const polices = ref([]);
getPolices();
watch(value, (val) => {
emit("update:modelValue", val);
});
watch(departId, () => {
getPolices();
});
async function getPolices() {
if (departId.value) {
if (props.isLeader) {
polices.value = await listPoliceLeader(departId.value);
} else {
polices.value = await listPoliceAll(departId.value);
}
}
}
watch(
() => props.disabldKeys,
() => {
polices.value.forEach((item) => {
item.disabled = props.disabldKeys.includes(item.empNo);
});
}
);
function onChange(val) {
emit("change", polices.value.filter((item) => item.empNo === val)[0]);
}
</script>
<style lang="scss" scoped>
</style>

44
src/components/problem-type-select.vue

@ -0,0 +1,44 @@
<template>
<el-tree-select
v-model="value"
:data="dictContent"
:props="{
label: 'name',
value: 'code',
}"
node-key="code"
clearable
filterable
accordion
style="width: 320px"
@current-change="handleChange"
/>
</template>
<script setup>
import useCatchStore from "@/stores/modules/catch";
const catchSotre = useCatchStore();
const dictContent = catchSotre.getDictContent();
const props = defineProps({
modelValue: {
type: String,
default: ''
},
});
const emit = defineEmits(["update:modelValue", "change"]);
const value = ref(props.modelValue);
watch(() => props.modelValue, (val) => {
value.value = val;
});
watch(value, (val) => {
emit("update:modelValue", val);
});
function handleChange(nodeData, node) {
emit("change", node);
}
</script>
<style lang="scss" scoped>
</style>

21
src/enums/appEnums.ts

@ -0,0 +1,21 @@
// 菜单类型
export enum MenuEnum {
CATALOGUE = 'M',
MENU = 'C',
BUTTON = 'A'
}
export const MENU_ROOT_ID = 0;
export const DICT_CONTENT_ROOT_ID = '-1';
// 部门跟节点
export const ROOT_DEPART_ID = '12630';
// 状态
export enum Status {
ENABLE = '1',
DISABLE = '0'
}
export const WEEKS = ["一", "二", "三", "四", "五", "六", "日"];

136
src/enums/dictEnums.ts

@ -0,0 +1,136 @@
// 核查情况
export enum InspectCase {
// 属实
TRUE = '1',
// 部分属实
PARTIALLY_TRUE = '2',
// 不属实
FALSE = '3',
// 无法办理
UNABLE = '4'
}
// 是否整改
export enum IsRectify {
NOT = '0',
YES = '1'
}
// 追责对象
export enum AccountabilityTarget {
PERSONAL = '1',
DEPARTMENT = '2',
PERSONAL_AND_DEPARTMENT = '3'
}
// 涉及类型
export enum BlameType {
PERSONAL = "personal",
DEPARTMENT = "department",
}
// 帮扶情况
export enum AssistCase {
YES = "1",
NO = "2",
}
// 问题来源
export enum ProblemSources {
// 警务评议
JWDC = '2',
// 警意调查
JYDC = '3',
// 执法监督
JFZD = '4',
// 监督管理
JDGL = '10',
// 国家信访平台
GJXFPT = '21',
// 公安部信访
GABXF = '22',
// 局长信箱
JZXX = '23',
// 12337信访
XF12337 = '24',
XCDC = '13',
// 专项督察
ZXDC = '15',
// 现场督察
// 其他
XF_QT = '25'
}
export const ProblemSources_XFTS = [ProblemSources.GJXFPT, ProblemSources.GABXF, ProblemSources.JZXX, ProblemSources.XF12337, ProblemSources.XF_QT]
// 主办层级
export enum HostLevel {
FIRST = '1',
SECOND = '2',
THREE = '3'
}
// 审批流程
export enum ApprovalFlow {
SECOND = '2',
THREE = '3'
}
// 办理时限
export enum TimeLimit {
// 137工作制
WORK_137 = '3+7',
// 10+10工作制
WORK_10_10 = '10+7',
// 14+7工作制
WORK_14_7 = '14+7',
// 其他
OTHER = 'other'
}
// 人员属性
export enum PersonType {
// 民警
POLICE = '1',
// 职工
WORKERS = '2',
// 辅警
ASSISTANT_POLICE = '3',
// 文员
CLERK = '4',
// 协警
AUXILIARY_POLICE = '5'
}
// 主观方面
export enum SubjectiveAspect {
OTHER = '3'
}
// 分发方式
export enum DistributionMethod {
DIRECTLY_DISTRIBUTE = '1',
MANUALLY_DISTRIBUTE = '2'
}
// 分发周期
export enum DistributionCycle {
DAY = 'day',
WEEKLY = 'weekly'
}
export enum ModelDataType {
NEGATIVE = '1',
NOTIFICATION = '2'
}
export enum DistributionState {
UNDISTRIBUTED = '0',
DISTRIBUTED = '1',
HANDLED = '2'
}

9
src/enums/fileEnums.ts

@ -0,0 +1,9 @@
// 文件类型
export enum FileType {
PDF = 'pdf',
IMG = 'img',
WORD = 'word',
EXCEL = 'excel',
MP3 = 'mp3',
Mp4 = 'mp4',
}

36
src/enums/flowEnums.ts

@ -0,0 +1,36 @@
// 流程节点
export enum FlowNodeEnum {
FIRST_DISTRIBUTE = 'first_distribute',
SECOND_SIGN = 'second_sign',
SECOND_DISTRIBUTE = 'second_distribute',
THREE_SIGN = 'three_sign',
VERIFY = 'verify',
SECOND_APPROVE = 'second_approve',
FIRST_APPROVE = 'first_approve',
SECOND_EXTENSION_APPROVE = 'second_extension_approve',
FIRST_EXTENSION_APPROVE = 'first_extension_approve',
COUNTERSIGN = 'countersign',
COMPLETED = 'completed'
}
// 流程操作
export enum FlowActionEnum {
APPLY_COMPLETION = 'apply_completion',
APPLY_EXTENSION = 'apply_extension',
THREE_SIGN_RETURN = 'three_sign_return',
SAVE = 'save'
}
// 审批状态
export enum ApproveState {
APPROVED = 'approved',
REJECTED = 'rejected'
}
// 办理状态
export enum ProcessingStatus {
SIGNING = 'signing',
PROCESSING = 'processing',
APPROVAL = 'approval',
COMPLETED = 'completed',
}

5
src/enums/pageEnum.ts

@ -0,0 +1,5 @@
export enum PageEnum {
//登录页面
LOGIN = '/login',
INDEX = '/'
}

28
src/install/directives/perms.ts

@ -0,0 +1,28 @@
/**
* perm
*
* <el-button v-perms="['auth.menu/edit']"></el-button>
*/
import useUserStore from '@/stores/modules/user'
export default {
mounted: (el: HTMLElement, binding: any) => {
const { value } = binding
const userStore = useUserStore()
const permissions = userStore.perms
const all_permission = '*'
if (Array.isArray(value)) {
if (value.length > 0) {
const hasPermission = permissions.some((key: string) => {
return all_permission == key || value.includes(key)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
}
} else {
throw new Error('like v-perms="[\'auth.menu/edit\']"')
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save