Browse Source

初次提交

master
肖正 1 month 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 },