Browse Source

初次提交

master
肖正 3 weeks ago
commit
7b17b69f42
  1. 24
      .gitignore
  2. 3
      .vscode/extensions.json
  3. 9
      README.md
  4. 9
      auto-imports.d.ts
  5. 18
      components.d.ts
  6. BIN
      hukou.zip
  7. BIN
      hukou/assets/DS-DIGIT-Bz4sH1xK.TTF
  8. BIN
      hukou/assets/bg-Ca7X2M0b.jpg
  9. BIN
      hukou/assets/bg1-B6_C6NJE.png
  10. BIN
      hukou/assets/btn1-CRKIxnkF.png
  11. BIN
      hukou/assets/btn2-B0GpvJoC.png
  12. BIN
      hukou/assets/eath-CHEjiCYl.png
  13. BIN
      hukou/assets/headcenter-Njohw23C.png
  14. BIN
      hukou/assets/headleft-BoeOVS0y.png
  15. BIN
      hukou/assets/headright-C5bcIe9i.png
  16. 1
      hukou/assets/home-DXVefj4c.css
  17. 28
      hukou/assets/home-QKeLYwBm.js
  18. 19
      hukou/assets/home-legacy-CEa2V95L.js
  19. BIN
      hukou/assets/icon1-DzZ3EAAm.png
  20. BIN
      hukou/assets/icon2-TfyNJkmG.png
  21. BIN
      hukou/assets/icon3-CVEMzhGp.png
  22. BIN
      hukou/assets/icon4-BG4veA_t.png
  23. BIN
      hukou/assets/iconbg-un2BVcht.png
  24. 22
      hukou/assets/index-DOfL5DGB.js
  25. 13
      hukou/assets/index-legacy-BceoyPKk.js
  26. BIN
      hukou/assets/line1-B71bjm7p.png
  27. BIN
      hukou/assets/line2-BHsY8Ivs.png
  28. BIN
      hukou/assets/line3-CtTb4JFW.png
  29. BIN
      hukou/assets/line4-CEdqVrZG.png
  30. BIN
      hukou/assets/line5-CHX4vXjx.png
  31. BIN
      hukou/assets/line6-CbecP0qS.png
  32. BIN
      hukou/assets/line7-CDANFz2y.png
  33. 1
      hukou/assets/polyfills-legacy-BoP4WWJT.js
  34. 18
      hukou/index.html
  35. 1
      hukou/vite.svg
  36. 13
      index.html
  37. 7649
      package-lock.json
  38. 38
      package.json
  39. 1
      public/vite.svg
  40. 13
      src/App.vue
  41. 207
      src/api/request.ts
  42. 58
      src/api/storage.ts
  43. 18
      src/api/user.ts
  44. 40
      src/assets/font/DIGITAL.TXT
  45. BIN
      src/assets/font/DS-DIGI.TTF
  46. BIN
      src/assets/font/DS-DIGIB.TTF
  47. BIN
      src/assets/font/DS-DIGII.TTF
  48. BIN
      src/assets/font/DS-DIGIT.TTF
  49. BIN
      src/assets/img/bg.jpg
  50. BIN
      src/assets/img/bg1.png
  51. BIN
      src/assets/img/btn1.png
  52. BIN
      src/assets/img/btn2.png
  53. BIN
      src/assets/img/data_bg.png
  54. BIN
      src/assets/img/eath.png
  55. BIN
      src/assets/img/headcenter.png
  56. BIN
      src/assets/img/headleft.png
  57. BIN
      src/assets/img/headright.png
  58. BIN
      src/assets/img/icon1.png
  59. BIN
      src/assets/img/icon2.png
  60. BIN
      src/assets/img/icon3.png
  61. BIN
      src/assets/img/icon4.png
  62. BIN
      src/assets/img/iconbg.png
  63. BIN
      src/assets/img/icondown.png
  64. BIN
      src/assets/img/iconup.png
  65. BIN
      src/assets/img/line01.png
  66. BIN
      src/assets/img/line02.png
  67. BIN
      src/assets/img/line1.png
  68. BIN
      src/assets/img/line2.png
  69. BIN
      src/assets/img/line3.png
  70. BIN
      src/assets/img/line4.png
  71. BIN
      src/assets/img/line5.png
  72. BIN
      src/assets/img/line6.png
  73. BIN
      src/assets/img/line7.png
  74. BIN
      src/assets/img/man.png
  75. BIN
      src/assets/img/man_cld.png
  76. BIN
      src/assets/img/pattern.png
  77. BIN
      src/assets/img/weight.png
  78. BIN
      src/assets/img/woman.png
  79. BIN
      src/assets/img/woman_cld.png
  80. 38
      src/components/HelloWorld.vue
  81. 5
      src/main.ts
  82. 22
      src/router/index.ts
  83. 331
      src/views/cancer.vue
  84. 251
      src/views/countFlop.vue
  85. 129
      src/views/gene.vue
  86. 615
      src/views/home.vue
  87. 77
      src/views/hospital.vue
  88. 57189
      src/views/map.json
  89. 207
      src/views/people.vue
  90. 236
      src/views/style.css
  91. 217
      src/views/test.vue
  92. 450
      src/views/townDialog.vue
  93. 1
      src/vite-env.d.ts
  94. 32
      tsconfig.json
  95. 11
      tsconfig.node.json
  96. 56
      vite.config.ts
  97. 4337
      yarn.lock

24
.gitignore

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

3
.vscode/extensions.json

@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}

9
README.md

@ -0,0 +1,9 @@
# Vue 3 + TypeScript + Vite
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
## Recommended Setup
- [VS Code](https://code.visualstudio.com/) + [Vue - Official](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (previously Volar) and disable Vetur
- Use [vue-tsc](https://github.com/vuejs/language-tools/tree/master/packages/tsc) for performing the same type checking from the command line, or for generating d.ts files for SFCs.

9
auto-imports.d.ts

@ -0,0 +1,9 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
export {}
declare global {
}

18
components.d.ts

@ -0,0 +1,18 @@
/* eslint-disable */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
export {}
/* prettier-ignore */
declare module 'vue' {
export interface GlobalComponents {
ElCol: typeof import('element-plus/es')['ElCol']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRow: typeof import('element-plus/es')['ElRow']
HelloWorld: typeof import('./src/components/HelloWorld.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

BIN
hukou.zip

Binary file not shown.

BIN
hukou/assets/DS-DIGIT-Bz4sH1xK.TTF

Binary file not shown.

BIN
hukou/assets/bg-Ca7X2M0b.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

BIN
hukou/assets/bg1-B6_C6NJE.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
hukou/assets/btn1-CRKIxnkF.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
hukou/assets/btn2-B0GpvJoC.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
hukou/assets/eath-CHEjiCYl.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

BIN
hukou/assets/headcenter-Njohw23C.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
hukou/assets/headleft-BoeOVS0y.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
hukou/assets/headright-C5bcIe9i.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

1
hukou/assets/home-DXVefj4c.css

File diff suppressed because one or more lines are too long

28
hukou/assets/home-QKeLYwBm.js

File diff suppressed because one or more lines are too long

19
hukou/assets/home-legacy-CEa2V95L.js

File diff suppressed because one or more lines are too long

BIN
hukou/assets/icon1-DzZ3EAAm.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
hukou/assets/icon2-TfyNJkmG.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
hukou/assets/icon3-CVEMzhGp.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
hukou/assets/icon4-BG4veA_t.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
hukou/assets/iconbg-un2BVcht.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

22
hukou/assets/index-DOfL5DGB.js

File diff suppressed because one or more lines are too long

13
hukou/assets/index-legacy-BceoyPKk.js

File diff suppressed because one or more lines are too long

BIN
hukou/assets/line1-B71bjm7p.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
hukou/assets/line2-BHsY8Ivs.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
hukou/assets/line3-CtTb4JFW.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
hukou/assets/line4-CEdqVrZG.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
hukou/assets/line5-CHX4vXjx.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
hukou/assets/line6-CbecP0qS.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
hukou/assets/line7-CDANFz2y.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

1
hukou/assets/polyfills-legacy-BoP4WWJT.js

File diff suppressed because one or more lines are too long

18
hukou/index.html

@ -0,0 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="./vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
<script type="module" crossorigin src="./assets/index-DOfL5DGB.js"></script>
<script type="module">import.meta.url;import("_").catch(()=>1);(async function*(){})().next();if(location.protocol!="file:"){window.__vite_is_modern_browser=true}</script>
<script type="module">!function(){if(window.__vite_is_modern_browser)return;console.warn("vite: loading legacy chunks, syntax error above and the same error below should be ignored");var e=document.getElementById("vite-legacy-polyfill"),n=document.createElement("script");n.src=e.src,n.onload=function(){System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))},document.body.appendChild(n)}();</script>
</head>
<body>
<div id="app"></div>
<script nomodule>!function(){var e=document,t=e.createElement("script");if(!("noModule"in t)&&"onbeforeload"in t){var n=!1;e.addEventListener("beforeload",(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute("nomodule")||!n)return;e.preventDefault()}),!0),t.type="module",t.src=".",e.head.appendChild(t),t.remove()}}();</script>
<script nomodule crossorigin id="vite-legacy-polyfill" src="./assets/polyfills-legacy-BoP4WWJT.js"></script>
<script nomodule crossorigin id="vite-legacy-entry" data-src="./assets/index-legacy-BceoyPKk.js">System.import(document.getElementById('vite-legacy-entry').getAttribute('data-src'))</script>
</body>
</html>

1
hukou/vite.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

13
index.html

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

7649
package-lock.json

File diff suppressed because it is too large

38
package.json

@ -0,0 +1,38 @@
{
"name": "hukou",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview",
"build:no-vue-tsc": "vite build"
},
"dependencies": {
"axios": "^1.7.2",
"echarts": "^5.5.1",
"echarts-gl": "^2.0.9",
"echarts-wordcloud": "^2.1.0",
"element-plus": "^2.7.5",
"element-ui": "^2.15.14",
"vue": "^3.4.21",
"vue-count-to": "^1.0.13",
"vue-router": "^4.3.2",
"vue3-seamless-scroll": "^2.0.1"
},
"devDependencies": {
"@types/node": "^20.14.2",
"@vitejs/plugin-legacy": "^5.4.1",
"@vitejs/plugin-vue": "^5.0.4",
"less": "^4.2.0",
"terser": "^5.31.1",
"typescript": "^5.2.2",
"unplugin-auto-import": "^0.17.6",
"unplugin-vue-components": "^0.27.0",
"vite": "^5.2.12",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-windicss": "^1.9.3",
"vue-tsc": "^2.0.6"
}
}

1
public/vite.svg

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

13
src/App.vue

