Browse Source

大屏

master
肖正 3 months ago
parent
commit
35ec9813e0
  1. 5
      .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

5
.env.development

@ -2,6 +2,7 @@
ENV = development ENV = development
# 本地环境接口地址 # 本地环境接口地址
# VITE_API_URL = http://localhost:5005 VITE_API_URL = http://localhost:5005
VITE_API_URL = http://192.168.88.206:5005 # VITE_API_URL = http://192.168.88.206:5005
# VITE_API_URL = http://192.168.88.76: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-gl": "^2.0.9",
"echarts-wordcloud": "^2.1.0", "echarts-wordcloud": "^2.1.0",
"element-plus": "^2.6.1", "element-plus": "^2.6.1",
"ezuikit-js": "^8.0.6-beta.2",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"js-table2excel": "^1.1.2", "js-table2excel": "^1.1.2",
"jsplumb": "^2.15.6", "jsplumb": "^2.15.6",
"konva": "^9.2.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"monaco-editor": "^0.47.0", "monaco-editor": "^0.47.0",
@ -44,7 +46,6 @@
"vcrontab-3": "^3.3.22", "vcrontab-3": "^3.3.22",
"vform3-builds": "^3.0.10", "vform3-builds": "^3.0.10",
"vue": "^3.4.21", "vue": "^3.4.21",
"konva": "^9.2.0",
"vue-clipboard3": "^2.0.0", "vue-clipboard3": "^2.0.0",
"vue-demi": "^0.14.7", "vue-demi": "^0.14.7",
"vue-grid-layout": "3.0.0-beta1", "vue-grid-layout": "3.0.0-beta1",

2
public/config.js

