Browse Source

大屏

master
肖正 2 months ago
parent
commit
35ec9813e0
  1. 7
      .env.development
  2. 3
      package.json
  3. 2
      public/config.js
  4. 20
      src/App.vue
  5. 29
      src/api/api.ts
  6. 28
      src/api/other.ts
  7. 7
      src/api/user.ts
  8. BIN
      src/assets/M9.png
  9. BIN
      src/assets/M9_01.png
  10. BIN
      src/assets/M9_02.png
  11. BIN
      src/assets/customer/bg.png
  12. BIN
      src/assets/customer/welcome.png
  13. BIN
      src/assets/customer/xiaozheng.png
  14. 40
      src/assets/font/DIGITAL.TXT
  15. BIN
      src/assets/font/DS-DIGI.TTF
  16. BIN
      src/assets/font/DS-DIGIB.TTF
  17. BIN
      src/assets/font/DS-DIGII.TTF
  18. BIN
      src/assets/font/DS-DIGIT.TTF
  19. BIN
      src/assets/home/bg.jpg
  20. BIN
      src/assets/home/bg01bigindex.png
  21. BIN
      src/assets/home/bg01rightarea.png
  22. BIN
      src/assets/home/bg02bigindex.png
  23. BIN
      src/assets/home/bg05rightarea.png
  24. BIN
      src/assets/home/eath.png
  25. BIN
      src/assets/home/lines1.png
  26. BIN
      src/assets/pdf/ten.pdf
  27. 8
      src/stores/themeConfig.ts
  28. 20
      src/theme/app.scss
  29. 3
      src/theme/dark.scss
  30. 2
      src/utils/request.ts
  31. 79
      src/views/HealthLayout/area.vue
  32. 212
      src/views/HealthLayout/cityPostion.js
  33. 69
      src/views/HealthLayout/index.vue
  34. 154
      src/views/customer/edit.vue
  35. 216
      src/views/customer/index.vue
  36. 427
      src/views/customer/info.vue
  37. 388
      src/views/health.vue
  38. 107
      src/views/home/index.vue
  39. 41
      src/views/home/user.vue
  40. BIN
      src/views/laboratory/img/AGV01.png
  41. BIN
      src/views/laboratory/img/AGV02.png
  42. BIN
      src/views/laboratory/img/M9.png
  43. BIN
      src/views/laboratory/img/incubator.png
  44. BIN
      src/views/laboratory/img/lb.png
  45. BIN
      src/views/laboratory/img/lowerTheTemperature.png
  46. BIN
      src/views/laboratory/img/microscope.png
  47. 6
      src/views/laboratory/laboratory.vue
  48. BIN
      src/views/system/mapManagement/centrifugal.png
  49. BIN
      src/views/system/mapManagement/incubator.png
  50. 38
      src/views/system/mapManagement/index.vue
  51. BIN
      src/views/system/mapManagement/m9.png
  52. 86
      src/views/system/monitor/index.vue
  53. 36
      src/views/system/monitor/mockData.json
  54. 7
      src/views/system/user/index.vue

7
.env.development

@ -2,6 +2,7 @@
ENV = development
# 本地环境接口地址
# VITE_API_URL = http://localhost:5005
VITE_API_URL = http://192.168.88.206:5005
# VITE_API_URL = http://192.168.88.76:5005
VITE_API_URL = http://localhost:5005
# VITE_API_URL = http://192.168.88.206:5005
# VITE_API_URL = http://192.168.88.76:5005
# VITE_API_URL = http://cloud.bodk.com.cn

3
package.json

@ -26,9 +26,11 @@
"echarts-gl": "^2.0.9",
"echarts-wordcloud": "^2.1.0",
"element-plus": "^2.6.1",
"ezuikit-js": "^8.0.6-beta.2",
"js-cookie": "^3.0.5",
"js-table2excel": "^1.1.2",
"jsplumb": "^2.15.6",
"konva": "^9.2.0",
"lodash-es": "^4.17.21",
"mitt": "^3.0.1",
"monaco-editor": "^0.47.0",
@ -44,7 +46,6 @@
"vcrontab-3": "^3.3.22",
"vform3-builds": "^3.0.10",
"vue": "^3.4.21",
"konva": "^9.2.0",
"vue-clipboard3": "^2.0.0",
"vue-demi": "^0.14.7",
"vue-grid-layout": "3.0.0-beta1",

2
public/config.js

@ -3,5 +3,5 @@ window.__env__ = {
"VITE_OPEN": "false",
"VITE_OPEN_CDN": "false",
"VITE_PUBLIC_PATH": "",
"VITE_API_URL": "http://192.168.88.206:5005"
"VITE_API_URL": "http://localhost:5005"
}

20
src/App.vue