@ -0,0 +1,13 @@
<script setup lang="ts">
</script>
<template>
<div>
<router-view></router-view>
</div>
</template>
<style>
</style>
<style scoped>
</style>

207
src/api/request.ts

@ -0,0 +1,207 @@
import axios, { AxiosInstance } from 'axios';
import { ElMessage } from 'element-plus';
import { Local, Session } from './storage';
// 配置新建一个 axios 实例
export const service = axios.create({
baseURL: 'http://127.0.0.1:5000',
timeout: 10000,
headers: { 'Content-Type': 'application/json' },
})
// token 键定义
export const accessTokenKey = 'access-token';
export const refreshAccessTokenKey = `x-${accessTokenKey}`;
// 获取 token
export const getToken = () => {
return Local.get(accessTokenKey);
};
// 清除 token
export const clearAccessTokens = () => {
Local.remove(accessTokenKey);
Local.remove(refreshAccessTokenKey);
// 清除其他
Session.clear();
// 刷新浏览器
window.location.reload();
};
// axios 默认实例
export const axiosInstance: AxiosInstance = axios;
// 添加请求拦截器
service.interceptors.request.use(
(config: any) => {
// // 在发送请求之前做些什么 token
// if (Session.get('token')) {
// (<any>config.headers).common['Authorization'] = `${Session.get('token')}`;
// }
// 获取本地的 token
const accessToken = Local.get(accessTokenKey);
if (accessToken) {
// 将 token 添加到请求报文头中
config.headers!['Authorization'] = `Bearer ${accessToken}`;
// 判断 accessToken 是否过期
const jwt: any = decryptJWT(accessToken);
const exp = getJWTDate(jwt.exp as number);
// token 已经过期
if (new Date() >= exp) {
// 获取刷新 token
const refreshAccessToken = Local.get(refreshAccessTokenKey);
// 携带刷新 token
if (refreshAccessToken) {
config.headers!['X-Authorization'] = `Bearer ${refreshAccessToken}`;
}
}
// debugger
// get请求映射params参数
if (config.method?.toLowerCase() === 'get' && config.data) {
let url = config.url + '?' + tansParams(config.data);
url = url.slice(0, -1);
config.data = {};
config.url = url;
}
}
return config;
},
(error: any) => {
// 对请求错误做些什么
return Promise.reject(error);
}
);
// 添加响应拦截器
service.interceptors.response.use(
(res: any) => {
// 获取状态码和返回数据
var status = res.status;
var serve = res.data;
// 处理 401
if (status === 401) {
clearAccessTokens();
}
// 处理未进行规范化处理的
if (status >= 400) {
throw new Error(res.statusText || 'Request Error.');
}
// 处理规范化结果错误
if (serve && serve.hasOwnProperty('errors') && serve.errors) {
throw new Error(JSON.stringify(serve.errors || 'Request Error.'));
}
// 读取响应报文头 token 信息
var accessToken = res.headers[accessTokenKey];
var refreshAccessToken = res.headers[refreshAccessTokenKey];
// 判断是否是无效 token
if (accessToken === 'invalid_token') {
clearAccessTokens();
}
// 判断是否存在刷新 token,如果存在则存储在本地
else if (refreshAccessToken && accessToken && accessToken !== 'invalid_token') {
Local.set(accessTokenKey, accessToken);
Local.set(refreshAccessTokenKey, refreshAccessToken);
}
// 响应拦截及自定义处理
if (serve.code === 401) {
clearAccessTokens();
} else if (serve.code === undefined) {
return Promise.resolve(res);
} else if (serve.code !== 200) {
var message;
// 判断 serve.message 是否为对象
if (serve.message && typeof serve.message == 'object') {
message = JSON.stringify(serve.message);
} else {
message = serve.message;
}
ElMessage.error(message);
throw new Error(message);
}
return res;
},
(error: any) => {
// 处理响应错误
if (error.response) {
if (error.response.status === 401) {
clearAccessTokens();
}
}
// console.log(99, error)
// 对响应错误做点什么
if (error.message.indexOf('timeout') != -1) {
ElMessage.error('网络超时');
} else if (error.message == 'Network Error') {
ElMessage.error('网络连接错误');
} else {
if (error) ElMessage.error(error);
else ElMessage.error('接口路径找不到');
}
return Promise.reject(error);
}
);
/**
*
* @param {*} params
*/
export function tansParams(params: any) {
let result = '';
for (const propName of Object.keys(params)) {
const value = params[propName];
var part = encodeURIComponent(propName) + '=';
if (value !== null && value !== '' && typeof value !== 'undefined') {
if (typeof value === 'object') {
for (const key of Object.keys(value)) {
if (value[key] !== null && value[key] !== '' && typeof value[key] !== 'undefined') {
let params = propName + '[' + key + ']';
var subPart = encodeURIComponent(params) + '=';
result += subPart + encodeURIComponent(value[key]) + '&';
}
}
} else {
result += part + encodeURIComponent(value) + '&';
}
}
}
return result;
}
/**
* JWT token
* @param token jwt token
* @returns <any>object
*/
export function decryptJWT(token: string): any {
token = token.replace(/_/g, '/').replace(/-/g, '+');
var json = decodeURIComponent(escape(window.atob(token.split('.')[1])));
return JSON.parse(json);
}
/**
* JWT Date
* @description `exp``iat``nbf`
* @param timestamp
* @returns Date
*/
export function getJWTDate(timestamp: number): Date {
return new Date(timestamp * 1000);
}
// 导出 axios 实例
export default service;

58
src/api/storage.ts

@ -0,0 +1,58 @@
/**
* window.localStorage
* @method set
* @method get
* @method remove
* @method clear
*/
export const Local = {
// 查看 v2.4.3版本更新日志
setKey(key: string) {
// @ts-ignore
return `${key}`;
},
// 设置永久缓存
set<T>(key: string, val: T) {
window.localStorage.setItem(Local.setKey(key), JSON.stringify(val));
},
// 获取永久缓存
get(key: string) {
let json = <string>window.localStorage.getItem(Local.setKey(key));
return JSON.parse(json);
},
// 移除永久缓存
remove(key: string) {
window.localStorage.removeItem(Local.setKey(key));
},
// 移除全部永久缓存
clear() {
window.localStorage.clear();
},
};
/**
* window.sessionStorage
* @method set
* @method get
* @method remove
* @method clear
*/
export const Session = {
// 设置临时缓存
set<T>(key: string, val: T) {
window.sessionStorage.setItem(Local.setKey(key), JSON.stringify(val));
},
// 获取临时缓存
get(key: string) {
let json = <string>window.sessionStorage.getItem(Local.setKey(key));
return JSON.parse(json);
},
// 移除临时缓存
remove(key: string) {
window.sessionStorage.removeItem(Local.setKey(key));
},
// 移除全部临时缓存
clear() {
window.sessionStorage.clear();
},
};

18
src/api/user.ts

@ -0,0 +1,18 @@
import request from './request';
// import type { ResultData } from './common';
export function getInfo(data: any) {
return request({
url: '/api/data',
method: 'post',
data,
});
}
// export function list(params: any) {
// return request({
// eslint-disable-next-line no-irregular-whitespace
//       url: "/list",
// method: "get",
// params,
// });
// }

40
src/assets/font/DIGITAL.TXT

@ -0,0 +1,40 @@
DS-Font's TrueType Fonts
Font name: DS-Digital (Normal, Bold, Italic, Bold Italic), Version 1.0
Author: Dusit Supasawat
Web Site: http://ds-font.hypermart.net
Contact me: Dusit Supasawat, 325/38 Suksawat32 Ratburana Bangkok Thailand 10140
Email address: dusit@mailcity.com
Thanks for trying! We hope you really enjoy this my typeface. This font is
distributed as shareware. You can use this font for a long time as you want.
After all, when you think this font can be usefulness for you. You can send
me some money, that would be way cool.
I'm only asking $20 US shareware fee per this typeface for personal use.
And $45 US is the usual amount per this typeface for commercial use.
Distribution: You are free to distribute this archive so long as this text
file is distributed with the archive, the font file have not been modified,
and it is understood that the font's copyright remains with the original
author (Dusit Supasawat).
To register send your payment to:
Dusit Supasawat
325/38 Suksawat32 Ratburana
Bangkok Thailand 10140
And fill out something as this order form, and send it in with your payment.
Font name:_________________________________________
Your information
Name:______________________________________________
Address:___________________________________________
City, State : _____________________________________
Zip Code:__________________________________________
Country:___________________________________________
E-MAIL address:____________________________________
You will receive fonts which you order by Email after registration. These fonts
will be generated for you by specify your name in font information.

BIN
src/assets/font/DS-DIGI.TTF

Binary file not shown.

BIN
src/assets/font/DS-DIGIB.TTF

Binary file not shown.

BIN
src/assets/font/DS-DIGII.TTF

Binary file not shown.

BIN
src/assets/font/DS-DIGIT.TTF

Binary file not shown.

BIN
src/assets/img/bg.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 KiB

BIN
src/assets/img/bg1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

BIN
src/assets/img/btn1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

BIN
src/assets/img/btn2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
src/assets/img/data_bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/assets/img/eath.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

BIN
src/assets/img/headcenter.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
src/assets/img/headleft.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
src/assets/img/headright.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
src/assets/img/icon1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
src/assets/img/icon2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/assets/img/icon3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
src/assets/img/icon4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
src/assets/img/iconbg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

BIN
src/assets/img/icondown.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

BIN
src/assets/img/iconup.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 647 B

BIN
src/assets/img/line01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
src/assets/img/line02.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/assets/img/line1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/img/line2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/assets/img/line3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
src/assets/img/line4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/assets/img/line5.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/assets/img/line6.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/assets/img/line7.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/assets/img/man.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/assets/img/man_cld.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
src/assets/img/pattern.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
src/assets/img/weight.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
src/assets/img/woman.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/assets/img/woman_cld.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

38
src/components/HelloWorld.vue

@ -0,0 +1,38 @@
<script setup lang="ts">
import { ref } from 'vue'
defineProps<{ msg: string }>()
const count = ref(0)
</script>
<template>
<h1>{{ msg }}</h1>
<div class="card">
<button type="button" @click="count++">count is {{ count }}</button>
<p>
Edit
<code>components/HelloWorld.vue</code> to test HMR
</p>
</div>
<p>
Check out
<a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
>create-vue</a
>, the official Vue + Vite starter
</p>
<p>
Install
<a href="https://github.com/vuejs/language-tools" target="_blank">Volar</a>
in your IDE for a better DX
</p>
<p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
</style>

5
src/main.ts

@ -0,0 +1,5 @@
import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')

22
src/router/index.ts