@ -3,5 +3,5 @@ window.__env__ = {
"VITE_OPEN": "false", "VITE_OPEN": "false",
"VITE_OPEN_CDN": "false", "VITE_OPEN_CDN": "false",
"VITE_PUBLIC_PATH": "", "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 setIntroduction from '/@/utils/setIconfont';
// import checkUpdate from '/@/utils/auto-update'; // import checkUpdate from '/@/utils/auto-update';
import { SysOrgApi } from '/@/api-services/api'; import { SysOrgApi } from '/@/api-services/api';
//
const getThemeConfig = computed(() => {
return themeConfig.value;
});
// //
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue')); const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
@ -107,6 +111,22 @@ watch(
() => route.path, () => route.path,
() => { () => {
other.useTitle(); 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, 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', 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) { // export function list(params: any) {
// return request({ // return request({
// eslint-disable-next-line no-irregular-whitespace // 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 主题颜色
primary: '#11559C', //红色:#DE2910 //蓝色:#11559C //绿色:#057748 primary: '#11559C', //红色:#DE2910 //蓝色:#11559C //绿色:#057748
// 是否开启深色模式 // 是否开启深色模式
isIsDark: false, isIsDark: true,
/** /**
* *
@ -30,7 +30,7 @@ export const useThemeConfig = defineStore('themeConfig', {
// 默认顶栏导航字体颜色 // 默认顶栏导航字体颜色
topBarColor: '#000000', topBarColor: '#000000',
// 是否开启顶栏背景颜色渐变 // 是否开启顶栏背景颜色渐变
isTopBarColorGradual: false, isTopBarColorGradual: true,
/** /**
* *
@ -42,7 +42,7 @@ export const useThemeConfig = defineStore('themeConfig', {
// 默认菜单高亮背景色 // 默认菜单高亮背景色
menuBarActiveColor: 'var(--el-color-primary-light-7)', menuBarActiveColor: 'var(--el-color-primary-light-7)',
// 是否开启菜单背景颜色渐变 // 是否开启菜单背景颜色渐变
isMenuBarColorGradual: false, isMenuBarColorGradual: true,
/** /**
* *
@ -125,7 +125,7 @@ export const useThemeConfig = defineStore('themeConfig', {
* `initSetLayoutChange(设置布局切换,重置主题样式)` * `initSetLayoutChange(设置布局切换,重置主题样式)`
*/ */
// 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults // 布局切换:可选值"<defaults|classic|transverse|columns>",默认 defaults
layout: 'classic', layout: 'transverse',
/** /**
* *

20
src/theme/app.scss

@ -336,3 +336,23 @@ body,
padding-left: #{$i}px !important; 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; 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--primary,
.el-button--info, .el-button--info,
.el-button--danger, .el-button--danger,

2
src/utils/request.ts

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

79
src/views/HealthLayout/area.vue

@ -30,85 +30,10 @@
</template> </template>
<script setup lang="ts" name="area"> <script setup lang="ts" name="area">
import { ref } from 'vue' import { ref } from 'vue'
import { mockData, mockData2 } from './cityPostion'
const activeNames = ref(['广州']) 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> </script>
<style lang="scss"> <style lang="scss">

212
src/views/HealthLayout/cityPostion.js

@ -35,6 +35,218 @@ const positionArr = [
{ name: '江苏', value: ['118.7727814', '32.0476151'] }, { 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) { export function getCityPositionByName(name) {
return positionArr.find((item) => item.name === name); return positionArr.find((item) => item.name === name);
} }

69
src/views/HealthLayout/index.vue

@ -1,6 +1,6 @@
<template> <template>
<div class="HealthLayout-box"> <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-row ref="mapBox" :style="{height: height+'px'}" style="margin-left: 30px;overflow: hidden;">
<el-col :span="8" class="area-box"> <el-col :span="8" class="area-box">
<Area /> <Area />
@ -19,24 +19,24 @@
</template> </template>
<script lang="ts" setup name="HealthLayout"> <script lang="ts" setup name="HealthLayout">
import { onMounted, reactive, computed, ref, onBeforeUnmount } from 'vue'; import { onMounted, reactive, ref } from 'vue';
import { ElMessage } from 'element-plus'; // import { ElMessage } from 'element-plus';
import './china'; import './china';
const mapBox = ref(null); const mapBox = ref(null);
let height = ref(0); let height = ref(0);
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import Area from './area.vue'; import Area from './area.vue';
import { getCityPositionByName } from './cityPostion' import { getCityPositionByName, } from './cityPostion'
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
const router = useRouter(); const router = useRouter();
// 10 // 10
let mockData = [ let mockData = [
{ name: '北京', value: 500 }, { name: '北京', value: 11500 },
{ name: '天津', value: 200 }, { name: '天津', value: 1200 },
{ name: '河南', value: 300 }, { name: '河南', value: 2300 },
{ name: '广西', value: 300 }, { name: '广西', value: 1300 },
{ name: '广东', value: 300 }, { name: '广东', value: 9300 },
{ name: '河北', value: 300 }, { name: '河北', value: 5300 },
]; ];
const state = reactive({ const state = reactive({
loading: false, loading: false,
@ -59,6 +59,16 @@ const init = async () => {
value: cityPosition.concat(i.value), 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')) let initMap = echarts.init(document.querySelector('#mapDom'))
initMap.on('click', mapClick); initMap.on('click', mapClick);
@ -158,31 +168,30 @@ const init = async () => {
}, },
}, },
z: 2, 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,
}, },
// {
// 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) => { const mapClick = (item) => {
// console.log(88888, item);
router.push({name: 'home', query: {name: item.name}}); router.push({name: 'home', query: {name: item.name}});
} }
</script> </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(() => {
return {
humidity: (random.value + 10).toFixed(1),
top: (random.value + 183.1).toFixed(1),
center: (random.value + 192.2).toFixed(1),
bottom: (random.value + 194.5).toFixed(1),
};
});
//
const openDrawer = (row: any) => {
state.ruleForm = JSON.parse(JSON.stringify(row));
drawer.value = true;
// ruleFormRef.value?.resetFields();
};
//
const closeDrawer = () => {
// emits('handleQuery');
drawer.value = false;
};
const changeImg = () => {
state.className = "lun-img-two";
setTimeout(() => {
state.className = "lun-img";
}, 300);
}
//
const cancel = () => {
drawer.value = false;
};
function confirmClick() {
ElMessageBox.confirm(`Are you confirm to chose ${radio1.value} ?`)
.then(() => {
drawer.value = false
})
.catch(() => {
// catch error
})
}
//
defineExpose({ openDrawer });
</script>
<style>
.cursor-info .el-drawer__header {
display: none;
}
.cursor-info .el-drawer__body {
background: #f8f9fa;
}
</style>
<style scoped lang="scss">
.orido_tm_hero {
width: 100%;
height: 100vh;
position: relative;
background-size: cover;
background-position: center center;
background-image: url(/@/assets/customer/bg.png);
background-color: #fff;
.close-box {
position: fixed;
top: 30px;
right: 30px;
width: 40px;
height: 40px;
border-radius: 50%;
text-align: center;
box-shadow: -0.0625rem 0 .625rem 0 rgba(0, 0, 0, 0.07), 0.3125rem 1.25rem 2.5rem 0 rgba(0, 0, 0, 0.04);
background: #eee;
z-index: 1;
cursor: pointer;
}
.info-close {
font-size: 30px;
margin-top: 5px;
color: #777;
}
.title-heading {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
max-width: 60%;
.alert {
border-radius: 30px;
display: inline-block;
background: #fff;
box-shadow: 0 0 3px rgba(60, 72, 88, 0.15);
padding: 8px 15px;
font-size: 14px;
.badge {
border-radius: 12px;
background-color: var(--el-color-primary);
margin-right: .25rem;
display: inline-block;
padding: .35em .65em;
font-size: .75em;
font-weight: 700;
line-height: 1;
color: #fff;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
}
.content {
font-size: 14px;
line-height: 26px;
font-weight: 600;
}
}
.heading {
margin-bottom: .5rem;
font-size: 57px;
letter-spacing: -0.5px;
line-height: 1.2;
color: #161c2d;
}
.hero-btn {
padding-top: .5rem;
margin-top: 1.5rem;
}
}
.author {
position: absolute;
bottom: 0;
right: 30px;
width: 35%;
}
.svg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 25px;
height: 25px;
margin-top: 2px;
margin-left: 2px;
}
.anim_circle{
width: 150px;
width: 150px;
animation: animCircle 15s infinite linear;
}
.video_button {
position: absolute;
bottom: 0;
right: 0;
}
}
.info-icon {
color: var(--el-color-primary);
}
.pera-title {
color: #8492a6;
font-size: 15px;
margin-bottom: 1rem;
line-height: 26px;
}
.section {
padding-top: 100px;
padding-bottom: 100px;
position: relative;
}
.content-box {
display: flex;
flex-wrap: wrap;
.content-item {
padding: .5rem 0.75rem 0;
margin-top: 1.5rem;
width: 33%;
.feature-widget {
padding: 30px 45px;
background-color: #fff;
box-shadow: -0.0625rem 0 .625rem 0 rgba(0, 0, 0, 0.07), 0.3125rem 1.25rem 2.5rem 0 rgba(0, 0, 0, 0.04);
border-radius: 10px;
h3 {
font-size: 20px;
margin-bottom: 1rem;
}
p{
margin-bottom: .1rem;
span{
font-size: 1.4rem;
}
}
}
}
}
.text-light-muted {
color: #8492a6;
}
.container-title {
text-align: center;
margin-bottom: 2rem;
h2 {
color: #161c2d;
font-weight: 600;
font-size: 30px;
margin-bottom: 1.5rem;
line-height: 1.5;
}
}
@keyframes animCircle {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
}
.container {
max-width: 1130px;
margin: 0px auto;
height: 100%;
position: relative;
}
.device-box {
background: #fff;
.lun-img {
transition: all 4s;
transform: scale(1.5);
}
.lun-img-two {
transform: scale(1);
}
.el-carousel__item.is-animating {
transition: transform 1s ease-in-out;
}
&-item {
display: flex;
justify-content: center;
flex-wrap: wrap;
align-content: center;
height: 100%;
.cold-storage-content {
width: 400px;
height: 100%;
text-align: center;
position: relative;
&-tips {
position: absolute;
white-space: nowrap;
min-width: 140px;
width: 30%;
text-align: left;
&-line {
display: inline-block;
margin: 0 10px;
width: 30%;
margin-bottom: 3px;
}
.blue {
background: blue;
height: 5px;
}
.red {
background: red;
height: 2px;
}
}
}
.cta-full-img-box {
padding: 100px 5% 100px 15%;
text-align: center;
h4{
color: #161c2d;
font-weight: 600;
font-size: 30px;
margin-bottom: 1.5rem;
}
}
}
}
</style>

388
src/views/health.vue

@ -1,14 +1,396 @@
<template> <template>
<div class="home-box"> <div class="home-box">
<iframe src="http://365.robot365.cn/#/monitorScreen/scada-1" <!-- <iframe src="http://365.robot365.cn/#/monitorScreen/scada-1"
style="height: 100%;" frameborder="0"></iframe> style="height: 100%;" frameborder="0"></iframe> -->
<!-- <h1 class="title">松山湖基地M9_01号生命安全库</h1> -->
<el-row :style="{height: height+'px'}" style="margin-left: 30px;overflow: hidden;">
<el-col :span="16" style="position: relative;">
<div class="linebox">
<img class="line1" src="/@/assets/home/lines1.png">
<img class="line2" src="/@/assets/home/lines2.png">
<img class="line3" src="/@/assets/home/lines3.png">
</div>
<div id='mapDom' @click="dialogShow">
<el-image width="100%" src="/@/assets/M9_01.png" alt="" />
</div>
</el-col>
<el-col :span="8" class="right-area">
<h1 class="title">松山湖M9_01号生命安全库</h1>
<h3>设备状态监控<b></b></h3>
<div class="area-inbox-1">
<dl>
<dt>上月平均值</dt>
<dd class="font12"><span>66.525%</span><b></b></dd>
<dt class="ml-20">今日使用率</dt>
<dd class="font-red ml-20"><span>74.113%</span><b></b></dd>
<dt>使用率环比增长</dt>
<dd><span>28.113%</span><b></b></dd>
</dl>
<div class="round-1"></div>
<div class="round-2"></div>
<div class="round-3">92%</div>
<div class="round-4"></div>
</div>
<div class="area-inbox-2">
<ul :style="{height: (height-400)+'px'}">
<li>
<b class="animation-2"></b>
<p>密封腔湿度</p>
<strong>14.6%</strong>
</li>
<li>
<b class="animation-2"></b>
<p>腔内顶部温度</p>
<strong>-183.2</strong>
</li>
<li>
<b class="animation-2"></b>
<p>腔内中部温度</p>
<strong>-192.3</strong>
</li>
<li>
<b class="animation-2"></b>
<p>腔内底部温度</p>
<strong>-194.5</strong>
</li>
<li>
<b class="animation-2"></b>
<p>液氮高度</p>
<strong>175.3mm</strong>
</li>
<li>
<b class="animation-2"></b>
<p>液氮上限</p>
<strong>195mm</strong>
</li>
<li>
<b class="animation-2"></b>
<p>液氮下限</p>
<strong>125mm</strong>
</li>
<li>
<b class="animation-2"></b>
<p>已用冻存盒</p>
<strong>286</strong>
</li>
<li>
<b class="animation-2"></b>
<p>总冻存盒</p>
<strong>312</strong>
</li>
<li>
<b class="animation-2"></b>
<p>使用率</p>
<strong>91.2%</strong>
</li>
</ul>
</div>
</el-col>
</el-row>
<el-dialog v-model="dialogVisible" class="health-dialog" :title="state.title" width="800">
<el-input ref="searchInput" v-if="!state.show" @keyup.enter.native="nameSearch"
v-model="input" style="font-size: 25px; height: 50px;">
<template #append>
<el-button :icon="Search" @click="nameSearch" style="height: 50px;font-size: 25px;" />
</template>
</el-input>
<iframe src="/@/assets/pdf/ten.pdf" v-else style="width: 100%; height: 80vh;" frameborder="0"></iframe>
</el-dialog>
</div> </div>
</template> </template>
<script lang="ts" setup name="M9home"> <script lang="ts" setup name="M9home">
import { onMounted, reactive, ref } from 'vue';
import { ElMessage } from 'element-plus';
import { Search } from '@element-plus/icons-vue'
const searchInput = ref(null);
let height = ref(0);
const input = ref('')
const dialogVisible = ref(false)
const state = reactive({
loading: false,
title: '请输入要查询的用户姓名',
angle: 0,
show: false,
editUserTitle: '',
});
onMounted(async () => {
height.value = window.innerHeight - 130;
// init();
});
const nameSearch = () => {
if (!input.value) {
ElMessage.warning('请输入要查询的用户姓名');
return;
}
state.title = `${input.value} 的体检报告`;
state.show = true;
}
const dialogShow = async () => {
input.value = '';
state.show = false;
state.title = '请输入要查询的用户姓名';
// searchInput.value.focus();
dialogVisible.value = true;
setTimeout(() => {
searchInput.value.focus();
}, 200);
}
</script> </script>
<style lang="scss">
.home-box .el-card__body {
height: 100%;
}
.health-dialog{
background-color: rgba(11,11,40,0.8);
.el-dialog__header {
background: transparent;
}
}
</style>
<style scoped lang="scss">
$color: rgb(211, 130, 50);
#mapDom {
width: 45%;
position: absolute;
left: 50%;
top: 54%;
transform: translate(-50%, -50%);
cursor: pointer;
}
.area-box {
height: 100%;
overflow-y: auto;
padding-right: 10px;
border: 1px solid #666;
border-radius: 15px;
background: rgba(255,255,255, .1);
&::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
}
.home-box:before,
.home-box::after {
display: block;
content: '';
position: absolute;
width: 100%;
height: 100%;
top: 0;
pointer-events: none;
z-index: 10;
}
.home-box {
background: url(/@/assets/home/eath.png) center center;
background-size: 100% 100%;
}
.title {
font-size: 26px;
margin-top: 10px;
color: #fff;
}
@keyframes scales1{0%{transform:rotate(0)}
100%{transform:rotate(360deg)}
}
@keyframes scales2{0%{transform:rotate(0)}
100%{transform:rotate(-360deg)}
}
.linebox {
position: absolute;
width: 80%;
height: 80%;
padding-top: 20%;
margin-left: 10%;
//padding-top: 250px;
transform: scale(1, .7);
opacity: .5;
display: flex;
justify-content: center;
align-items: center;
img {
position: absolute;
width: 100%;
max-width: unset;
}
.line1 {
animation: scales2 60s linear infinite;
margin-left: -3px;
margin-top: -7px;
}
.line2 {
animation: scales1 15s linear infinite;
}
.line3 {
animation: scales2 20s linear infinite;
opacity: 1;
}
}
</style>
<style scoped lang="scss">.home-box{ <style scoped lang="scss">.home-box{
height: 100%; height: 100%;
} }
@font-face{font-family:electronicFont;src:url(/@/assets/font/DS-DIGIT.TTF)}
@-webkit-keyframes forotate{
from{
-webkit-transform:rotate(-360deg);
opacity: .9;
}
to{
-webkit-transform:rotate(0);
opacity: 1;
}
}
@-webkit-keyframes forotate1{
from{
-webkit-transform:rotate(0);
}
to{
-webkit-transform:rotate(-180deg);
}
}
@-webkit-keyframes whitePulse {
from {
box-shadow: 0 0 26px #fff,
0 0 4px #fff,
0 0 2px #fff,
0 0 0px #fff;
}
to {
box-shadow: 0 0 0 #fff,
0 0 2px #fff,
0 0 4px #fff,
0 0 26px #fff;
}
}
.right-area{
position: relative;
color: #fff;
}
.right-area h3 {
position: relative;
top: 20px;
padding-bottom: 6px;
padding-left: 6px;
font-size: 14px;
font-weight: normal;
}
.area-inbox-1 {
width: 293px;
height: 293px;
background: url(/@/assets/home/bg01rightarea.png) right bottom no-repeat;
background-size: 100%;
margin-left: 60px;
position: relative;
dl {
padding: 105px 0 0 130px;
dt {
color: rgba(255, 255, 255, .3);
margin-top: 4px;
}
font12 {
font-size: 12px;
}
}
.round-1 {
position: absolute;
left: 94px;
top: 98px;
width: 168px;
height: 168px;
border-radius: 100%;
border: 1px dashed #fff;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: forotate;
-webkit-animation-duration: 19000ms;
}
.round-2 {
position: absolute;
left: 79px;
top: 84px;
width: 198px;
height: 198px;
border-radius: 100%;
border: 1px dashed rgba(255, 255, 255, 0.5);
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: forotate1;
-webkit-animation-duration: 8000ms;
}
.round-3 {
position: absolute;
left: 30px;
top: 43px;
width: 40px;
height: 40px;
border: 1px solid rgba(255, 255, 255, .8);
text-align: center;
line-height: 40px;
font-family: 'electronicFont';
font-size: 14px;
border-radius: 100%;
background: url(../images/bg05rightarea.png) right bottom no-repeat;
-webkit-animation-iteration-count: infinite;
-webkit-animation-name: whitePulse;
-webkit-animation-duration: 2s;
}
}
.area-inbox-1 dl dd span {
font-family: 'electronicFont';
position: relative;
z-index: 1;
font-size: 22px;
margin-top: 6px;
letter-spacing: 1px;
opacity: 1;
}
.area-inbox-1 dl dd.font-red {
color: #ff3114;
}
.area-inbox-2
{
ul {
width: 500px;
margin-top: 20px;
overflow-y: auto;
&::-webkit-scrollbar {
display: none; /* Chrome Safari */
}
}
li {
transition: all 0.1s ease;
cursor: pointer;
position: relative;
display: inline-block;
overflow: hidden;
width: 146px;
height: 55px;
padding: 10px 0 0 30px;
background: url(/@/assets/home/bg01bigindex.png) 0 0 no-repeat;
margin: 15px 0 0 40px;
}
.animation-2 {
position: absolute;
right: 0;
top: 1px;
height: 16px;
width: 15px;
background: url(/@/assets/home/bg02bigindex.png) 0 0 no-repeat;
}
p {
display: block;
color: #b8b9bb;
font-size: 12px;
}
strong {
display: block;
color: #fff;
font-family: 'electronicFont';
font-size: 22px;
font-weight: normal;
}
}
</style> </style>

107
src/views/home/index.vue

@ -65,7 +65,7 @@
:src="item.idView" :src="item.idView"
fit="fit"></el-image> fit="fit"></el-image>
<div class="cold-storage-content-tips" style="top: 110px; left: -15%;"> <div class="cold-storage-content-tips" style="top: 110px; left: -15%;">
<span class="cold-storage-content-tips-text">密封腔湿度{{ item.shi }}</span> <span class="cold-storage-content-tips-text">密封腔湿度{{ m9Msg.humidity }}</span>
<span class="cold-storage-content-tips-line blue" style="width: 50px;"></span> <span class="cold-storage-content-tips-line blue" style="width: 50px;"></span>
</div> </div>
<div class="cold-storage-content-tips" style="top: 170px; left: -15%;"> <div class="cold-storage-content-tips" style="top: 170px; left: -15%;">
@ -78,15 +78,15 @@
</div> </div>
<div class="cold-storage-content-tips" style="top: 110px; right: -23%;"> <div class="cold-storage-content-tips" style="top: 110px; right: -23%;">
<span class="cold-storage-content-tips-line blue"></span> <span class="cold-storage-content-tips-line blue"></span>
<span class="cold-storage-content-tips-text">{{item.top}}</span> <span class="cold-storage-content-tips-text">{{m9Msg.top}}</span>
</div> </div>
<div class="cold-storage-content-tips" style="top: 170px; right: -23%;"> <div class="cold-storage-content-tips" style="top: 170px; right: -23%;">
<span class="cold-storage-content-tips-line blue"></span> <span class="cold-storage-content-tips-line blue"></span>
<span class="cold-storage-content-tips-text">{{item.center}}</span> <span class="cold-storage-content-tips-text">{{m9Msg.center}}</span>
</div> </div>
<div class="cold-storage-content-tips" style="top: 240px; right: -23%;"> <div class="cold-storage-content-tips" style="top: 240px; right: -23%;">
<span class="cold-storage-content-tips-line blue"></span> <span class="cold-storage-content-tips-line blue"></span>
<span class="cold-storage-content-tips-text">{{item.bottom}}</span> <span class="cold-storage-content-tips-text">{{m9Msg.bottom}}</span>
</div> </div>
<div> <div>
<span>液氮高度{{ item.height }} mm</span> <span>液氮高度{{ item.height }} mm</span>
@ -135,7 +135,7 @@
<!-- <div style="height: 100%" ref="homePieRef"></div> --> <!-- <div style="height: 100%" ref="homePieRef"></div> -->
</div> </div>
<div class="home-card-item" style="margin-top: 15px;height: 320px;"> <div class="home-card-item" style="margin-top: 15px;height: 320px;">
<div class="home-card-item-title">系统告警</div> <div class="home-card-item-title">设备状态监控</div>
<el-form :model="state.queryDictTypeParams" ref="queryForm" :inline="true"> <el-form :model="state.queryDictTypeParams" ref="queryForm" :inline="true">
<el-form-item label="日期"> <el-form-item label="日期">
<el-date-picker <el-date-picker
@ -178,13 +178,13 @@
</el-button-group> </el-button-group>
</el-form-item> --> </el-form-item> -->
</el-form> </el-form>
<el-table :data="state.tableData" style="width: 100%;height: 200px" :border="true" ref="scrollTable" <el-table :data="state.tableData" style="width: 100%;height: 200px" :border="true" ref="myTable"
@mouseenter.native="autoScroll(true)" @mouseover.native="clearScroll"
@mouseleave.native="autoScroll" @mouseleave.native="createScroll"
size="small"> size="small">
<el-table-column prop="date" label="时间" /> <el-table-column prop="id" label="序号" />
<el-table-column prop="name" label="事件" /> <el-table-column prop="date" label="设备" />
<el-table-column prop="text" label="描述" /> <el-table-column prop="name" label="类型" />
<el-table-column prop="status" label="状态"> <el-table-column prop="status" label="状态">
<template #default="scope"> <template #default="scope">
<el-tag type="danger" v-if="scope.row.status === 0">警告</el-tag> <el-tag type="danger" v-if="scope.row.status === 0">警告</el-tag>
@ -199,24 +199,33 @@
</template> </template>
<script setup lang="ts" name="home"> <script setup lang="ts" name="home">
import { reactive, onMounted, ref, watch, nextTick, onActivated, markRaw } from 'vue'; import { reactive, onMounted, ref, watch, nextTick, onActivated, markRaw, onBeforeUnmount, computed } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useThemeConfig } from '/@/stores/themeConfig'; import { useThemeConfig } from '/@/stores/themeConfig';
import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes'; import { useTagsViewRoutes } from '/@/stores/tagsViewRoutes';
import { getAddInfo } from '/@/api/user';
import mapManagement from '../system/mapManagement/index.vue'; import mapManagement from '../system/mapManagement/index.vue';
import userChart from './user.vue'; import userChart from './user.vue';
import imgUrl from '/@/assets/M9.png' import imgUrl from '/@/assets/M9.png'
import carYellow from '/@/assets/car_yellow.png' let timer = null
import carGreen from '/@/assets/car_green.png' let timer2 = null
let random = ref(0);
let myTable = ref(null)
// //
const homeLineRef = ref() const homeLineRef = ref()
const storesTagsViewRoutes = useTagsViewRoutes(); const storesTagsViewRoutes = useTagsViewRoutes();
const storesThemeConfig = useThemeConfig(); const storesThemeConfig = useThemeConfig();
const { themeConfig } = storeToRefs(storesThemeConfig); const { themeConfig } = storeToRefs(storesThemeConfig);
const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes); const { isTagsViewCurrenFull } = storeToRefs(storesTagsViewRoutes);
const m9Msg = computed(() => {
return {
humidity: (random.value + 10).toFixed(1),
top: (random.value + 183.1).toFixed(1),
center: (random.value + 192.2).toFixed(1),
bottom: (random.value + 194.5).toFixed(1),
};
});
const state = reactive({ const state = reactive({
global: { global: {
homeChartOne: null, homeChartOne: null,
@ -230,12 +239,25 @@ const state = reactive({
data: '', data: '',
}, },
tableData: [ tableData: [
{id: 0, date: '2023-03-23', name: '机械臂', text: '机械臂报警', status: 0}, {id: 1, date: '升降AGV', name: 'AGV', status: 1},
{id: 1, date: '2023-03-23', name: '机械臂', text: '机械臂报警', status: 1}, {id: 2, date: '协作AGV', name: 'AGV', status: 1},
{id: 2, date: '2023-03-23', name: '机械臂', text: '机械臂报警', status: 2}, {id: 3, date: 'M9_01', name: 'M9', status: 1},
{id: 3, date: '2023-03-23', name: '机械臂', text: '机械臂报警', status: 2}, {id: 4, date: 'M9_02', name: 'M9', status: 1},
{id: 4, date: '2023-03-23', name: '机械臂', text: '机械臂报警', status: 2}, {id: 5, date: 'M9_03', name: 'M9', status: 1},
{id: 5, date: '2023-03-23', name: '机械臂', text: '机械臂报警', status: 2}, {id: 6, date: 'M9_04', name: 'M9', status: 1},
{id: 7, date: 'M9_05', name: 'M9', status: 1},
{id: 8, date: 'M9_06', name: 'M9', status: 1},
{id: 9, date: '转运桶', name: '转运桶', status: 1},
{id: 10, date: '转运叉', name: '机械臂', status: 1},
{id: 11, date: '机械臂', name: '机械臂', status: 1},
{id: 12, date: '夹爪', name: '夹爪', status: 1},
{id: 13, date: '培养箱_01', name: '培养箱', status: 1},
{id: 14, date: '培养箱_02', name: '培养箱', status: 1},
{id: 15, date: '培养箱_03', name: '培养箱', status: 1},
{id: 16, date: '培养箱_04', name: '培养箱', status: 1},
{id: 17, date: '离心机_01', name: '离心机', status: 1},
{id: 18, date: '离心机_02', name: '离心机', status: 1},
{id: 19, date: '离心机_03', name: '离心机', status: 1},
], ],
className: "", className: "",
images: [ images: [
@ -312,11 +334,35 @@ const state = reactive({
}, },
}); });
const getAddUser = async () => { const clearScroll = () => {
var res = await getAddInfo(); clearInterval(timer)
state.userAddInfo = res.data.result; timer = null
// console.log(9999, state.userAddInfo.result); }
}; const createScroll = () => {
clearScroll()
// table
const table = myTable.value.layout.table.refs
//
const tableWrapper = table.bodyWrapper.firstElementChild.firstElementChild
timer = setInterval(() => {
tableWrapper.scrollTop += 1
// 0+=
if (tableWrapper.clientHeight + tableWrapper.scrollTop == tableWrapper.scrollHeight) {
tableWrapper.scrollTop = 0
}
}, 50)
}
const clearTimer2 = () => {
clearInterval(timer2)
timer2 = null
}
const createTimer2 = () => {
clearTimer2()
timer2 = setInterval(() => {
random.value = Math.random()*0.5;
}, 1000)
}
// 线 // 线
const initLineChart = () => { const initLineChart = () => {
@ -387,7 +433,12 @@ const changeImg = () => {
// //
onMounted(() => { onMounted(() => {
initEchartsResize(); initEchartsResize();
// getAddUser(); createScroll();
createTimer2();
});
onBeforeUnmount(() => {
clearScroll();
clearTimer2();
}); });
// keep-alive // keep-alive
onActivated(() => { onActivated(() => {

41
src/views/home/user.vue

@ -20,23 +20,30 @@ const state = reactive({
}); });
// //
const city = reactive([ const city = reactive([
{ value: 35835, name: '一号机' }, { value: 25835, name: '东城' },
{ value: 12335, name: '二号机' }, { value: 12335, name: '南城' },
{ value: 14835, name: '三号机' }, { value: 14835, name: '万江' },
{ value: 11935, name: '四号机' }, { value: 11935, name: '莞城' },
{ value: 7335, name: '五号机' }, { value: 7335, name: '石碣' },
{ value: 8933, name: '六号机' }, { value: 8933, name: '石龙' },
{ value: 14275, name: '七号机' }, { value: 14275, name: '茶山' },
{ value: 16635, name: '八号机' }, { value: 16635, name: '石排' },
{ value: 13510, name: '九号机' }, { value: 13510, name: '企石' },
{ value: 6474, name: '十号机' }, { value: 6474, name: '横沥' },
{ value: 17374, name: '十一号机' }, { value: 17374, name: '桥头' },
{ value: 5374, name: '十二号机' }, { value: 5374, name: '谢岗' },
{ value: 18774, name: '十三号机' }, { value: 18774, name: '东坑' },
{ value: 6974, name: '十四号机' }, { value: 6974, name: '常平' },
{ value: 13474, name: '十五号机' }, { value: 13474, name: '寮步' },
{ value: 15235, name: '十六号机' }, { value: 15235, name: '樟木头' },
{ value: 13280, name: '十七号机' } { value: 13280, name: '大朗' },
{ value: 11280, name: '黄江' },
{ value: 9280, name: '凤岗' },
{ value: 16280, name: '大岭山' },
{ value: 7280, name: '长安' },
{ value: 12280, name: '虎门' },
{ value: 15280, name: '厚街' },
{ value: 13280, name: '麻涌' },
]) ])
const cityName = reactive([]) // -citynamecityName const cityName = reactive([]) // -citynamecityName
const cityValue = reactive([]) // -cityvaluecityValue\ const cityValue = reactive([]) // -cityvaluecityValue\

BIN
src/views/laboratory/img/AGV01.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 199 KiB

BIN
src/views/laboratory/img/AGV02.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 355 KiB

BIN
src/views/laboratory/img/M9.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 242 KiB

BIN
src/views/laboratory/img/incubator.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 KiB

After

Width:  |  Height:  |  Size: 130 KiB

BIN
src/views/laboratory/img/lb.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 MiB

BIN
src/views/laboratory/img/lowerTheTemperature.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1009 KiB

After

Width:  |  Height:  |  Size: 192 KiB

BIN
src/views/laboratory/img/microscope.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 854 KiB

6
src/views/laboratory/laboratory.vue

@ -1,13 +1,13 @@
<template> <template>
<div class="svg-box"> <div class="svg-box">
<!-- <img href="./img/m9.png" width="100%" height="100%" /> --> <!-- <img href="./img/m9.png" width="100%" height="100%" /> -->
<svg ref="svg" :width="width" :height="height"> <!-- <svg ref="svg" :width="width" :height="height">
<image <image
:x="0" :x="0"
:y="0" :y="0"
href="./img/lb.png" href="./img/lb.png"
:width="width" :width="width"
/> /> -->
<!-- 定义椭圆轨道 --> <!-- 定义椭圆轨道 -->
<!-- <ellipse <!-- <ellipse
:cx="cx" :cx="cx"
@ -104,7 +104,7 @@
:height="100" :height="100"
:transform="`rotate(${imageRotation2}, ${imagePosition2.x}, ${imagePosition2.y})`" :transform="`rotate(${imageRotation2}, ${imagePosition2.x}, ${imagePosition2.y})`"
/> />
</svg> <!-- </svg> -->
</div> </div>
</template> </template>

BIN
src/views/system/mapManagement/centrifugal.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 MiB

After

Width:  |  Height:  |  Size: 230 KiB

BIN
src/views/system/mapManagement/incubator.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 KiB

After

Width:  |  Height:  |  Size: 111 KiB

38
src/views/system/mapManagement/index.vue

@ -17,7 +17,7 @@
</template> </template>
<script lang="ts" setup name="sysRole"> <script lang="ts" setup name="sysRole">
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive } from 'vue';
import Konva from 'konva'; import Konva from 'konva';
// import { ElMessageBox, ElMessage } from 'element-plus'; // import { ElMessageBox, ElMessage } from 'element-plus';
import mapData from './map/lab0522xiezuo(1).json'; import mapData from './map/lab0522xiezuo(1).json';
@ -537,40 +537,6 @@ console.log(77777, advancedPointList, normalPosList?.length)
}; };
const drawBackground = () => {//
var tempCanvas = document.createElement('canvas');
tempCanvas.width = 100; //
tempCanvas.height = 100; //
var tempContext = tempCanvas.getContext('2d');
//
tempContext.strokeStyle = '#000000'; //
tempContext.lineWidth = 2; //
tempContext.beginPath();
tempContext.moveTo(0, 20);
tempContext.lineTo(20, 0);
tempContext.stroke();
//
var pattern = tempContext.createPattern(tempCanvas, 'repeat');
//
var backgroundRect = new Konva.Rect({
x: 0,
y: 0,
width: mapCanvas.width,
height: mapCanvas.width,
fillPatternImage: tempCanvas,
fillPatternRepeat: 'repeat',
});
//
mapCanvas.layer.add(backgroundRect);
// //
// layer.draw();
}
const drawCircle = (x, y, radius, fill) => { const drawCircle = (x, y, radius, fill) => {
if (!mapCanvas.circle) { if (!mapCanvas.circle) {
mapCanvas.circle = new Konva.Circle({ mapCanvas.circle = new Konva.Circle({
@ -696,7 +662,7 @@ const buildAnchor = (x, y, type, index) => {
const drawAccess = () => { const drawAccess = () => {
const {advancedPointList, advancedCurveList} = accessAGV; const {advancedPointList, advancedCurveList} = accessAGV;
console.log(8998, advancedPointList) // console.log(8998, advancedPointList)
const offsetX = 4.56; const offsetX = 4.56;
const offsetY = 6.5; const offsetY = 6.5;
let advancedPointObj ={}; let advancedPointObj ={};

BIN
src/views/system/mapManagement/m9.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 721 KiB

After

Width:  |  Height:  |  Size: 284 KiB

86
src/views/system/monitor/index.vue

@ -4,7 +4,7 @@
<el-row ref="mapBox" :style="{height: height+'px'}" style="margin-left: 30px;overflow: hidden;"> <el-row ref="mapBox" :style="{height: height+'px'}" style="margin-left: 30px;overflow: hidden;">
<el-col :span="8" class="area-box"> <el-col :span="8" class="area-box">
<div class="content" :class="currentTarget==k?'active':''" <div class="content" :class="currentTarget==k?'active':''"
@click="currentTarget=k" @click="currentTargetChange(k)"
v-for="(city, k) in state.deviceList" :key="k">{{city.device_title}}</div> v-for="(city, k) in state.deviceList" :key="k">{{city.device_title}}</div>
</el-col> </el-col>
<el-col :span="16" style="position: relative;"> <el-col :span="16" style="position: relative;">
@ -13,10 +13,11 @@
<img class="line2" src="/@/assets/home/lines2.png"> <img class="line2" src="/@/assets/home/lines2.png">
<img class="line3" src="/@/assets/home/lines3.png"> <img class="line3" src="/@/assets/home/lines3.png">
</div> --> </div> -->
<div class="pulefttop"> <div class="pulefttop" ref="pulefttop">
<h2 class="tith2">{{state.deviceList[currentTarget]?.device_title}}</h2> <h2 class="tith2">{{state.deviceList[currentTarget]?.device_title}}</h2>
<div class="no-camera" v-if="!state.deviceList[currentTarget]?.live_sn">当前设备无已绑定的摄像头</div> <div class="no-camera" v-if="!state.deviceList[currentTarget]?.live_sn">当前设备无已绑定的摄像头</div>
<iframe v-else :src="`https://open.ys7.com/ezopen/h5/iframe?bSupporDoubleClickFull=0&url=ezopen://open.ys7.com/${state.deviceList[currentTarget]?.live_sn}/1.hd.live&autoplay=1&audio=1&accessToken=at.7vy7t758d879vfm31k8rlh0eawfz4gvm-8ojld67hnz-1jvykt4-fnf2b3dzp&templete=0&id=ezplayer&decoderVersion=`" frameborder="0"></iframe> <!-- <iframe v-else :src="`https://open.ys7.com/ezopen/h5/iframe?bSupporDoubleClickFull=0&url=ezopen://open.ys7.com/${state.deviceList[currentTarget]?.live_sn}/1.hd.live&autoplay=1&audio=1&accessToken=${state.accessToken}&templete=0&id=ezplayer&decoderVersion=`" frameborder="0"></iframe> -->
<div v-else id="video-container"></div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>
@ -25,42 +26,73 @@
</template> </template>
<script lang="ts" setup name="monitor"> <script lang="ts" setup name="monitor">
import { onMounted, reactive, computed, ref, onBeforeUnmount } from 'vue'; import { onMounted, reactive, ref } from 'vue';
// import { ElMessage } from 'element-plus'; // import { ElMessage } from 'element-plus';
import { getEZUIKitToken } from '/@/api/other';
import EZUIKit from 'ezuikit-js';
import { Session } from '/@/utils/storage';
const mapBox = ref(null); const mapBox = ref(null);
const pulefttop = ref(null);
let height = ref(0); let height = ref(0);
let currentTarget = ref(0); let currentTarget = ref(0);
import * as echarts from 'echarts';
import deviceMsg from './mockData.json' import deviceMsg from './mockData.json'
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 },
];
const state = reactive({ const state = reactive({
loading: false, loading: false,
angle: 0, angle: 0,
eZUIKitPlayer: null,
height: 0, height: 0,
deviceList: [], deviceList: [],
editUserTitle: '', editUserTitle: '',
accessToken: '',
}); });
onMounted(async () => { onMounted(async () => {
height.value = window.innerHeight - 200; height.value = window.innerHeight - 200;
state.deviceList = deviceMsg.deviceList; state.deviceList = deviceMsg.deviceList;
console.log(8888, state.deviceList) // state.accessToken = Session.get('EZUIKit') || '';
// if (!state.accessToken) {
// await getToken();
// }
initEZUIKitPlayer();
// var player = new EZUIKit.EZUIKitPlayer({
// id: 'video-container', // ID
// accessToken: 'at.6wfns7l8bqxftya36029px0ebk4ch4ky-9nzp0ci78e-0k8m16u-fwldpzkdx',
// url: 'ezopen://open.ys7.com/K76445988/1.live',
// })
// console.log(8888, state.accessToken)
}); });
const init = async () => { const getToken = async () => {
let res = await getEZUIKitToken('appKey=5975bdd7841141dc834e19f23041dab3&appSecret=517b93391c2b132a92c263162e5d3c3e')
state.accessToken = res?.data?.data?.accessToken
// console.log(1111, state.accessToken)
Session.set('EZUIKit', res?.data?.data?.accessToken)
}
//
const initEZUIKitPlayer = async () => {
if (!state.accessToken) {
await getToken();
}
let width = pulefttop.value.offsetWidth-20;
let height = pulefttop.value.offsetHeight-60
state.eZUIKitPlayer = new EZUIKit.EZUIKitPlayer({
id: "video-container",
accessToken: state.accessToken,
url: `ezopen://open.ys7.com/${state.deviceList[currentTarget.value]?.live_sn}/1.live`,
header: ["capturePicture", "save", "zoom"],
footer: ["fullScreen"],
autoplay: true,
audio: 1,
width,
height,
template: "simple",
});
// console.log(6788,pulefttop.value, width,height)
} }
const mapClick = (item) => { const currentTargetChange = (k) => {
// console.log(88888, item); currentTarget.value = k;
router.push({name: 'home', query: {name: item.name}}); state.eZUIKitPlayer.stop().then(() => {
initEZUIKitPlayer();
});
} }
</script> </script>
<style> <style>
@ -106,6 +138,7 @@ $color: rgb(211, 130, 50);
text-align: center; text-align: center;
font-size: 30px; font-size: 30px;
color: #fff; color: #fff;
margin-top: 20px;
} }
.linebox { .linebox {
position: absolute; position: absolute;
@ -167,13 +200,14 @@ $color: rgb(211, 130, 50);
background-size: 100% 100%; background-size: 100% 100%;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: top center; background-position: top center;
margin-top: 20px; margin-top: 10px;
width: 90%; width: 90%;
height: 100%; height: 95%;
iframe { padding-left: 10px;
#video-container, iframe {
width: 98%; width: 98%;
height: 86%; //height: 86% !important;
margin: 1px 0 0 10px; margin: 1px 0 0 20px;
} }
} }
.tith2 { .tith2 {

36
src/views/system/monitor/mockData.json

@ -2,6 +2,42 @@
{ {
"device_id": 36452, "device_id": 36452,
"device_order_id": 1, "device_order_id": 1,
"device_title": "松山湖实验室AGV",
"binder_devtitle": "",
"device_sn": "101",
"live_sn": "K76445988",
"device_model": ""
},
{
"device_id": 36452,
"device_order_id": 1,
"device_title": "松山湖实验室生物安全柜",
"binder_devtitle": "",
"device_sn": "101",
"live_sn": "K57062996",
"device_model": ""
},
{
"device_id": 36452,
"device_order_id": 1,
"device_title": "松山湖实验室M9调试机",
"binder_devtitle": "",
"device_sn": "101",
"live_sn": "L30891752",
"device_model": ""
},
{
"device_id": 36452,
"device_order_id": 1,
"device_title": "松山湖实验室原代培养平台",
"binder_devtitle": "",
"device_sn": "101",
"live_sn": "K58965955",
"device_model": ""
},
{
"device_id": 36452,
"device_order_id": 1,
"device_title": "中美赛尔干细胞培养工程", "device_title": "中美赛尔干细胞培养工程",
"binder_devtitle": "", "binder_devtitle": "",
"device_sn": "101", "device_sn": "101",

7
src/views/system/user/index.vue

@ -167,7 +167,7 @@ import OrgTree from '/@/views/system/org/component/orgTree.vue';
import EditUser from '/@/views/system/user/component/editUser.vue'; import EditUser from '/@/views/system/user/component/editUser.vue';
import { getAPI } from '/@/utils/axios-utils'; import { getAPI } from '/@/utils/axios-utils';
import { SysUserApi } from '/@/api-services/api'; import { SysUserApi, SysOrgApi } from '/@/api-services/api';
import { SysUser, SysOrg } from '/@/api-services/models'; import { SysUser, SysOrg } from '/@/api-services/models';
import { Session } from '/@/utils/storage'; import { Session } from '/@/utils/storage';
@ -199,8 +199,9 @@ onMounted(async () => {
// //
const loadOrgData = async () => { const loadOrgData = async () => {
state.loading = true; state.loading = true;
// var res = await getAPI(SysOrgApi).apiSysOrgListGet(0); var res = await getAPI(SysOrgApi).apiSysOrgListGet(0);
state.orgTreeData = Session.get('orgData') ?? []; console.log(8888, res)
state.orgTreeData = res.data?.result;
state.loading = false; state.loading = false;
}; };

Loading…
Cancel
Save