@ -22,6 +22,10 @@ import mittBus from '/@/utils/mitt';
import setIntroduction from '/@/utils/setIconfont';
// import checkUpdate from '/@/utils/auto-update';
import { SysOrgApi } from '/@/api-services/api';
//
const getThemeConfig = computed(() => {
return themeConfig.value;
});
//
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
@ -107,6 +111,22 @@ watch(
() => route.path,
() => {
other.useTitle();
let routeList = ['HealthLayout', 'home', 'health', 'monitor'];
let i = routeList.indexOf(route.name.toString());
const body = document.documentElement as HTMLElement;
if (getThemeConfig.value.isIsDark) {
if (i < 0){
body.setAttribute('data-theme', '');
themeConfig.value.isIsDark = false;
}
}
else {
if (i > -1){
body.setAttribute('data-theme', 'dark');
themeConfig.value.isIsDark = true;
}
}
console.log(8888, route.name )
},
{
deep: true,

29
src/api/api.ts

@ -0,0 +1,29 @@
import request from '/@/utils/request';
export function getList(api, data) {
return request({
url: `/api/${api}/getList`,
method: 'post',
data,
});
}
export function add(api, data) {
return request({
url: `/api/${api}/add`,
method: 'post',
data,
});
}
export function update(api, data) {
return request({
url: `/api/${api}/update`,
method: 'post',
data,
});
}
export function del(api, id) {
return request({
url: `/api/${api}/delete/${id}`,
method: 'post',
});
}

28
src/api/other.ts

@ -0,0 +1,28 @@
import request from '/@/utils/request';
// import type { ResultData } from './common';
export function getDeviceInfo() {
return request({
baseURL: 'http://39.108.191.53:8089',
url: '/api/v1/device?page=1&limit=20',
method: 'get',
});
}
export function getEZUIKitToken(data) {
return request({
baseURL: 'https://open.ys7.com',
url: '/api/lapp/token/get',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
method: 'post',
data,
});
}
// export function list(params: any) {
// return request({
// eslint-disable-next-line no-irregular-whitespace
//       url: "/list",
// method: "get",
// params,
// });
// }

7
src/api/user.ts

@ -7,13 +7,6 @@ export function getAddInfo() {
method: 'get',
});
}
export function getDeviceInfo() {
return request({
baseURL: 'http://39.108.191.53:8089',
url: '/api/v1/device?page=1&limit=20',
method: 'get',
});
}
// export function list(params: any) {
// return request({
// eslint-disable-next-line no-irregular-whitespace

BIN
src/assets/M9.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 MiB

After

Width:  |  Height:  |  Size: 670 KiB

BIN
src/assets/M9_01.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 918 KiB

BIN
src/assets/M9_02.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

BIN
src/assets/customer/bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
src/assets/customer/welcome.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/assets/customer/xiaozheng.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

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/home/bg.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 KiB

After

Width:  |  Height:  |  Size: 62 KiB

BIN
src/assets/home/bg01bigindex.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
src/assets/home/bg01rightarea.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
src/assets/home/bg02bigindex.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/assets/home/bg05rightarea.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
src/assets/home/eath.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 KiB

BIN
src/assets/home/lines1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 KiB

After

Width:  |  Height:  |  Size: 27 KiB

BIN
src/assets/pdf/ten.pdf

Binary file not shown.

8
src/stores/themeConfig.ts