@ -0,0 +1,22 @@
import { createRouter, createWebHashHistory } from "vue-router";
const routes = [
{
path: '/',
name: 'home',
component: () =>
import(/* webpackChunkName: "about" */ '../views/home.vue'),
},
{
path: '/test',
name: 'test',
component: () =>
import(/* webpackChunkName: "about" */ '../views/test.vue'),
},
]
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes,
});
export default router;

331
src/views/cancer.vue

File diff suppressed because one or more lines are too long

251
src/views/countFlop.vue

@ -0,0 +1,251 @@
<template>
<div class="count-flop" :key="state.compKey">
<div :class="item!='.'?'data_cage':'count-flop-point'" v-for="(item, index) in state.value" :key="index">
<div v-if="item!='.'" class="count-flop-content" :class="['rolling_' + item]">
<!-- <div v-if="item!='.'" class="count-flop-content" :style="{transform: `translateY(-${item}0%)`}"> -->
<div v-for="(item2,index2) in state.numberList" :key="index2" class="count-flop-num">{{item2}}</div>
</div>
<div v-else class="count-flop-content">.</div>
</div>
<div v-if="suffix" class="count-flop-unit">{{suffix}}</div>
</div>
<!-- <div class="count-flop" :key="state.compKey">
<div :class="item!='.'?'count-flop-box':'count-flop-point'" v-for="(item, index) in state.value" :key="index">
<div v-if="item!='.'" class="count-flop-content" :class="['rolling_' + item]">
<div v-for="(item2,index2) in state.numberList" :key="index2" class="count-flop-num">{{item2}}</div>
</div>
<div v-else class="count-flop-content">.</div>
</div>
<div v-if="suffix" class="count-flop-unit">{{suffix}}</div>
</div> -->
</template>
<script lang="ts" setup name="CountFlop">
// import { number } from 'echarts';
import { reactive, onMounted, watch } from 'vue';
//
const props = defineProps({
val: {
type: Number,
default: () => 0,
},
suffix: {
type: String,
default: () => '',
},
});
const state = reactive({
value: [0,0,0,0] as any ,
numberList: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
compKey: 0
});
watch(
() => props.val,
() => {
init();
}
);
onMounted(() => {
init();
});
const init = () => {
let arr = props.val.toString().split('');
if(arr.length < 4) {
for(let i = arr.length; i < 4; i++) {
arr.unshift('0');
}
}
state.value = arr;
// state.compKey += 1;
}
</script>
<style scoped>
@font-face{font-family:electronicFont;src:url(../assets/font/DS-DIGIT.TTF)}
.data_cage {
display: block;
background-image: url(../assets/img/data_bg.png);
height: 100%;
width: 38px;
float: left;
margin-left: 1px;
color: white;
text-align: center;
font-size: 40px;
line-height: 52px;
background-repeat: no-repeat;
background-size: 100%;
}
.count-flop-num {
font-family: 'electronicFont';
}
.count-flop {
margin: 0 10px;
display: inline-block;
font-size: 0;
/* 可更改 */
height: 50px;
line-height: 50px;
font-size: 36px;
color: #4898f1;
}
.count-flop > div {
position: relative;
display: inline-block;
overflow: hidden;
height: 100%;
}
.count-flop-box {
/* 可更改 */
margin-right: 5px;
width: 36px;
border: 1px solid rgba(72, 152, 241, 0.3);
line-height: 48px;
border-radius: 6px;
}
.count-flop-point {
/* 可更改 */
margin-right: 5px;
width: 10px;
}
.count-flop-content {
font-family: MicrosoftYaHei-Bold;
text-align: center;
position: absolute;
left: 0;
top: 0;
width: 100%;
animation-fill-mode: forwards !important;
transition: transform 2s linear;
}
.rolling_0 {
animation: rolling_0 2.1s ease;
}
@keyframes rolling_0 {
from {
transform: translateY(-90%);
}
to {
transform: translateY(0);
}
}
.rolling_1 {
animation: rolling_1 3s ease;
}
@keyframes rolling_1 {
from {
transform: translateY(0);
}
to {
transform: translateY(-10%);
}
}
.rolling_2 {
animation: rolling_2 2.1s ease;
}
@keyframes rolling_2 {
from {
transform: translateY(0);
}
to {
transform: translateY(-20%);
}
}
.rolling_3 {
animation: rolling_3 3s ease;
}
@keyframes rolling_3 {
from {
transform: translateY(0);
}
to {
transform: translateY(-30%);
}
}
.rolling_4 {
animation: rolling_4 2.1s ease;
}
@keyframes rolling_4 {
from {
transform: translateY(0);
}
to {
transform: translateY(-40%);
}
}
.rolling_5 {
animation: rolling_5 3s ease;
}
@keyframes rolling_5 {
from {
transform: translateY(0);
}
to {
transform: translateY(-50%);
}
}
.rolling_6 {
animation: rolling_6 2.1s ease;
}
@keyframes rolling_6 {
from {
transform: translateY(0);
}
to {
transform: translateY(-60%);
}
}
.rolling_7 {
animation: rolling_7 3.1s ease;
}
@keyframes rolling_7 {
from {
transform: translateY(0);
}
to {
transform: translateY(-70%);
}
}
.rolling_8 {
animation: rolling_8 2.1s ease;
}
@keyframes rolling_8 {
from {
transform: translateY(0);
}
to {
transform: translateY(-80%);
}
}
.rolling_9 {
animation: rolling_9 3.6s ease;
}
@keyframes rolling_9 {
from {
transform: translateY(0);
}
to {
transform: translateY(-90%);
}
}
</style>

129
src/views/gene.vue

@ -0,0 +1,129 @@
<template>
<div class="boxnav" ref="geneRef" style="padding: 0 10px;">
</div>
</template>
<script setup lang="ts" name="gene">
import { reactive, onMounted, ref} from 'vue';
import * as echarts from 'echarts';
//
const geneRef = ref()
const state = reactive({
charts: {
theme: '',
bgColor: '',
color: '#303133',
},
});
//
const setPie = () => {
var myChart = echarts.init(geneRef.value);
let data1 = ['肝癌','肺癌','胃癌','结直肠癌','食管癌','胰腺癌','脑胶质瘤','肾癌','膀胱癌','前列腺癌']
let data2 = ['肝癌','肺癌','胃癌','结直肠癌','食管癌','甲状腺癌','卵巢瘤','乳腺癌','宫颈癌','子宫内膜癌']
var option = {
color: "#04CFE4",
grid: {
top: 20,
left: 10,
right: 0,
bottom: 40
},
xAxis: {
type: 'category',
axisTick: false,
axisLine: {
lineStyle: {
color: "rgba(255, 129, 109,.1)",
width: 1, //
},
},
axisLabel: {
interval: 0,
color: '#08DFFE',
rotate: 30,
fontSize: 12
},
data: data1
},
yAxis: {
show: false,
type: 'value',
interval: 1,
axisLine: {
lineStyle: {
color: "rgba(255, 129, 109, 0.1)",
width: 1, //
},
},
axisLabel: {
color: '#fff'
},
splitArea: {
areaStyle: {
color: "rgba(255,255,255,.5)",
},
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(255, 129, 109, 0.1)",
width: 0.5,
type: "dashed",
},
},
},
series: [
{
data: [1.23, 0.86, 2.11, 1.23, 0.92, 1.92, 2.92, 0.32, 0.12, 2.92],
type: "pictorialBar",
barCategoryGap: "0%",
symbol: "path://M0,10 L10,10 C5.5,10 5.5,5 5,0 C4.5,5 4.5,10 0,10 z",
label: {
show: true,
position: "top",
// distance: 15,
color: "#08DFFE",
fontWeight: "bolder",
fontSize: 12,
formatter: (a:any)=> {
return a.data + '%'
}
},
itemStyle: {
normal: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#9A11FF",
},
{
offset: 1,
color: "#08DFFE",
},
],
global: false, // false
},
},
emphasis: {
opacity: 1,
},
},
}
]
}
myChart.setOption(option);
};
//
onMounted(() => {
setPie();
});
</script>
<style scoped>
</style>

615
src/views/home.vue

@ -0,0 +1,615 @@
<template>
<div class="videobg style1"></div>
<div class="mainbox" style="width: 100%; height: 100%">
<div class="head fadeInDown">
<h1><span>湖口县全民健康大数据平台</span></h1>
<div class="timebox">
{{state.time}}<span>{{ state.weekday }}</span>
</div>
</div>
<ul style="height: calc(100vh - 85px); padding: 15px 15px 15px 15px">
<li style="width: 27%">
<div class="box card fadeIn delay06" style="height: calc(31% - 10px)">
<div class="tit">湖口县概况</div>
<div class="boxnav" id="">
<ul class="drqk clearfix">
<li>
<div class="icon"><img src="../assets/img/icon1.png" /></div>
<div>
<span>总面积</span>
<p><em>673</em><i>平方公里</i></p>
</div>
</li>
<li>
<div class="icon"><img src="../assets/img/icon2.png" /></div>
<div>
<span>户籍人口</span>
<p><em>28.67</em><i>万人</i></p>
</div>
</li>
<li>
<div class="icon"><img src="../assets/img/icon3.png" /></div>
<div>
<span>常住人口</span>
<p><em>22.06</em><i>万人</i></p>
</div>
</li>
<li>
<div class="icon"><img src="../assets/img/icon4.png" /></div>
<div>
<span>邮政编码</span>
<p><em>332500</em><i></i></p>
</div>
</li>
</ul>
</div>
</div>
<div class="box card fadeIn delay06" style="height: calc(33.33% - 10px)">
<div class="tit">居民构成</div>
<div class="boxnav">
<People />
</div>
</div>
<div class="box card fadeIn delay06" style="height: calc(34%)">
<div class="tit">医院就诊监控</div>
<Hospital />
</div>
</li>
<li style="width: 46%">
<div class="fadeIn delay06" style="height: calc(100% - 10px)">
<div class="linebox">
<span class="line1"><img src="../assets/img/line1.png" /></span>
<span class="line2"><img src="../assets/img/line2.png" /></span>
<span class="line3"><img src="../assets/img/line3.png" /></span>
<span class="line4"><img src="../assets/img/line4.png" /></span>
<span class="line5"><img src="../assets/img/line5.png" /></span>
<span class="line6"><img src="../assets/img/line6.png" /></span>
<span class="line7"><img src="../assets/img/line7.png" /></span>
</div>
<div class="maptabs">
<ul>
<li :class="maptabsCurrent==1? 'active':''" @click="maptabsClick(1)"><a href="#">健康数据</a></li>
<li :class="maptabsCurrent==0? 'active':''" @click="maptabsClick(0)"><a href="#">人口分布</a></li>
</ul>
</div>
<div style="position: absolute; top: 20px; width: 100%">
<ul class="txtnum txtnum2 clearfix">
<li>
<div>
<p>13153</p>
<span>癌症患者管理数</span>
</div>
</li>
<li>
<div>
<p>84.8%</p>
<span>癌症患者就诊率</span>
</div>
</li>
<li>
<div>
<p>13</p>
<span>服务医院</span>
</div>
</li>
<li>
<div>
<p>71.15%</p>
<span>电子健康档案开发率</span>
</div>
</li>
</ul>
</div>
<div class="mapbox" id="map" style="width: 100%; height: 100%"></div>
</div>
</li>
<li style="width: 27%">
<div
class="box card fadeIn delay06"
style="height: calc(33.33% - 10px)"
>
<div class="tit">出生死亡人口监控</div>
<div class="boxnav" id="echarts2">
<div class="born-box">
<span class="p_a01">今日出生人口</span>
<CountFlop :val="state.born" />
<div class="p_a01" style="font-size: 12px;">
环比
<img src="../assets/img/iconup.png" height="16" style="vertical-align: sub;" alt="">
3%
</div>
</div>
<div class="born-box">
<span class="p_a01">今日死亡人口</span>
<CountFlop :val="state.die" />
<div class="p_a01" style="font-size: 12px;">
环比
<img src="../assets/img/icondown.png" height="16" style="vertical-align: sub;" alt="">
3%
</div>
</div>
</div>
</div>
<div
class="box card fadeIn delay06"
style="height: calc(33.33% - 10px)"
>
<div class="tit">基因健康风险数据</div>
<Gene />
</div>
<div
class="box card fadeIn delay06"
style="height: calc(33.33% - 10px)"
>
<div class="tit">高危疾病排名TOP10</div>
<Cancer />
</div>
</li>
</ul>
<TownDialog ref="townRef" />
</div>
</template>
<script lang="ts" setup>
import './style.css'
import { reactive, onMounted, ref } from 'vue';
import * as echarts from 'echarts';
import 'echarts-gl';
import gdMap from './map.json'
import People from './people.vue';
import Hospital from './hospital.vue';
import TownDialog from './townDialog.vue';
import Gene from './gene.vue';
import Cancer from './cancer.vue';
import CountFlop from './countFlop.vue';
const timer = ref<NodeJS.Timeout | null>(null);
const townRef = ref();
const chinaGeoCoordMap = ref<any> ({
双钟镇: [116.23,29.7],
流泗镇: [116.36,29.73809724307942],
马影镇: [116.29,29.68],
武山镇: [116.34,29.55],
城山镇: [116.191,29.601],
大垅乡: [116.37,29.69],
凰村镇: [116.308,29.706],
张青乡: [116.33,29.652],
均桥镇: [116.31,29.592],
付垅乡: [116.34,29.61],
舜德乡: [116.19,29.52],
流芳乡: [116.248,29.52],
});
const state = reactive({
list: [],
born: 16,
die: 28,
time: '',
weekday: '',
mapdata1: [
{ name: '双钟镇', value: 150 },
{ name: '流泗镇', value: 190 },
{ name: '马影镇', value: 120 },
{ name: '武山镇', value: 40 },
{ name: '城山镇', value: 110 },
{ name: '均桥镇', value: 60 },
{ name: '凰村镇', value: 70 },
{ name: '大垅乡', value: 80 },
{ name: '张青乡', value: 50 },
{ name: '付垅乡', value: 30 },
{ name: '舜德乡', value: 60 },
{ name: '流芳乡', value: 90 },
],
mapdata2: [
{ name: '双钟镇', value: 210 },
{ name: '流泗镇', value: 190 },
{ name: '马影镇', value: 220 },
{ name: '武山镇', value: 140 },
{ name: '城山镇', value: 110 },
{ name: '均桥镇', value: 160 },
{ name: '凰村镇', value: 70 },
{ name: '大垅乡', value: 180 },
{ name: '张青乡', value: 50 },
{ name: '付垅乡', value: 130 },
{ name: '舜德乡', value: 90 },
{ name: '流芳乡', value: 120 },
],
})
const maptabsCurrent = ref(0);
onMounted(() => {
init();
timer.value = setTimeout(time, 1000);//
setInterval(() => {
state.born++;
}, 20000);
setInterval(() => {
state.die++;
}, 21000);
})
function time() {
clearTimeout(t);//
let dt = new Date();
var y = dt.getFullYear();
var mt = dt.getMonth() + 1;
// var weekday = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var weekday = ["星期天", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
var day = dt.getDate();
var h = dt.getHours();//
var m = dt.getMinutes();//
var s = dt.getSeconds();//
var toady = dt.getDay()
// alert(toady)
var t = null;
state.time = y + "-" + mt + "-" + Appendzero(day) + " " + Appendzero(h) + ":" + Appendzero(m) + ":" + Appendzero(s);
state.weekday = weekday[toady];
function Appendzero(obj: any) {
if (obj < 10) return "0" + "" + obj;
else return obj;
}
t = setTimeout(time, 1000); //,
}
const maptabsClick = (i: any) => {
maptabsCurrent.value = i;
if (i === 0)
map(state.mapdata1, gdMap)
else
map(state.mapdata2, gdMap)
}
const init = () => {
map(state.mapdata1, gdMap) //
}
var convertData = function (data: any) {
var res = []
for (var i = 0; i < data.length; i++) {
// console.log(data[i])
var dataItem = data[i]
var fromCoord = chinaGeoCoordMap.value[dataItem[0].name]
var toCoord = [116.36,29.79] //
if (fromCoord && toCoord) {
res.push({
// 线
coords:[
fromCoord,toCoord
],
})
// res.push([
// // 线
// fromCoord,
// // 线
// toCoord,
// ])
}
}
// console.log(9999, res)
return res
}
async function map(a: any, map: any) {
var myChartmap = echarts.init(document.getElementById("map"));
myChartmap.on('click', mapClick);
if(myChartmap){
myChartmap.clear();
}
var regions = []
var colors = ""
for (let i = 0; i < a.length; i++) {
//
if (a[i].value < 20) {
colors = "#41a9ed"
}
if (a[i].value >= 20) {
colors = "#3c8fda"
}
if (a[i].value >= 40) {
colors = "#397dce"
}
if (a[i].value >= 60) {
colors = "#366ec3"
}
if (a[i].value >= 80) {
colors = "#335eb8"
}
if (a[i].value >= 100) {
colors = "#304ead"
}
if (a[i].value >= 120) {
colors = "#2e40a3"
}
if (a[i].value >= 140) {
colors = "#2b339a"
}
regions.push(
{
name: a[i].name,
height: a[i].value / 15,
// height: 0,
itemStyle: {
borderWidth: 0,
// borderColor:"#00873A",
// opacity:0.95,
color: colors,
},
}
)
}
echarts.registerMap('湖口', map);
var viewControl = {
// autoRotate:true,
// minBeta:-3600,
// maxBeta:3600,
projection: 'perspective',// 'perspective''orthographic'
// autoRotate: true,
autoRotateDirection: 'cw',//cw
distance: 165,
minDistance: 40,
maxDistance: 200,//
alpha: 40,
beta: 0,
center: [-5, -5, 0],
}
let option = {
tooltip: {
},
geo3D: {
//
type: 'map3D',
name: '地图',
shading: 'realistic',
regions: regions,
zlevel: 0,
regionHeight: 20,
map: '湖口',
label: {
show: false,
},
itemStyle: {
color: '#fff',
borderWidth: 1,
borderColor: '#005eda'
},
//
emphasis: {
label: {
show: false,
},
itemStyle: {
color: 'rgb(0, 192, 255)',//
}
},
light: {
main: {
color: '#00d2ff',
intensity: 1.1,
shadow: true,
shadowQuality: 'high', // 'low', 'medium', 'high', 'ultra' [ default: 'medium' ]
alpha: 55,
beta: 30
},
ambient: { //
color: '#fff',
intensity: 0.5 // [ default: 0.2 ]
}
},
viewControl: viewControl,
// data: a
},
series: [
{
//
type: 'map3D',
name: '模拟数据',
shading: 'realistic',
zlevel: 5,
regionHeight: 5,
map: '湖口',
label: {
show: true,
formatter: function (e: any) {
if (e.data.value) {
return e.name + ":" + e.data.value
} else {
return e.name + ":" + 0
}
},
distance: 0,
textStyle: {
color: '#fff',
fontFamily: "苹方",
background: 'rgba(0,0,0,0.4)',
fontSize: 14,
},
},
itemStyle: {
color: 'transparent',
},
emphasis: {
label: {
show: true,
},
itemStyle: {
color: 'transparent',
}
},
viewControl: viewControl,
data: a
},
]
}
option.series = option.series.concat(await setMap());
myChartmap.setOption(option);
window.addEventListener("resize", function () {
myChartmap.resize();
});
}
const setMap = async () => {
let formdata = '流泗镇' //
var series = [] as any;
var chinaDatas = [
[{name: '双钟镇', value: 0}],
[{name: '流泗镇', value: 0}],
[{name: '马影镇', value: 0}],
[{name: '武山镇', value: 0}],
[{name: '城山镇', value: 0}],
[{name: '大垅乡', value: 0}],
[{name: '凰村镇', value: 0}],
[{name: '张青乡', value: 0}],
[{name: '均桥镇', value: 0}],
[{name: '付垅乡', value: 0}],
[{name: '舜德乡', value: 0}],
[{name: '流芳乡', value: 0}],
];
[[formdata, chinaDatas]].forEach(function (item, i) {
series.push(
{
type: 'lines3D',
coordinateSystem: 'geo3D',
regionHeight: 10,
effect: {
show: true,
period: 2, //
trailLength: 0.15, //[0,1]
// constantSpeed: 5, //
symbol: 'arrow', //
symbolSize: 9, //
color: '#fcdd6e', //
trailOpacity: 1, //
trailColor: 'rgba(255, 255, 255, 0.5)' //
},
lineStyle: {
width: 1, // 线
color: 'rgba(118 , 192, 234, 1)', // 线
opacity: 1,
normal: {
show: true,
width: 1, //线
opacity: 1, //线
curveness: 0.3, //线
color: '#fcdd6e', // 线
},
// color: '#fcdd6e',
},
blendMode: 'lighter',
data: convertData(item[1]),
});
series.push(
{
type: 'scatter3D',
coordinateSystem: 'geo3D',
zlevel: 1, //
rippleEffect: {
//
period: 4, //
brushType: 'stroke', // stroke, fill
scale: 3, //
color: '#fcdd6e',
},
label: {
normal: {
show: false,
position: 'right', //
// offset: [5, 0], //
// formatter: function (params: any) {
// //
// return params.data.name
// },
fontSize: 13,
},
emphasis: {
show: false,
},
},
showEffectOn: 'render', //
hoverAnimation: true, //
symbol: 'circle',
symbolSize: function (val: any) {
return 10 //
},
itemStyle: {
normal: {
show: false,
color: '#fce182',
},
},
data: getEffectScatter(item[1]),
},
//
{
type: 'scatter3D',
coordinateSystem: 'geo3D',
zlevel: 2,
rippleEffect: {
period: 4,
brushType: 'stroke',
scale: 4,
color: '#38ff85',
},
label: {
normal: {
show: false,
position: 'right',
//offset:[5, 0],
color: '#38ff85',
formatter: '{b}',
textStyle: {
color: '#38ff85',
},
},
emphasis: {
show: false,
color: '#38ff85',
},
},
symbol: 'circle',
symbolSize: 15,
itemStyle: {
color: '#38ff85',
},
data: [
{
name: item[0],
value: [116.36,29.79].concat([10]),
},
],
}
)
})
return series
}
const getEffectScatter = (data: any) => {
var res = []
for (var i = 0; i < data.length; i++) {
var dataItem = data[i]
res.push({
name: dataItem[0].name,
value: chinaGeoCoordMap.value[dataItem[0].name].concat([dataItem[0].value]),
})
}
return res
}
const mapClick = (item:any) => {
// console.log(9999, item)
townRef.value.show(item);
}
</script>
<style scoped>
@font-face{font-family:electronicFont;src:url(../assets/font/DS-DIGIT.TTF)}
.born-box {
display: flex;
height: 45%;
line-height: 52px;
}
.p_a01 {
font-size: 15px;
color: #00aeff;
float: left;
margin-right: 1%;
}
</style>