@ -20,7 +20,7 @@ export const useThemeConfig = defineStore('themeConfig', {
// 默认 primary 主题颜色
primary: '#11559C', //红色:#DE2910 //蓝色:#11559C //绿色:#057748
// 是否开启深色模式
isIsDark: false,
isIsDark: true,
/**
*
@ -30,7 +30,7 @@ export const useThemeConfig = defineStore('themeConfig', {
// 默认顶栏导航字体颜色
topBarColor: '#000000',
// 是否开启顶栏背景颜色渐变
isTopBarColorGradual: false,
isTopBarColorGradual: true,
/**
*
@ -42,7 +42,7 @@ export const useThemeConfig = defineStore('themeConfig', {
// 默认菜单高亮背景色
menuBarActiveColor: 'var(--el-color-primary-light-7)',
// 是否开启菜单背景颜色渐变
isMenuBarColorGradual: false,
isMenuBarColorGradual: true,
/**
*
@ -125,7 +125,7 @@ export const useThemeConfig = defineStore('themeConfig', {
* `initSetLayoutChange(设置布局切换,重置主题样式)`
*/
// 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults
layout: 'classic',
layout: 'transverse',
/**
*

20
src/theme/app.scss

@ -336,3 +336,23 @@ body,
padding-left: #{$i}px !important;
}
}
.avatar-uploader .el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
transition: var(--el-transition-duration-fast);
}
.avatar-uploader .el-upload:hover {
border-color: var(--el-color-primary);
}
.el-icon.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
text-align: center;
}

3
src/theme/dark.scss

@ -71,6 +71,9 @@
border-color: var(--next-border-color) !important;
}
}
.el-tag.el-tag--primary {
--el-tag-text-color: var(--next-color-white) !important;
}
.el-button--primary,
.el-button--info,
.el-button--danger,

2
src/utils/request.ts

@ -119,7 +119,7 @@ service.interceptors.response.use(
clearAccessTokens();
} else if (serve.code === undefined) {
return Promise.resolve(res);
} else if (serve.code !== 200) {
} else if (serve.code != 200) {
var message;
// 判断 serve.message 是否为对象
if (serve.message && typeof serve.message == 'object') {

79
src/views/HealthLayout/area.vue

@ -30,85 +30,10 @@
</template>
<script setup lang="ts" name="area">
import { ref } from 'vue'
import { mockData, mockData2 } from './cityPostion'
const activeNames = ref(['广州'])
//
let mockData = [
{ area: '华南区域', list: [
{city: '广州', list: [{name: '白云健康中心', value: 245223},{name: '海珠健康中心', value: 245223},{name: '天河健康中心', value: 245223},
{name: '增城健康中心', value: 245223},{name: '番禺健康中心', value: 245223},{name: '花都健康中心', value: 245223},
]},
{city: '佛山', list: [{name: '顺德健康中心', value: 245223},{name: '禅城健康中心', value: 245223},]},
{city: '深圳', list: [{name: '福田健康中心', value: 245223},{name: '罗湖健康中心', value: 245223},{name: '南山健康中心', value: 245223},
{name: '盐田健康中心', value: 245223},{name: '保安健康中心', value: 245223},{name: '龙岗健康中心', value: 245223},
]},
{city: '珠海', list: [{name: '香洲健康中心', value: 245223},{name: '斗门健康中心', value: 245223},{name: '金湾健康中心', value: 245223},]},
{city: '东莞', list: [{name: '东城健康中心', value: 245223},{name: '南城健康中心', value: 245223},{name: '万江健康中心', value: 245223},
{name: '莞城健康中心', value: 245223},{name: '松山湖健康中心', value: 245223},{name: '寮步健康中心', value: 245223},
{name: '常平健康中心', value: 245223},{name: '樟木头健康中心', value: 245223},{name: '虎门健康中心', value: 245223},
]},
{city: '河源', list: [{name: '河源健康中心', value: 245223},]},
{city: '肇庆', list: [{name: '肇庆健康中心', value: 245223},]},
{city: '汕头', list: [{name: '汕头健康中心', value: 245223},]},
{city: '梅州', list: [{name: '梅州健康中心', value: 245223},]},
{city: '韶关', list: [{name: '韶关健康中心', value: 245223},]},
{city: '南宁', list: [{name: '南宁健康中心', value: 245223},]},
{city: '三亚', list: [{name: '海棠健康中心', value: 245223},{name: '吉阳健康中心', value: 245223},{name: '天涯健康中心', value: 245223},
{name: '崖州健康中心', value: 245223},
]},
{city: '海口', list: [{name: '海口健康中心', value: 245223},]},
{city: '香港', list: [{name: '湾仔健康中心', value: 245223},{name: '九龙健康中心', value: 245223},]},
{city: '澳门', list: [{name: '澳门健康中心', value: 245223},]},
]},
{ area: '东北区域', list: [
{city: '沈阳', list: [{name: '铁西健康中心', value: 245223},{name: '辽中健康中心', value: 245223},]},
{city: '长春', list: [{name: '长春健康中心', value: 245223},]},
{city: '哈尔滨', list: [{name: '哈尔滨健康中心', value: 245223},]},
]},
{ area: '西北区域', list: [
{city: '西安', list: [{name: '西安健康中心', value: 245223}]},
]},
{ area: '华北区域', list: [
{city: '北京', list: [{name: '东城健康中心', value: 245223},{name: '西城健康中心', value: 245223},{name: '朝阳健康中心', value: 245223},{name: '海淀健康中心', value: 245223},
{name: '通州健康中心', value: 245223},{name: '大兴健康中心', value: 245223},{name: '丰台健康中心', value: 245223},
]},
{city: '天津', list: [{name: '和平健康中心', value: 245223},{name: '河东健康中心', value: 245223},{name: '河西健康中心', value: 245223},]},
{city: '呼和浩特', list: [{name: '呼和浩特健康中心', value: 245223}]},
{city: '石家庄', list: [{name: '石家庄健康中心', value: 245223},]},
]},
];
let mockData2 = [
{ area: '华中区域', list: [
{city: '武汉', list: [{name: '武昌健康中心', value: 245223},{name: '汉口健康中心', value: 245223},{name: '汉阳健康中心', value: 245223},]},
{city: '长沙', list: [{name: '雨花健康中心', value: 245223},{name: '芙蓉健康中心', value: 245223},]},
{city: '郑州', list: [{name: '郑州健康中心', value: 245223},]},
]},
{ area: '西南区域', list: [
{city: '成都', list: [{name: '景江健康中心', value: 245223},{name: '成华健康中心', value: 245223},]},
{city: '重庆', list: [{name: '重庆健康中心', value: 245223},]},
{city: '昆明', list: [{name: '昆明健康中心', value: 245223},]},
{city: '贵阳', list: [{name: '贵阳健康中心', value: 245223},]},
]},
{ area: '华东区域', list: [
{city: '上海', list: [{name: '黄埔健康中心', value: 245223},{name: '徐汇健康中心', value: 245223},{name: '静安健康中心', value: 245223},
{name: '普陀健康中心', value: 245223},{name: '宝山健康中心', value: 245223},{name: '浦东健康中心', value: 245223},
]},
{city: '苏州', list: [{name: '姑苏健康中心', value: 245223},{name: '吴中健康中心', value: 245223},]},
{city: '杭州', list: [{name: '余杭健康中心', value: 245223},{name: '西湖健康中心', value: 245223},]},
{city: '南昌', list: [{name: '南昌健康中心', value: 245223},]},
{city: '厦门', list: [{name: '厦门健康中心', value: 245223},]},
{city: '宁波', list: [{name: '宁波健康中心', value: 245223},]},
{city: '合肥', list: [{name: '合肥健康中心', value: 245223},]},
{city: '南京', list: [{name: '玄武健康中心', value: 245223},{name: '秦淮健康中心', value: 245223},{name: '建业健康中心', value: 245223},]},
{city: '青岛', list: [{name: '青岛健康中心', value: 245223},]},
{city: '福州', list: [{name: '福州健康中心', value: 245223},]},
{city: '温州', list: [{name: '温州健康中心', value: 245223},]},
{city: '济南', list: [{name: '济南健康中心', value: 245223},]},
{city: '无锡', list: [{name: '无锡健康中心', value: 245223},]},
{city: '泉州', list: [{name: '泉州健康中心', value: 245223},]},
{city: '南通', list: [{name: '通州健康中心', value: 245223},]},
]},
]
</script>
<style lang="scss">

212
src/views/HealthLayout/cityPostion.js

@ -35,6 +35,218 @@ const positionArr = [
{ name: '江苏', value: ['118.7727814', '32.0476151'] },
];
export const mockData = [
{
area: '华南区域',
list: [
{
city: '广州',
list: [
{ name: '白云健康中心', value: 245223 },
{ name: '海珠健康中心', value: 245223 },
{ name: '天河健康中心', value: 245223 },
{ name: '增城健康中心', value: 245223 },
{ name: '番禺健康中心', value: 245223 },
{ name: '花都健康中心', value: 245223 },
],
},
{
city: '佛山',
list: [
{ name: '顺德健康中心', value: 245223 },
{ name: '禅城健康中心', value: 245223 },
],
},
{
city: '深圳',
list: [
{ name: '福田健康中心', value: 245223 },
{ name: '罗湖健康中心', value: 245223 },
{ name: '南山健康中心', value: 245223 },
{ name: '盐田健康中心', value: 245223 },
{ name: '保安健康中心', value: 245223 },
{ name: '龙岗健康中心', value: 245223 },
],
},
{
city: '珠海',
list: [
{ name: '香洲健康中心', value: 245223 },
{ name: '斗门健康中心', value: 245223 },
{ name: '金湾健康中心', value: 245223 },
],
},
{
city: '东莞',
list: [
{ name: '东城健康中心', value: 245223 },
{ name: '南城健康中心', value: 245223 },
{ name: '万江健康中心', value: 245223 },
{ name: '莞城健康中心', value: 245223 },
{ name: '松山湖健康中心', value: 245223 },
{ name: '寮步健康中心', value: 245223 },
{ name: '常平健康中心', value: 245223 },
{ name: '樟木头健康中心', value: 245223 },
{ name: '虎门健康中心', value: 245223 },
],
},
{ city: '河源', list: [{ name: '河源健康中心', value: 245223 }] },
{ city: '肇庆', list: [{ name: '肇庆健康中心', value: 245223 }] },
{ city: '汕头', list: [{ name: '汕头健康中心', value: 245223 }] },
{ city: '梅州', list: [{ name: '梅州健康中心', value: 245223 }] },
{ city: '韶关', list: [{ name: '韶关健康中心', value: 245223 }] },
{ city: '南宁', list: [{ name: '南宁健康中心', value: 245223 }] },
{
city: '三亚',
list: [
{ name: '海棠健康中心', value: 245223 },
{ name: '吉阳健康中心', value: 245223 },
{ name: '天涯健康中心', value: 245223 },
{ name: '崖州健康中心', value: 245223 },
],
},
{ city: '海口', list: [{ name: '海口健康中心', value: 245223 }] },
{
city: '香港',
list: [
{ name: '湾仔健康中心', value: 245223 },
{ name: '九龙健康中心', value: 245223 },
],
},
{ city: '澳门', list: [{ name: '澳门健康中心', value: 245223 }] },
],
},
{
area: '东北区域',
list: [
{
city: '沈阳',
list: [
{ name: '铁西健康中心', value: 245223 },
{ name: '辽中健康中心', value: 245223 },
],
},
{ city: '长春', list: [{ name: '长春健康中心', value: 245223 }] },
{ city: '哈尔滨', list: [{ name: '哈尔滨健康中心', value: 245223 }] },
],
},
{ area: '西北区域', list: [{ city: '西安', list: [{ name: '西安健康中心', value: 245223 }] }] },
{
area: '华北区域',
list: [
{
city: '北京',
list: [
{ name: '东城健康中心', value: 245223 },
{ name: '西城健康中心', value: 245223 },
{ name: '朝阳健康中心', value: 245223 },
{ name: '海淀健康中心', value: 245223 },
{ name: '通州健康中心', value: 245223 },
{ name: '大兴健康中心', value: 245223 },
{ name: '丰台健康中心', value: 245223 },
],
},
{
city: '天津',
list: [
{ name: '和平健康中心', value: 245223 },
{ name: '河东健康中心', value: 245223 },
{ name: '河西健康中心', value: 245223 },
],
},
{ city: '呼和浩特', list: [{ name: '呼和浩特健康中心', value: 245223 }] },
{ city: '石家庄', list: [{ name: '石家庄健康中心', value: 245223 }] },
],
},
];
export const mockData2 = [
{
area: '华中区域',
list: [
{
city: '武汉',
list: [
{ name: '武昌健康中心', value: 245223 },
{ name: '汉口健康中心', value: 245223 },
{ name: '汉阳健康中心', value: 245223 },
],
},
{
city: '长沙',
list: [
{ name: '雨花健康中心', value: 245223 },
{ name: '芙蓉健康中心', value: 245223 },
],
},
{ city: '郑州', list: [{ name: '郑州健康中心', value: 245223 }] },
],
},
{
area: '西南区域',
list: [
{
city: '成都',
list: [
{ name: '景江健康中心', value: 245223 },
{ name: '成华健康中心', value: 245223 },
],
},
{ city: '重庆', list: [{ name: '重庆健康中心', value: 245223 }] },
{ city: '昆明', list: [{ name: '昆明健康中心', value: 245223 }] },
{ city: '贵阳', list: [{ name: '贵阳健康中心', value: 245223 }] },
],
},
{
area: '华东区域',
list: [
{
city: '上海',
list: [
{ name: '黄埔健康中心', value: 245223 },
{ name: '徐汇健康中心', value: 245223 },
{ name: '静安健康中心', value: 245223 },
{ name: '普陀健康中心', value: 245223 },
{ name: '宝山健康中心', value: 245223 },
{ name: '浦东健康中心', value: 245223 },
],
},
{
city: '苏州',
list: [
{ name: '姑苏健康中心', value: 245223 },
{ name: '吴中健康中心', value: 245223 },
],
},
{
city: '杭州',
list: [
{ name: '余杭健康中心', value: 245223 },
{ name: '西湖健康中心', value: 245223 },
],
},
{ city: '南昌', list: [{ name: '南昌健康中心', value: 245223 }] },
{ city: '厦门', list: [{ name: '厦门健康中心', value: 245223 }] },
{ city: '宁波', list: [{ name: '宁波健康中心', value: 245223 }] },
{ city: '合肥', list: [{ name: '合肥健康中心', value: 245223 }] },
{
city: '南京',
list: [
{ name: '玄武健康中心', value: 245223 },
{ name: '秦淮健康中心', value: 245223 },
{ name: '建业健康中心', value: 245223 },
],
},
{ city: '青岛', list: [{ name: '青岛健康中心', value: 245223 }] },
{ city: '福州', list: [{ name: '福州健康中心', value: 245223 }] },
{ city: '温州', list: [{ name: '温州健康中心', value: 245223 }] },
{ city: '济南', list: [{ name: '济南健康中心', value: 245223 }] },
{ city: '无锡', list: [{ name: '无锡健康中心', value: 245223 }] },
{ city: '泉州', list: [{ name: '泉州健康中心', value: 245223 }] },
{ city: '南通', list: [{ name: '通州健康中心', value: 245223 }] },
],
},
];
export function getCityPositionByName(name) {
return positionArr.find((item) => item.name === name);
}

69
src/views/HealthLayout/index.vue

@ -1,6 +1,6 @@
<template>
<div class="HealthLayout-box">
<h1 class="title">博工未来健康产业生态体系实体布局图</h1>
<h1 class="title">未来健康产业生态体系布局图</h1>
<el-row ref="mapBox" :style="{height: height+'px'}" style="margin-left: 30px;overflow: hidden;">
<el-col :span="8" class="area-box">
<Area />
@ -19,24 +19,24 @@
</template>
<script lang="ts" setup name="HealthLayout">
import { onMounted, reactive, computed, ref, onBeforeUnmount } from 'vue';
import { ElMessage } from 'element-plus';
import { onMounted, reactive, ref } from 'vue';
// import { ElMessage } from 'element-plus';
import './china';
const mapBox = ref(null);
let height = ref(0);
import * as echarts from 'echarts';
import Area from './area.vue';
import { getCityPositionByName } from './cityPostion'
import { getCityPositionByName, } from './cityPostion'
import { useRouter } from 'vue-router';
const router = useRouter();
// 10
let mockData = [
{ name: '北京', value: 500 },
{ name: '天津', value: 200 },
{ name: '河南', value: 300 },
{ name: '广西', value: 300 },
{ name: '广东', value: 300 },
{ name: '河北', value: 300 },
{ name: '北京', value: 11500 },
{ name: '天津', value: 1200 },
{ name: '河南', value: 2300 },
{ name: '广西', value: 1300 },
{ name: '广东', value: 9300 },
{ name: '河北', value: 5300 },
];
const state = reactive({
loading: false,
@ -59,6 +59,16 @@ const init = async () => {
value: cityPosition.concat(i.value),
}
})
// let data = (mockData.concat(mockData2)).map(i => {
// return i.list.map(item => {
// let cityPosition = getCityPositionByName(item.city)?.value
// return cityPosition ? {
// name: item.city,
// value: cityPosition.concat(item.value || 0),
// } : null;
// })
// })
// console.log(88888, data);
let initMap = echarts.init(document.querySelector('#mapDom'))
initMap.on('click', mapClick);
@ -158,31 +168,30 @@ const init = async () => {
},
},
z: 2,
data: data,
},
{
type: 'scatter',
coordinateSystem: 'geo',
symbol: 'pin',
symbolSize: [50, 50],
label: {
show: true,
color: '#fff',
formatter(value) {
return value.data.value[2]
},
},
itemStyle: {
color: '#e30707', //
},
z: 2,
data: data,
// data: data,
},
// {
// type: 'scatter',
// coordinateSystem: 'geo',
// symbol: 'pin',
// symbolSize: [50, 50],
// label: {
// show: true,
// color: '#fff',
// formatter(value) {
// return value.data.value[2]
// },
// },
// itemStyle: {
// color: '#e30707', //
// },
// z: 2,
// data: data,
// },
],
})
}
const mapClick = (item) => {
// console.log(88888, item);
router.push({name: 'home', query: {name: item.name}});
}
</script>

154
src/views/customer/edit.vue

@ -0,0 +1,154 @@
<template>
<div class="sys-menu-container">
<el-dialog v-model="state.isShowDialog" draggable :close-on-click-modal="false" width="500px">
<template #header>
<div style="color: #fff">
<el-icon size="16" style="margin-right: 3px; display: inline; vertical-align: middle"> <ele-Edit /> </el-icon>
<span> {{ props.title }} </span>
</div>
</template>
<el-form :model="state.ruleForm" ref="ruleFormRef" label-width="auto">
<el-row :gutter="35">
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="客户名称" prop="name" :rules="[{ required: true, message: '客户名称不能为空', trigger: 'blur' }]">
<el-input v-model="state.ruleForm.name" placeholder="客户名称" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="客户电话" prop="phone" :rules="[{ required: true, message: '客户电话不能为空', trigger: 'blur' }]">
<el-input v-model="state.ruleForm.phone" placeholder="客户电话" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="性别" prop="isMale" :rules="[{ required: true, message: '性别不能为空', trigger: 'blur' }]">
<el-radio-group v-model="state.ruleForm.isMale">
<el-radio :value="false"></el-radio>
<el-radio :value="true"></el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="身份证号">
<el-input v-model="state.ruleForm.idCard" placeholder="身份证号" clearable />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="备注">
<el-input v-model="state.ruleForm.remark" placeholder="请输入备注内容" clearable type="textarea" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="个人形象照">
<el-upload
class="avatar-uploader"
:action="baseUrl+'/api/sysFile/uploadFile'"
:show-file-list="false"
:headers="{Authorization: `Bearer ${state.token}`}"
:on-success="handleAvatarSuccess"
>
<img v-if="state.ruleForm.imageUrl" :src="state.ruleForm.imageUrl" class="avatar" />
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
</el-upload>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
<el-form-item label="声音">
<el-upload
v-model:file-list="fileList"
class="upload-demo"
:action="baseUrl+'/api/sysFile/uploadFile'"
multiple
:headers="{Authorization: `Bearer ${state.token}`}"
:on-success="handleSuccess"
:on-remove="handleRemove"
:limit="1"
>
<el-button type="primary">点击上传</el-button>
</el-upload>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="cancel"> </el-button>
<el-button type="primary" @click="submit"> </el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="sysEdit">
import { reactive, ref } from 'vue';
import { add, update } from '/@/api/api';
import type { UploadProps, UploadUserFile } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { Local } from '/@/utils/storage';
const props = defineProps({
title: String,
});
const baseUrl = window.__env__.VITE_API_URL
const fileList = ref<UploadUserFile[]>([])
const emits = defineEmits(['handleQuery']);
const ruleFormRef = ref();
const state = reactive({
isShowDialog: false,
dialogUploadVisible: false,
ruleForm: {} as any,
token: Local.get('access-token')
});
//
const openDialog = (row: any) => {
state.ruleForm = JSON.parse(JSON.stringify(row));
state.isShowDialog = true;
ruleFormRef.value?.resetFields();
};
const handleRemove: UploadProps['onRemove'] = (file, uploadFiles) => {
console.log(file, uploadFiles)
}
const handleSuccess: UploadProps['onSuccess'] = (uploadFile) => {
// console.log(98, uploadFile)
state.ruleForm.voiceUrl = uploadFile?.result?.url;
}
//
const closeDialog = () => {
emits('handleQuery');
state.isShowDialog = false;
};
const handleAvatarSuccess: UploadProps['onSuccess'] = (
response
) => {
state.ruleForm.imageUrl = response?.result?.url;
}
//
const cancel = () => {
state.isShowDialog = false;
};
//
const submit = () => {
ruleFormRef.value.validate(async (valid: boolean) => {
if (!valid) return;
if (state.ruleForm.id != undefined && state.ruleForm.id > 0) {
await update('customer', state.ruleForm);
} else {
await add('customer', state.ruleForm);
}
closeDialog();
});
};
//
defineExpose({ openDialog });
</script>
<style scoped>
.avatar-uploader .avatar {
width: 178px;
height: 178px;
display: block;
}
</style>

216
src/views/customer/index.vue

@ -0,0 +1,216 @@
<template>
<div class="customer-box">
<el-card shadow="hover" :body-style="{ paddingBottom: '0' }">
<el-form :model="state.queryParams" ref="queryForm" :inline="true">
<el-form-item label="客户名称">
<el-input v-model="state.queryParams.name" placeholder="客户名称" clearable />
</el-form-item>
<el-form-item label="客户电话">
<el-input v-model="state.queryParams.phone" placeholder="客户电话" clearable />
</el-form-item>
<el-form-item>
<el-button-group>
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysMenu:list'"> 查询 </el-button>
<el-button icon="ele-Refresh" @click="resetQuery"> 重置 </el-button>
</el-button-group>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="ele-Plus" @click="openAddMenu" v-auth="'sysMenu:add'"> 新增 </el-button>
<!-- <el-button type="primary" icon="ele-Plus" @click="openInfo({})" v-auth="'sysMenu:add'"> 新增 </el-button> -->
</el-form-item>
</el-form>
</el-card>
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<el-table :data="state.tableData" v-loading="state.loading" row-key="id" border>
<el-table-column prop="name" label="客户名称" align="center" show-overflow-tooltip />
<el-table-column label="形象" width="150" align="center" show-overflow-tooltip>
<template #default="scope">
<el-image style="width: 50px" v-if="scope.row.imageUrl" :src="scope.row.imageUrl" fit="contain" />
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column prop="phone" label="客户电话" align="center" show-overflow-tooltip />
<el-table-column prop="idCard" label="身份证号" align="center" show-overflow-tooltip />
<el-table-column label="性别" width="150" align="center" show-overflow-tooltip>
<template #default="scope">
<el-tag type="success" v-if="scope.row.isMale"></el-tag>
<el-tag type="primary" v-else></el-tag>
</template>
</el-table-column>
<el-table-column label="修改记录" width="200" align="center" show-overflow-tooltip>
<template #default="scope">
<el-popover placement="bottom" width="280" trigger="hover">
<template #reference>
<el-text type="primary">
<el-icon><ele-InfoFilled /></el-icon>
</el-text>
</template>
<el-descriptions direction="vertical" :column="2" border>
<el-descriptions-item width="140">
<template #label>
<el-text>
<el-icon><ele-UserFilled /></el-icon>
</el-text>
</template>
<el-tag>{{ scope.row.createUserName ?? '无' }}</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<el-text>
<el-icon><ele-Calendar /></el-icon>
</el-text>
</template>
<el-tag>{{ scope.row.createTime ?? '无' }}</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<el-text>
<el-icon><ele-UserFilled /></el-icon>
</el-text>
</template>
<el-tag>{{ scope.row.updateUserName ?? '无' }}</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<el-text>
<el-icon><ele-Calendar /></el-icon>
</el-text>
</template>
<el-tag>{{ scope.row.updateTime ?? '无' }}</el-tag>
</el-descriptions-item>
<el-descriptions-item>
<template #label>
<el-text>
<el-icon><ele-Tickets /></el-icon>
</el-text>
</template>
{{ scope.row.remark }}
</el-descriptions-item>
</el-descriptions>
</el-popover>
</template>
</el-table-column>
<el-table-column label="操作" width="200" fixed="right" align="center" show-overflow-tooltip>
<template #default="scope">
<el-button icon="ele-Edit" size="small" text type="primary" @click="openInfo(scope.row)" v-auth="'sysMenu:update'"> 详情 </el-button>
<el-button icon="ele-Edit" size="small" text type="primary" @click="openEditMenu(scope.row)" v-auth="'sysMenu:update'"> 编辑 </el-button>
<el-button icon="ele-Delete" size="small" text type="danger" @click="delMenu(scope.row)" v-auth="'sysMenu:delete'"> 删除 </el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
v-model:currentPage="state.tableParams.page"
v-model:page-size="state.tableParams.pageSize"
:total="state.tableParams.total"
:page-sizes="[10, 20, 50, 100]"
small
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
layout="total, sizes, prev, pager, next, jumper"
/>
</el-card>
<EditCustomer ref="editRef" :title="state.editTitle" @handleQuery="handleQuery" />
<CustomerInfo ref="infoRef" :title="state.infoTitle" @handleQuery="handleQuery" />
</div>
</template>
<script lang="ts" setup name="customer" >
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import EditCustomer from './edit.vue';
import CustomerInfo from './info.vue';
import { SysMenu } from '/@/api-services/models';
import { getList, del } from '../../api/api';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig';
const storesThemeConfig = useThemeConfig();
const { themeConfig } = storeToRefs(storesThemeConfig);
const editRef = ref();
const infoRef = ref();
const state = reactive({
loading: false,
tableData: [] as Array<SysMenu>,
queryParams: {
name: undefined,
phone: undefined,
},
tableParams: {
page: 1,
pageSize: 10,
total: 0 as any,
},
editTitle: '',
infoTitle: '',
});
onMounted(async () => {
console.log(888, themeConfig.value.isIsDark)
themeConfig.value.isIsDark = false;
handleQuery();
});
//
const handleQuery = async () => {
state.loading = true;
let params = Object.assign(state.queryParams, state.tableParams);
var res = await getList('customer', params);
state.tableData = res.data.result?.items ?? [];
state.tableParams.total = res.data.result?.total;
state.loading = false;
};
//
const resetQuery = () => {
state.queryParams.name = undefined;
state.queryParams.phone = undefined;
handleQuery();
};
//
const openAddMenu = () => {
state.editTitle = '添加客户';
editRef.value?.openDialog({ type: 2, isHide: false, isKeepAlive: true, isAffix: false, isIframe: false, status: 1, orderNo: 100 });
};
//
const openEditMenu = (row: any) => {
state.editTitle = '编辑客户';
editRef.value?.openDialog(row);
};
const openInfo = (row: any) => {
state.infoTitle = `${row.name} 的数字生命`;
infoRef.value?.openDrawer(row);
};
//
const delMenu = (row: any) => {
ElMessageBox.confirm(`确定删除客户:【${row.name}】?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
})
.then(async () => {
await del('customer', row.id );
handleQuery();
ElMessage.success('删除成功');
})
.catch(() => {});
};
//
const handleSizeChange = (val: number) => {
state.tableParams.pageSize = val;
handleQuery();
};
//
const handleCurrentChange = (val: number) => {
state.tableParams.page = val;
handleQuery();
};
</script>
<style scoped lang="scss">
$color: rgb(211, 130, 50);
</style>

427
src/views/customer/info.vue

@ -0,0 +1,427 @@
<template>
<el-drawer v-model="drawer" :direction="direction" class="cursor-info" size="100%">
<template #default>
<div class="orido_tm_hero">
<div class="close-box" @click="closeDrawer">
<el-icon class="info-close"><CloseBold /></el-icon>
</div>
<div class="container">
<div class="title-heading">
<div class="alert">
<span class="badge">Hot</span>
<span class="content">生命数据库</span>
</div>
<h1 class="heading">肖正的生命数据库</h1>
<p class="pera-title">Obviously I'm a Web Designer. Web Developer with over 3 years of experience. Experienced with all stages of the development</p>
<div class="hero-btn">
<el-button type="primary" size="default">体检报告</el-button>
<el-button size="default">细胞储存信息</el-button>
</div>
</div>
<img src="/@/assets/customer/xiaozheng.png" class="author" alt="">
<div class="video_button">
<a class="popup-youtube" href="https://www.youtube.com/watch?v=7e90gBu4pas">
<img class="anim_circle" src="/@/assets/customer/welcome.png" alt="">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="25" viewBox="0 0 20 25" fill="none" class="svg replaced-svg">
<path d="M0.693848 0.149658V24.7257L19.3059 12.4377L0.693848 0.149658Z" fill="white"></path>
</svg>
</a>
</div>
</div>
</div>
<div class="section bg-light">
<div class="container">
<div class="container-title">
<h2>体检报告</h2>
<p class="pera-title">体检时间2024-07-31体检机构东莞松山湖基地</p>
</div>
<div class="content-box">
<div class="content-item" v-for="(item, i) in 6" :key="i">
<div class="feature-widget">
<div style="margin-bottom: 16px;">
<el-icon size="38" class="info-icon"><House /></el-icon>
</div>
<h3>肝癌</h3>
<p class="text-light-muted">中国人群肝癌平均遗传风险为 22.2您的遗传风险值为 10 是平均遗传风险的0.45 处于较低风险2 </p>
<p>遗传相对风险指数<span>0.8</span></p>
<p>遗传相对风险等级<span>略低</span></p>
</div>
</div>
</div>
</div>
</div>
<div class="device-box">
<div class="container">
<el-carousel :interval="5000" height="600px" @change="changeImg" indicator-position="outside">
<el-carousel-item v-for="(item,index) in state.images" :key="index">
<el-row class="device-box-item">
<el-col :span="9" class="cold-storage-content">
<el-image
style="height:60%; margin-top: 30%"
:src="item.idView"
fit="fit"></el-image>
<div class="cold-storage-content-tips" style="top: 210px; left: 0;">
<span class="cold-storage-content-tips-text">密封腔湿度{{ m9Msg.humidity }}</span>
<span class="cold-storage-content-tips-line blue" style="width: 20px;"></span>
</div>
<div class="cold-storage-content-tips" style="top: 270px; left: 0;">
<span class="cold-storage-content-tips-text">液氮上限 195mm</span>
<span class="cold-storage-content-tips-line red"></span>
</div>
<div class="cold-storage-content-tips" style="top: 340px; left: 0">
<span class="cold-storage-content-tips-text">液氮下限 125mm</span>
<span class="cold-storage-content-tips-line red"></span>
</div>
<div class="cold-storage-content-tips" style="top: 210px; right: -10%;">
<span class="cold-storage-content-tips-line blue"></span>
<span class="cold-storage-content-tips-text">{{m9Msg.top}}</span>
</div>
<div class="cold-storage-content-tips" style="top: 270px; right: -10%;">
<span class="cold-storage-content-tips-line blue"></span>
<span class="cold-storage-content-tips-text">{{m9Msg.center}}</span>
</div>
<div class="cold-storage-content-tips" style="top: 340px; right: -10%;">
<span class="cold-storage-content-tips-line blue"></span>
<span class="cold-storage-content-tips-text">{{m9Msg.bottom}}</span>
</div>
<div>
<span>液氮高度{{ item.height }} mm</span>
<span style="margin-left: 60px;" class="">转运区<span :style="{color: item.status === 0?'red':'green'}">{{item.status === 0?'无桶':'有桶'}}</span></span>
</div>
</el-col>
<el-col :span="15" class="cta-full-img-box">
<h4>造血干细胞</h4>
<p style="margin-bottom: 30px;" class="text-light-muted">广东省东莞市松山湖园区科技二路宏远新智汇1栋</p>
<p style="text-align: left;">操作记录</p>
<el-table :data="tableData" style="width: 100%" height="260" stripe>
<el-table-column type="index" label="序号" width="60" />
<el-table-column prop="type" label="类型" />
<el-table-column prop="operator" label="操作员" />
<el-table-column prop="time" label="操作时间" />
</el-table>
</el-col>
</el-row>
</el-carousel-item>
</el-carousel>
</div>
</div>
</template>
<!-- <template #footer>
<div style="flex: auto">
<el-button @click="closeDrawer">cancel</el-button>
<el-button type="primary" @click="confirmClick">confirm</el-button>
</div>
</template> -->
</el-drawer>
</template>
<script lang="ts" setup name="customerInfo">
import { ref, reactive, computed } from 'vue'
import { ElMessageBox, } from 'element-plus'
import { House, CloseBold } from '@element-plus/icons-vue'
import type { DrawerProps } from 'element-plus'
import imgUrl from '/@/assets/M9.png'
const props = defineProps({
title: String,
});
const tableData = [
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
{type: '取出', operator: '黄志峰', time: '2024-07-22 15:30'},
];
const drawer = ref(false)
const direction = ref<DrawerProps['direction']>('rtl')
const radio1 = ref('Option 1')
const emits = defineEmits(['handleQuery']);
let random = ref(0);
const state = reactive({
ruleForm: {} as any,
className: "",
images: [
{id: 0, idView: imgUrl, top: '-180.1℃', center: '-192.2℃', bottom: '-195.1℃', shi: '1%',height: 162, status: 0},
{id: 1, idView: imgUrl, top: '-181.6℃', center: '-190.6℃', bottom: '-195.3℃', shi: '1.3%',height: 166, status: 1},
{id: 2, idView: imgUrl, top: '-182.4℃', center: '-192.4℃', bottom: '-195.5℃', shi: '2.1%',height: 162, status: 1},
{id: 3, idView: imgUrl, top: '-183.1℃', center: '-191.5℃', bottom: '-195.6℃', shi: '1.7%',height: 168, status: 0},
{id: 4, idView: imgUrl, top: '-180.9℃', center: '-190.2℃', bottom: '-195.3℃', shi: '3.1%',height: 166, status: 1},
{id: 5, idView: imgUrl, top: '-182.2℃', center: '-192.9℃', bottom: '-195.4℃', shi: '2.3%',height: 169, status: 0},
],
});
const m9Msg = computed(() => {