77
src/views/hospital.vue

@ -0,0 +1,77 @@
<template>
<div class="boxnav">
<div class="listhead">
<span>序号</span>
<span>医院名</span>
<span>床位数</span>
<span>就诊人数</span>
</div>
<div class="listnav scrollDiv">
<!-- <ul>
<li v-for="(item, i) in state.hospitalList" :key="i">
<span>{{item.index}}</span>
<span>{{item.name}}</span>
<span>{{item.bad}}</span>
<span>{{item.visit}}</span>
</li>
</ul> -->
<vue3-seamless-scroll
class="scroll"
v-model="isScroll"
:list="listData"
:step="0.3"
:hover="true"
:limit-scroll-num="3"
:wheel="true"
>
<ul>
<li v-for="item in listData" class="item">
<span>{{item.index}}</span>
<span>{{item.name}}</span>
<span>{{item.bad}}</span>
<span>{{item.visit}}</span>
</li>
</ul>
</vue3-seamless-scroll>
</div>
</div>
</template>
<script setup lang="ts" name="hospital">
import { reactive, onMounted, ref} from 'vue';
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll';
const isScroll=ref(true)
const listData = ref([
{index: 1, name: '湖口县中医医院', bad: 854, visit: 242},
{index: 2, name: '建民医院', bad: 854, visit: 242},
{index: 3, name: '湖口县人民医院', bad: 854, visit: 242},
{index: 4, name: '潘思宏诊所', bad: 854, visit: 242},
{index: 5, name: '湖口县中医医院新园区', bad: 854, visit: 242},
{index: 6, name: '湖口县人民医院新园区', bad: 854, visit: 242},
{index: 7, name: '潘郭华诊所', bad: 854, visit: 242},
{index: 8, name: '殷智诊所', bad: 854, visit: 242},
{index: 9, name: '庐山市人民医院', bad: 854, visit: 242},
]);
const state = reactive({
hospitalList: [
{index: 1, name: '湖口县中医医院', bad: 854, visit: 242},
{index: 2, name: '建民医院', bad: 854, visit: 242},
{index: 3, name: '湖口县人民医院', bad: 854, visit: 242},
{index: 4, name: '潘思宏诊所', bad: 854, visit: 242},
{index: 5, name: '湖口县中医医院新园区', bad: 854, visit: 242},
{index: 6, name: '湖口县人民医院新园区', bad: 854, visit: 242},
{index: 7, name: '潘郭华诊所', bad: 854, visit: 242},
{index: 8, name: '殷智诊所', bad: 854, visit: 242},
{index: 9, name: '庐山市人民医院', bad: 854, visit: 242},
]
});
//
onMounted(() => {
});
</script>
<style scoped>
.user-container {
height: 100%;
}
</style>

57189
src/views/map.json

File diff suppressed because it is too large

207
src/views/people.vue

@ -0,0 +1,207 @@
<template>
<div class="user-container layout-pd">
<div style="height: 100%;" ref="peoplePie"></div>
<!-- <div style="height: 50%" ref="peopleBar"></div> -->
</div>
</template>
<script setup lang="ts" name="people">
import { reactive, onMounted, ref} from 'vue';
import * as echarts from 'echarts';
// import { DataZoomComponent } from 'echarts/components';
// echarts.use([DataZoomComponent]);
//
const peoplePie = ref()
const peopleBar = ref()
const state = reactive({
charts: {
theme: '',
bgColor: '',
color: '#303133',
},
});
//
const city = reactive([
{ value: 25835, name: '0-6岁' },
{ value: 12335, name: '7-17岁' },
{ value: 14835, name: '18-40岁' },
{ value: 11935, name: '41-60岁' },
{ value: 7335, name: '60岁以上' },
])
const cityName = reactive([]) // -citynamecityName
const cityValue = reactive([]) // -cityvaluecityValue\
// option
const axisAlign = () => {
var myChart = echarts.init(peopleBar.value, state.charts.theme);
var option = {
// 线 x0, y0, x2, y2, 0 - 1 globalCoord `true`
color:{
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#00fefb' // 0%
}, {
offset: 1, color: '#0063ce' // 100%
}],
global: false // false
},
/* 鼠标移入的工具提示 */
// tooltip: {
// trigger: 'axis',
// axisPointer: {
// type: 'line'
// },
// backgroundColor : 'rgba(0,0,0,0.4)', /* */
// borderColor: 'transparent', //
// textStyle: { //
// color : 'rgba(255,255,255,0.8)'
// }
// },
/* x y 轴的文字样式 */
textStyle:{
color: '#4c9bfd'
},
//
axisTick: {
lineStyle : { color : '#096b80' }
},
/* 布局 */
grid: {
left: '0%',
right: '0%',
bottom: '10%',
top: '4%',
show: true, // true
containLabel: true,
borderColor: '#096b80' /* 边框的颜色 */
},
/* 直角坐标系 grid 中的 x 轴 */
xAxis: [
{
type: 'category',
data: cityName, /* 数据 */
axisLabel: {
interval: 0,
// rotate: 30
},
axisTick: {
alignWithLabel: true
},
}
],
/* 直角坐标系 grid 中的 y 轴 */
yAxis: [
{
type: 'value',
splitLine: { // y线
show:true,
lineStyle: {
color: "#096b80",
}
}
},
],
/* 整体配置 */
series: [
{
name: '人数',
type: 'bar',
barWidth: '40%',
label: {
show: true,
position: 'top'
},
data: cityValue,
},
]
};
myChart.setOption(option);
}
const setPie = () => {
var myChart = echarts.init(peoplePie.value);
var option = {
// color: ['#A0CE3A', '#31C5C0', '#1E9BD1', '#0F347B', '#585247', '#7F6AAD', '#009D85', "rgba(250,250,250,0.3)"],
grid: {
bottom: 0,
left: 0,
right: '0',
},
series: [
{
radius: ['30%', '60%'],
center: ['50%', '50%'],
type: 'pie',
roseType: 'area',
label: {
normal: {
show: true,
formatter: ['{b|{b}}', '{c|{c}%}'].join('\n'),
//formatter: ['{b|{b}}','{c|{c}}', '{d|{d}%}'].join('\n'),
rich: {
c: {
color: 'yellow',
fontSize: 18,
fontFamily: '等线',
fontWeight: 'bold',
},
b: {
color: 'rgba(255,255,255,.75)',
fontSize: 14,
// fontFamily: fontFamily,
height: 20,
},
},
position: 'outside',
},
emphasis: {
show: true,
},
},
itemStyle: {
borderRadius: 3,
// borderColor: '#fff',
borderWidth: 2,
},
labelLine: {
normal: {
show: true,
// length: 15,
//length2: 50
},
emphasis: {
show: true,
},
},
name: '饼图1',
data: [
{ value: 20, name: '0-6岁' },
{ value: 22, name: '7-17岁' },
{ value: 28, name: '18-40岁' },
{ value: 15, name: '41-60岁' },
{ value: 15, name: '60岁以上' },
] ,
},
],
}
myChart.setOption(option);
};
//
onMounted(() => {
city.map(city => {
cityName.push(city.name);
cityValue.push(city.value);
})
// axisAlign();
setPie();
});
</script>
<style scoped>
.user-container {
height: 100%;
}
</style>

236
src/views/style.css

@ -0,0 +1,236 @@
@charset "utf-8";*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
*,body{padding:0;margin:0;font-family:"PingFang SC","Lantinghei SC","Microsoft YaHei","HanHei SC","Helvetica Neue","Open Sans",Arial,"Hiragino Sans GB",,STHeiti,"WenQuanYi Micro Hei",SimSun,sans-serif,HYWenHei-GEW}
body,html{height:100%}
li{list-style-type:none}
i{margin:0;padding:0;text-indent:0}
img{border:none;max-width:100%;
/* image-rendering: -webkit-optimize-contrast; */
}
a{text-decoration:none;color:#fff}
a.active,a:focus{outline:0!important;text-decoration:none}
h1,h2,h3,h4,h5,h6,ol,p,ul{padding:0;margin:0}
a:hover{color:#06c;text-decoration:none!important}
i{font-style:normal}
/* 滚动条 */
::-webkit-scrollbar {width:3px;position:absolute;}
::-webkit-scrollbar-thumb {background:#ff0000}
::-webkit-scrollbar-track {background:#6c1a1a}
body{color:#fff;font-size:14px;overflow-x:hidden; background: #000d4a url(../assets/img/bg.jpg) center center;
background-size: cover;
color: rgba(255,255,255,.75); overflow: hidden;}
.videobg{ position: fixed;; width: 100%; height: 100%; left: 0; top: 0; z-index: 1;left: 0; top: 0;
background: #000;background: -webkit-radial-gradient(50% 10%,farthest-corner, #2a4fa9 0%, #101e42 50%,#0b1024,#000);}
.videobg video{ object-fit: cover; filter:blur(2px); opacity: .05;filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius='5'); position: relative; }
.style1,.style2{position:absolute;width:100%;height:100%;pointer-events:none;border-radius:3px}
.style2{border:none}
.style1:before{width:100%;height:1px;content:"";background:linear-gradient(to right,rgba(255,255,255,.02),rgba(108,176,255,.1),rgba(255,255,255,.02));position:absolute}
.style2::after,.style2:before{width:1px;height:100%;content:"";background:linear-gradient(to bottom,rgba(108,176,255,.04),rgba(255,255,255,0));position:absolute}
.style1:before{top:0}
.style2:before{left:-1px}
.style2:after{right:-1px}
body::before{content:"";position:absolute;width:100%;opacity:1;transition:all .5s;height:100%;top:0;left:0;pointer-events:none;background-color:transparent;background-image:url(../assets/img/pattern.png);background-size:4.6875rem;background-repeat:repeat;background-attachment:initial;z-index:11;opacity:.8}
body:after {
position: absolute;
top: 0; left: 0;
z-index: 1;
content: "";
width: 100%;
height: 100%;
background: url(../assets/img/bg1.png) no-repeat center top;
opacity: 0.3;
pointer-events: none;
}
.mainbox{ position: relative; z-index: 10;}
.mainbox>ul{display:flex;padding:10px 15px}
.mainbox>ul>li{width:25%;padding:0}
.mainbox>ul,
.mainbox>ul>li{ height: 100%;}
/* 标题 */
.tit{padding:10px 10px 0 30px;font-size:16px;font-weight:500;color:#bcdcff;position:relative;font-weight:bolder;display:flex}
.tit:before{transform:rotate(45deg);border-radius:3px;position:absolute;content:"";width:6px;height:6px;border:2px solid #81bcff;left:12px;top:16px}
/* .card{height:26vh;margin-bottom:10px;border-radius:5px;backdrop-filter:blur(3px);background:linear-gradient(135deg,rgba(247,111,0,.2),transparent,transparent);box-shadow:0 0 20px rgba(0,0,0,.1);position:relative;border:none}
.card:after{position:absolute;left:0;top:0;z-index:1;pointer-events:none;content:"";width:100%;height:100%;background:linear-gradient(315deg,rgba(255,47,47,.5),transparent,transparent)} */
/* 边框&背景 */
.card{position:relative;height:300px; margin-bottom:10px; backdrop-filter:blur(3px);background:linear-gradient(135deg,rgba(0, 169, 247, 0.2),transparent,transparent,rgba(0, 169, 247, 0.1));box-shadow:0 0 20px rgba(0,0,0,.1);}
.card::before{position:absolute;right:0;top:0;pointer-events:none;content:"";border-right:2px solid #0793ff;border-top:2px solid #0793ff;width:calc(100% - 200px);height:calc(100% - 20px); }
.card:after{position:absolute;left:190px;top:0;pointer-events:none;content:"";background:url(../assets/img/line01.png);width:70px;height:11px;}
.boxnav{padding:10px 15px;height:calc(100% - 33px);position:relative;z-index:10}
.boxnav::before{position:absolute;left:0;bottom:0;pointer-events:none;content:"";border-left:2px solid #0793ff;border-bottom:2px solid #0793ff;width:calc(100% - 100px);height:calc(100% - 50px);}
.boxnav:after{position:absolute;right:0;bottom:0;pointer-events:none;content:"";background:url(../assets/img/line02.png);width:75px;height:11px;}
.boxnav:after,
.boxnav::before,
.card:after,
.card::before{opacity: .15;}
/* 动画 */
.fadeIn{opacity:0;animation:fadeIn 1.5s forwards}
.fadeInDown{opacity:0;transform:translate3d(0,-100%,0);animation:fadeInDown .6s forwards}
.fadeInUp{animation:fadeInUp 1s forwards;opacity:0}
.fadeInLeft{animation:fadeInLeft .6s forwards}
.bounceIn{transform:scale(0,1);animation:bounceIn .6s forwards}
@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}
to{opacity:1;-webkit-transform:none;transform:none}
}
@keyframes fadeIn{0%{opacity:0;transform:scale(.8)}
to{opacity:1;transform:scale(1)}
}
@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}
to{opacity:1;-webkit-transform:none;transform:none}
}
@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}
to{opacity:1;-webkit-transform:none;transform:none}
}
.delay02{animation-delay:.2s}
.delay04{animation-delay:.4s}
.delay06{animation-delay:.6s}
.delay08{animation-delay:.8s}
.delay1{animation-delay:1s}
.delay12{animation-delay:1.2s}
.delay14{animation-delay:1.4s}
.delay16{animation-delay:1.6s}
.delay18{animation-delay:1.8s}
.delay2{animation-delay:2s}
/* 滚动所需 */
.str_wrap{overflow:hidden;width:100%;position:relative;-moz-user-select:none;-khtml-user-select:none;user-select:none;white-space:nowrap}
.str_move{white-space:nowrap;position:absolute;top:0;left:0;cursor:move}
.str_move_clone{display:inline-block;vertical-align:top;position:absolute;left:100%;top:0}
.str_vertical .str_move_clone{left:0;top:100%}
.str_down .str_move_clone{left:0;bottom:100%}
.str_down .str_move,.str_vertical .str_move{white-space:normal;width:100%}
.noStop .str_move,.no_drag .str_move,.str_static .str_move{cursor:inherit}
.str_wrap img{max-width:none!important}
.listhead{display:flex;justify-content:space-between;color:rgba(255,255,255,.5);border-bottom:1px solid rgba(255,255,255,.1)}
.listnav{height:calc(100% - 30px);border-bottom:1px solid rgba(255,255,255,.1);overflow-y: hidden;}
.listnav ul li{height:100%;display:flex;justify-content:space-between}
.listhead span,.listnav li span{padding:8px 0;text-align:center;font-size:13px;}
.listhead span{padding-top:0}
.listhead span:nth-child(1),
.listnav li span:nth-child(1){width: 8%; white-space: nowrap;}
.listhead span:nth-child(2),
.listnav li span:nth-child(2){width: 52%; text-align: left; padding-right: 10px;}
.listhead span:nth-child(3),
.listnav li span:nth-child(3){width: 23%;text-align: left;}
.listhead span:nth-child(4),
.listnav li span:nth-child(4){width: 12%;white-space: nowrap;}
.listnav ul li:nth-child(odd){background:rgba(255,255,255,.05)}
.listnav ul li{border:1px solid rgba(255,255,255,.1);border-top:none;border-bottom:none}
/* 数字类 */
.txtnum{height:100%;display:flex;align-items:center; justify-content: center;}
.txtnum li{text-align:center;position:relative; padding:0 30px;}
.txtnum li>div{position: relative; z-index: 10;;}
.txtnum span{color:rgba(255,255,255,.75); display: block; padding-top: 5px; white-space: nowrap;}
.txtnum p{font-size:24px;font-style:normal;font-weight:bolder; color: #fff; display: inline; white-space: nowrap;
background:linear-gradient(0deg,#f2f9ff,#bfe0ff);font-style:normal;background-size:cover;font-family:"等线";font-weight:bolder;font-size:30px;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;text-fill-color:transparent
}
.txtnum li:after{height:100%;width:100%;content:"";left:0;top:-2px;position:absolute;background:-webkit-radial-gradient(50% 50%,farthest-corner,#0076d1 0,transparent,transparent);opacity:.4}
.txtnum li::before{height:120%;width:1px;content:"";right:0;top:-10%;position:absolute;background:linear-gradient(to bottom,transparent,#a8d6ff,transparent);opacity:.5}
.txtnum li:last-child::before{display:none}
.maptabs{position: absolute; left:-30px; top: 120px; z-index: 11; padding: 10px 20px;}
.maptabs li a{ display: block; transition: all .5s; color: rgba(255,255,255,.75); text-align: center; height: 48px; background: url(../assets/img/btn1.png) right top no-repeat; width: 140px; padding: 6px 0 0 10px ;
font-size: 15px;
margin: 10px 0;}
.maptabs li.active a{ background: url(../assets/img/btn2.png) right top no-repeat; color: #fff; font-weight: bold;}
.maptabs li a:hover{ transform: translateX(10px); color: rgba(0, 191, 255, 0.85);}
.maptabs p{ padding: 15px 30px; color: #07e5ff; }
/* 头部大标题 */
.head{display:flex;justify-content:center;align-items:center;}
.head h1{flex-shrink:0;background:url(../assets/img/headcenter.png) no-repeat center bottom; background-size:100% auto ;height:85px;line-height: 85px;}
.head h1 span{font-size:46px;background:linear-gradient(to bottom,#00fff7,#37cdff); padding: 0 20px; background-size:cover;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;text-fill-color:transparent;font-weight:bold; font-family:"Microsoft YaHei"; line-height: 1; letter-spacing: 2px;}
.head::after,.head::before{height:85px;content:"";width:100%}
.head::before{background:url(../assets/img/headleft.png) no-repeat right bottom;}
.head::after{background:url(../assets/img/headright.png) no-repeat left bottom; }
.timebox{ position: absolute; right: 30px; font-size: 16px; color: #50c2ff; padding-bottom: 42px;}
.timebox span{ color: #fff; padding-left: 10px;}
/* .time{ position:absolute; right:15px; top:0; line-height: 66px;color:rgba(255,255,255,.7); font-size: 18px; padding-right: 15px;} */
.map{display: flex; justify-content: center; align-items: center;}
.mapbox{width: 90%; position: relative;}
.mapbox img{width: 100%;}
/* .others{position: absolute;width: 1920px; left: calc(50% - 960px); top: 0;} */
.others{position: relative; height: 100%; display: flex; align-items: center; }
.others>span{ position: absolute;}
.others .img1{ top: 5px; width: 200px; right: 50px;}
.others .img2{ width: 180px; left: 130px; top: -10px}
.others .img3{ width: 100px; left: 30px; transform: rotate(45deg); top: 0px;}
/* 图标类 */
.drqk{height:100%;display:flex;align-items:center;flex-wrap:wrap; justify-content: center;}
.drqk li{width:50%;display:flex;align-items:center; }
.icon{display:flex;position:relative;justify-content:center;align-items:center;flex-shrink:0;margin-right:15px;padding:15px;width:60px;height:60px}
.icon::before{position:absolute;content:"";background:url(../assets/img/iconbg.png) no-repeat center center;background-size:auto 100%;width:100%;height:100%;left:0;top:0}
.drqk li span{}
.drqk li em{background:linear-gradient(0deg,#f2f9ff,#bfe0ff);font-style:normal;background-size:cover;font-family:"等线";font-weight:bolder;font-size:24px;-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;text-fill-color:transparent}
/* 背景动画类 更多模板下载:http://www.bootstrapmb.com*/
.linebox{ position: absolute; width: 100%; transform: scale(1.3,0.65); overflow: hidden; height: 100%; left: 0; top: 15%; display: flex; justify-content: center; align-items: center;}
.linebox>span{ position: absolute; opacity: .1; width: 100%; height: 100%;}
.linebox>span img{width: 100%; height: 100%; object-fit: contain;}
.linebox .line1{ width: 30%; animation:scales1 60s linear infinite}
.linebox .line2{ width: 40%; animation:scales2 55s linear infinite}
.linebox .line3{ width: 47%; animation:scales1 50s linear infinite}
.linebox .line4{ width: 60%; animation:scales2 45s linear infinite}
.linebox .line5{ width: 20%; animation:scales1 40s linear infinite}
.linebox .line6{ width: 70%; animation:scales2 35s linear infinite}
.linebox .line7{ width: 75%; animation:scales1 30s linear infinite}
@keyframes scales1{
0%{transform: rotate(0deg);}
100%{transform: rotate(360deg);}
}
@keyframes scales2{
0%{transform: rotate(0deg);}
100%{transform: rotate(-360deg);}
}
.marker{animation:fadeInDown 1s forwards; cursor: pointer;position: absolute; transition: all .5s; align-items: center;
display: flex; justify-content: center; }
.marker:before{ width: 8px; height: 8px; border-radius: 5px; background: rgb(0, 255, 255); position: absolute; content: ""; transform: scale(1,.75);}
.marker:hover span{display: block;}
.marker>i{ width: 20px; height: 20px;position: absolute; display: flex; align-items: center; justify-content: center; transform: scale(1,.75);}
.marker>i::after,
.marker>i::before{ position: absolute; content: "";background: rgba(0, 179, 255, 0.7); border: 1px solid rgb(161, 203, 255);; border-radius: 100px; transform: scale(0);opacity: 0;}
.marker>i::after{ width: 150%; height: 150%;animation: fadein 2s infinite linear; }
.marker>i::before{width:200%; height:200%;animation: fadein 2s 1s infinite linear;}
@keyframes fadein {
0%{transform: scale(0); opacity: 0;}
50%{transform: scale(.5); opacity: 1;}
100%{transform: scale(1); opacity: 0;}
}

217
src/views/test.vue

@ -0,0 +1,217 @@
<template>
<section class="cloud-bed">
<div class="cloud-box">
<span
v-for="(item, index) in listData"
:key="index" :style="item"
@click="getDataInfo(item)"
>
{{ item.name }}
</span>
</div>
</section>
</template>
<script lang="ts" setup>
import { onMounted, reactive, nextTick, ref } from 'vue';
const listData = ref([
{name: '缺血性心脏病', top: '40%', left: '50%', fontSize: '29px', color: 'rgb(255, 78, 105)'},
{ name: '中风', top: '46%', left: '80%', fontSize: '20px', color: 'rgb(255, 123, 2)'},
{name: '慢性阻塞性肺病', top: '57%', left: '59%', fontSize: '20px', color: 'rgb(92, 39, 254)'},
{name: '下呼吸道感染', top: '23%', left: '50%', fontSize: '20px', color: 'rgb(59, 196, 199)'},
{name: '新生儿疾病', top: '61%', left: '23%', fontSize: '20px', color: 'rgb(255, 123, 2)'},
{name: '气管癌、支气管癌、肺癌', top: '74%', left: '53%', fontSize: '15px', color: 'rgb(29, 229, 226)'},
{name: '阿尔兹海默症', top: '86%', left: '59%', fontSize: '15px', color: '#aaa'},
{name: '腹泻', top: '25%', left: '26%', fontSize: '15px', color: 'rgb(8, 199, 146)'},
{name: '糖尿病', top: '10%', left: '50%', fontSize: '12px', color: 'rgb(92, 39, 254)'},
{name: '肾病', top: '11%', left: '40%', fontSize: '12px', color: '#58D5FF'},
]);
const state = reactive({
timer: 10, //
radius: 0, //
dtr: Math.PI/380, //
active: false, //
lasta: 0, //
lastb: 0.5, //
distr: true,
tspeed: 0, //
mouseX: 0,
mouseY: 0,
tagAttrList: [],
tagContent: null,
cloudContent: null as any ,
sinA: '',
cosA: '',
sinB: '',
cosB: '',
sinC: '',
cosC: '',
})
onMounted(() => {
nextTick(() => {
state.radius = document.querySelector('.cloud-box').offsetWidth / 2
initWordCloud()
})
})
//
const getDataInfo = (item:any) => {
console.log(item, 'item')
};
const initWordCloud = () => {
state.cloudContent = document.querySelector('.cloud-box');
state.tagContent = state.cloudContent.getElementsByTagName('span');
for (let i = 0; i < state.tagContent.length; i++) {
let tagObj = {};
tagObj.offsetWidth = state.tagContent[i].offsetWidth;
tagObj.offsetHeight = state.tagContent[i].offsetHeight;
state.tagAttrList.push(tagObj);
}
sineCosine(0, 0, 0);
positionAll();
state.cloudContent.onmouseover = () => {
state.active=true;
};
state.cloudContent.onmouseout = () => {
state.active=false;
};
state.cloudContent.onmousemove = (ev: any) => {
let oEvent = window.event || ev;
state.mouseX = oEvent.clientX - (state.cloudContent.offsetLeft + state.cloudContent.offsetWidth/2);
state.mouseY = oEvent.clientY - (state.cloudContent.offsetTop + state.cloudContent.offsetHeight/2);
state.mouseX/= 5;
state.mouseY/= 5;
};
setInterval(update, state.timer);
};
const positionAll = () => {
let phi = 0;
let theta = 0;
let max = state.tagAttrList.length;
let aTmp = [];
let oFragment = document.createDocumentFragment();
//
for (let i=0; i < state.tagContent.length; i++) {
aTmp.push(state.tagContent[i]);
}
aTmp.sort(() => {
return Math.random() < 0.5 ? 1 : -1;
});
for (let i = 0; i < aTmp.length; i++) {
oFragment.appendChild(aTmp[i]);
}
state.cloudContent.appendChild(oFragment);
for(let i = 1; i < max + 1; i++){
if (state.distr) {
phi = Math.acos(-1 + (2 * i - 1) / max);
theta = Math.sqrt(max * Math.PI) * phi;
} else {
phi = Math.random() * (Math.PI);
theta = Math.random() * (2 * Math.PI);
}
//
state.tagAttrList[i-1].cx = state.radius * Math.cos(theta) * Math.sin(phi);
state.tagAttrList[i-1].cy = state.radius * Math.sin(theta) * Math.sin(phi);
state.tagAttrList[i-1].cz = state.radius * Math.cos(phi);
state.tagContent[i-1].style.left = state.tagAttrList[i-1].cx + state.cloudContent.offsetWidth / 2 - state.tagAttrList[i-1].offsetWidth / 2 + 'px';
state.tagContent[i-1].style.top = state.tagAttrList[i-1].cy + state.cloudContent.offsetHeight / 2 - state.tagAttrList[i-1].offsetHeight / 2 + 'px';
}
};
const update = () => {
let angleBasicA;
let angleBasicB;
if (state.active) {
angleBasicA = (-Math.min(Math.max(-state.mouseY, -200 ), 200) / state.radius) * state.tspeed;
angleBasicB = (Math.min(Math.max(-state.mouseX, -200 ), 200) / state.radius) * state.tspeed;
} else {
angleBasicA = state.lasta * 0.98;
angleBasicB = state.lastb * 0.98;
}
//
// lasta=a;
// lastb=b;
// if(Math.abs(a)<=0.01 && Math.abs(b)<=0.01)
// {
// return;
// }
sineCosine(angleBasicA, angleBasicB, 0);
for(let j = 0; j < state.tagAttrList.length; j++) {
let rx1 = state.tagAttrList[j].cx;
let ry1 = state.tagAttrList[j].cy * state.cosA + state.tagAttrList[j].cz * (-state.sinA);
let rz1 = state.tagAttrList[j].cy * state.sinA + state.tagAttrList[j].cz * state.cosA;
let rx2 = rx1 * state.cosB + rz1 * state.sinB;
let ry2 = ry1;
let rz2 = rx1 * (-state.sinB) + rz1 * state.cosB;
let rx3 = rx2 * state.cosC + ry2 * (-state.sinC);
let ry3 = rx2 * state.sinC + ry2 * state.cosC;
let rz3 = rz2;
state.tagAttrList[j].cx = rx3;
state.tagAttrList[j].cy = ry3;
state.tagAttrList[j].cz = rz3;
let per = 350 / (350 + rz3);
state.tagAttrList[j].x = rx3 * per - 2;
state.tagAttrList[j].y = ry3 * per;
state.tagAttrList[j].scale = per;
state.tagAttrList[j].alpha = per;
state.tagAttrList[j].alpha = (state.tagAttrList[j].alpha - 0.6) * (10/6);
}
doPosition();
depthSort();
}
const doPosition =() => {
let len = state.cloudContent.offsetWidth/2;
let height = state.cloudContent.offsetHeight/2;
for (let i=0;i < state.tagAttrList.length;i++) {
state.tagContent[i].style.left = state.tagAttrList[i].cx + len - state.tagAttrList[i].offsetWidth/2 + 'px';
state.tagContent[i].style.top = state.tagAttrList[i].cy + height - state.tagAttrList[i].offsetHeight/2 + 'px';
state.tagContent[i].style.fontSize = Math.ceil(12 * state.tagAttrList[i].scale/2) + 8 + 'px';
state.tagContent[i].style.filter = "alpha(opacity="+100 * state.tagAttrList[i].alpha+")";
state.tagContent[i].style.opacity = state.tagAttrList[i].alpha;
}
};
const depthSort = () => {
let aTmp = [];
for (let i = 0; i < state.tagContent.length; i++) {
aTmp.push(state.tagContent[i]);
}
aTmp.sort((item1, item2) => item2.cz - item1.cz);
for (let i = 0; i < aTmp.length; i++) {
aTmp[i].style.zIndex=i;
}
}
const sineCosine = (a, b, c) => {
state.sinA = Math.sin(a * state.dtr);
state.cosA = Math.cos(a * state.dtr);
state.sinB = Math.sin(b * state.dtr);
state.cosB = Math.cos(b * state.dtr);
state.sinC = Math.sin(c * state.dtr);
state.cosC = Math.cos(c * state.dtr);
}
</script>
<style scoped lang="less">
.cloud-bed {
width: 380px;
height: 170px;
.cloud-box{
position:relative;
margin:20px auto 0px;
width: 100%;
height: 100%;
background: #00000000;
span{
position: absolute;
padding: 3px 6px;
top: 0px;
font-weight: bold;
text-decoration:none;
left:0px;
}
}
}
</style>

450
src/views/townDialog.vue

@ -0,0 +1,450 @@
<template>
<el-dialog
v-model="dialogVisible"
:title="choseItem?.name + '健康大数据'"
class="hukou-dialog"
width="60%"
><div>
<el-row :gutter="20">
<el-col :span="15" class="box card fadeIn delay06" style=" height: 200px;">
<div class="tit">{{choseItem?.name}}人更高了</div>
<div class="boxnav people-content">
<div>
<div>18-44岁平均身高</div>
<div class="man-box">
<div class="man-box-item">
<img src="../assets/img/man.png" alt="">
<div>169.7厘米</div>
</div>
<div class="man-box-item">
<img src="../assets/img/woman.png" alt="">
<div>158.1厘米</div>
</div>
</div>
<div>与2015年相比分别增加</div>
<div><span class="largText">1.2厘米</span> <span class="largText">0.8厘米</span></div>
</div>
<div>
<div>6-17岁平均身高</div>
<div style="margin-top: 15px;">与2015年相比分别增加</div>
<div class="man-box">
<div class="man-box-item">
<img src="../assets/img/man_cld.png" alt="">
<div class="largText">1.6厘米</div>
</div>
<div class="man-box-item">
<img src="../assets/img/woman_cld.png" alt="">
<div class="largText">1厘米</div>
</div>
</div>
</div>
</div>
</el-col>
<el-col :span="8" class="box card fadeIn delay06" style="margin-left: 20px; height: 200px;position:relative;">
<div class="tit">{{choseItem?.name}}人更胖了</div>
<div class="weight-text">
<span>超重肥胖率继续上升</span>
<img src="../assets/img/weight.png" alt="">
</div>
<div class="user-container layout-pd" ref="weightRef" style="height: 200px;"></div>
</el-col>
</el-row>
<div
class="box card fadeIn delay06"
style="height: calc(33.33% - 10px)"
>
<div class="tit">{{choseItem?.name}}人更健康了</div>
<div class="user-container layout-pd" ref="geneRef" style="height: 200px;">
</div>
</div>
</div>
<template #footer>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const dialogVisible = ref(false);
const choseItem = ref<any>({});
import * as echarts from 'echarts';
const show = (item: any) => {
dialogVisible.value = true;
choseItem.value = item;
setTimeout(() => {
setPie();
setCharts();
}, 100);
}
const weightRef = ref();
const geneRef = ref();
const setPie = () => {
var myChart = echarts.init(weightRef.value);
let data = ['成年居民','6-17岁','6岁以下']
// let data1 = ['','','','','','','','','','']
// let data2 = ['','','','','','','','','','']
var option = {
// color: "#04CFE4",
color:{
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: '#00fefb' // 0%
}, {
offset: 1, color: '#0063ce' // 100%
}],
global: false // false
},
grid: {
top: '30%',
left: 10,
right: 0,
bottom: '30%'
},
xAxis: {
type: 'category',
axisTick: false,
axisLine: {
lineStyle: {
color: "rgba(255, 129, 109,.1)",
width: 1, //
},
},
axisLabel: {
interval: 0,
color: '#08DFFE',
// rotate: 30,
fontSize: 12
},
data: data
},
yAxis: {
show: false,
type: 'value',
interval: 1,
axisLine: {
lineStyle: {
color: "rgba(255, 129, 109, 0.1)",
width: 1, //
},
},
axisLabel: {
color: '#fff'
},
splitArea: {
areaStyle: {
color: "rgba(255,255,255,.5)",
},
},
splitLine: {
show: true,
lineStyle: {
color: "rgba(255, 129, 109, 0.1)",
width: 0.5,
type: "dashed",
},
},
},
series: [
{
data: [50, 19, 10.4],
type: 'bar',
barWidth: '40%',
label: {
show: true,
color: "#08DFFE",
fontWeight: "bolder",
fontSize: 12,
position: 'top'
},
}
]
}
myChart.setOption(option);
};
const setCharts = () => {
var myChart = echarts.init(geneRef.value);
let color = ["#0090FF", "#36CE9E", "#FFC005", "#FF515A", "#8B5CFF", "#00CA69"];
let option = {
backgroundColor: 'rgba(0,0,0,0.2)',
color: color,
legend: {
right: 10,
left: 0,
top: 10,
textStyle: {
color: "#fff",
},
},
tooltip: {
trigger: "axis",
formatter: function (params: any) {
let html = "";
params.forEach((v: any) => {
html += `<div style="color: #666;font-size: 14px;line-height: 24px">
<span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
color[v.componentIndex]
};"></span>
${v.seriesName}.${v.name}
<span style="color:${
color[v.componentIndex]
};font-weight:700;font-size: 18px">${v.value}</span>
${v.componentIndex===1?'岁':'%'}`;
});
return html;
},
extraCssText:
"background: #fff; border-radius: 0;box-shadow: 0 0 3px rgba(0, 0, 0, 0.2);color: #333;",
axisPointer: {
type: "shadow",
shadowStyle: {
color: "rgba(0,0,0,.2)",
shadowColor: "rgba(225,225,225,1)",
shadowBlur: 5,
},
},
},
grid: {
top: '10%',
bottom: 0,
containLabel: true,
},
xAxis: [
{
type: "category",
boundaryGap: false,
axisLabel: {
formatter: "{value}年",
rotate: 30,
textStyle: {
color: "#fff",
},
},
axisLine: {
lineStyle: {
color: "#fff",
},
},
data: ["2010", "2011", "2012", "2013", "2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023"],
},
],
yAxis: [
{
type: "value",
name: "单位:万千瓦时",
axisLabel: {
textStyle: {
color: "#fff",
},
},
nameTextStyle: {
color: "#fff",
fontSize: 12,
lineHeight: 40,
},
splitLine: {
show: false
},
axisLine: {
show: false,
},
axisTick: {
show: false,
},
},
],
series: [
{
name: "疫苗接种率",
type: "line",
// smooth: true,
// showSymbol: false,/
symbolSize: 8,
zlevel: 3,
lineStyle: {
normal: {
color: color[0],
shadowBlur: 3,
shadowColor: hexToRgba(color[0], 0.5),
shadowOffsetY: 8,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: hexToRgba(color[0], 0.3),
},
{
offset: 1,
color: hexToRgba(color[0], 0.1),
},
],
false
),
shadowColor: hexToRgba(color[0], 0.1),
shadowBlur: 10,
},
},
data: [72.6, 78.8, 71.3, 83.2, 64.2, 79.2, 85.2, 86.2,84.5, 82.6, 87.2, 88.2, 89.2, 90.2],
},
{
name: "居民人均寿命",
type: "line",
// smooth: true,
// showSymbol: false,
symbolSize: 8,
zlevel: 3,
lineStyle: {
normal: {
color: color[1],
shadowBlur: 3,
shadowColor: hexToRgba(color[1], 0.5),
shadowOffsetY: 8,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: hexToRgba(color[1], 0.3),
},
{
offset: 1,
color: hexToRgba(color[1], 0.1),
},
],
false
),
shadowColor: hexToRgba(color[1], 0.1),
shadowBlur: 10,
},
},
data: [65.4, 68.6, 70.58, 73.2, 73.3, 73.4, 75.6, 73.5, 73.6,76.8, 73.7, 73.8, 73.9, 83.8],
},
{
name: "重大疾病发病率",
type: "line",
// smooth: true,
// showSymbol: false,
symbolSize: 8,
zlevel: 3,
lineStyle: {
normal: {
color: color[2],
shadowBlur: 3,
shadowColor: hexToRgba(color[2], 0.5),
shadowOffsetY: 8,
},
},
areaStyle: {
normal: {
color: new echarts.graphic.LinearGradient(
0,
0,
0,
1,
[
{
offset: 0,
color: hexToRgba(color[2], 0.3),
},
{
offset: 1,
color: hexToRgba(color[2], 0.1),
},
],
false
),
shadowColor: hexToRgba(color[2], 0.1),
shadowBlur: 10,
},
},
data: [45.4, 28.6, 20.58, 13.2, 13.3, 13.4, 25.6, 23.5, 13.6,16.8, 43.7, 3.8, 3.9, 13.8],
},
],
}
myChart.setOption(option);
};
const hexToRgba = (hex: any, opacity: any) => {
let rgbaColor = "";
let reg = /^#[\da-f]{6}$/i;
if (reg.test(hex)) {
rgbaColor = `rgba(${parseInt("0x" + hex.slice(1, 3))},${parseInt(
"0x" + hex.slice(3, 5)
)},${parseInt("0x" + hex.slice(5, 7))},${opacity})`;
}
return rgbaColor;
};
//
defineExpose({ show });
</script>
<style>
.hukou-dialog{
background-color: transparent;
background-image: url(../assets/img/eath.png) ;
background-size: 100% 100%;
}
.hukou-dialog .el-dialog__header {
background: transparent;
color: #00fff7;
}
.hukou-dialog .el-dialog__header .el-dialog__title {
color: #00fff7;
}
.hukou-dialog .el-dialog__footer {
padding: 0;
}
</style>
<style scoped>
.drqk {
display: block;
margin-top: 4%;
}
.weight-text {
position: absolute;
right: 8%;
top: 12%;
color: #bfe0ff;
}
.weight-text img {
width: 40px;
}
.drqk li {
display: inline-block;
margin-top: 10px;
}
.people-content {
display: flex;
justify-content: space-around;
}
.man-box {
display: flex;
justify-content: space-around;
}
.boxnav {
text-align: center;
color: #bfe0ff;
}
.man-box-item img {
width: 50px;
}
.largText {
font-size: 1.2rem;
}
</style>

1
src/vite-env.d.ts

@ -0,0 +1 @@
/// <reference types="vite/client" />

32
tsconfig.json

@ -0,0 +1,32 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
"moduleResolution": "node",
// "paths": {
// "@/*": [
// "src/*"
// ]
// },
// "baseUrl": ".",
/* Bundler mode */
// "moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}

11
tsconfig.node.json

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

56
vite.config.ts

@ -0,0 +1,56 @@
import path from 'path'
import { defineConfig } from 'vite'
import type { Plugin, PluginOption } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import legacy from '@vitejs/plugin-legacy'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import WindiCSS from 'vite-plugin-windicss'
export default defineConfig(({ mode, command }) => {
const isBuild = command === 'build' // 是否是打包环境的判断
const plugins: (Plugin | Plugin[] | PluginOption[])[] = [
vue(),
WindiCSS(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
directoryAsNamespace: true,
}),
createSvgIconsPlugin({
// 指定需要缓存的图标文件夹
iconDirs: [path.resolve(process.cwd(), 'src/assets/svgicons')],
// 指定symbolId格式
symbolId: 'icon-[dir]-[name]',
}),
]
isBuild && plugins.push(legacy()) // 是打包环境,就把legacy()加入到plugins中
return {
plugins,
server: {
      host: '0.0.0.0'
    },
    publicPath: './',
    base: './',
    build: {
      outDir: 'hukou',
      assetsDir: 'assets',
    },
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true,
},
},
},
}
})

4337
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save