From d5ca37c6301ac1178702e0334c4feee6abf3ba9e Mon Sep 17 00:00:00 2001 From: whychdw <496960745@qq.com> Date: 星期五, 11 十月 2024 14:19:09 +0800 Subject: [PATCH] 内容提交 --- src/components/HdwCard/index.vue | 57 ++++ src/components/HdwTree/index.vue | 69 ++++ src/assets/images/user.png | 0 src/api/user.js | 2 components.d.ts | 11 src/router/modules/system.ts | 2 src/icons/svg/safe-lock-hdw.svg | 1 src/views/dashboard/components/LineChart.vue | 119 ++++++++ src/utils/resize.js | 56 ++++ src/views/dashboard/components/MenuCard.vue | 56 ++++ vite.config.ts | 3 .env.dev_prod | 4 mock/demo/user.js | 2 src/views/dashboard/index.vue | 295 ++++++++++++++++++++ src/icons/svg/people-hdw.svg | 1 src/views/device/lock/index.vue | 152 ++++++++++ .env.build_prod | 2 src/icons/svg/key-hdw.svg | 2 18 files changed, 819 insertions(+), 15 deletions(-) diff --git a/.env.build_prod b/.env.build_prod index a368e4c..24d10ff 100644 --- a/.env.build_prod +++ b/.env.build_prod @@ -2,4 +2,4 @@ NODE_ENV = 'production' # 鎵撳寘妯″紡杩炵敓浜ф湇 -VUE_APP_BASE_API = '/api-prod' \ No newline at end of file +VUE_APP_BASE_API = '/' diff --git a/.env.dev_prod b/.env.dev_prod index bb64344..87cce62 100644 --- a/.env.dev_prod +++ b/.env.dev_prod @@ -2,5 +2,5 @@ NODE_ENV = 'development' # 寮�鍙戞ā寮忚繛鐢熶骇鏈� -VUE_APP_BASE_API = '/api-prod' -VUE_APP_COOKIE = '' \ No newline at end of file +VUE_APP_BASE_API = '/' +VUE_APP_COOKIE = '' diff --git a/components.d.ts b/components.d.ts index be9f069..015ae34 100644 --- a/components.d.ts +++ b/components.d.ts @@ -13,12 +13,13 @@ DropdownMenu: typeof import('./src/components/Share/DropdownMenu.vue')['default'] Dropzone: typeof import('./src/components/Dropzone/index.vue')['default'] EditorImage: typeof import('./src/components/Tinymce/components/EditorImage.vue')['default'] + ElAvatar: typeof import('element-plus/es')['ElAvatar'] ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] ElButton: typeof import('element-plus/es')['ElButton'] - ElCard: typeof import('element-plus/es')['ElCard'] ElCol: typeof import('element-plus/es')['ElCol'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] + ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] ElDialog: typeof import('element-plus/es')['ElDialog'] ElDropdown: typeof import('element-plus/es')['ElDropdown'] ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] @@ -29,18 +30,22 @@ ElInput: typeof import('element-plus/es')['ElInput'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] - ElProgress: typeof import('element-plus/es')['ElProgress'] + ElPagination: typeof import('element-plus/es')['ElPagination'] + ElRadioButton: typeof import('element-plus/es')['ElRadioButton'] + ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] ElRow: typeof import('element-plus/es')['ElRow'] ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] ElSwitch: typeof import('element-plus/es')['ElSwitch'] ElTable: typeof import('element-plus/es')['ElTable'] ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] - ElTag: typeof import('element-plus/es')['ElTag'] ElTooltip: typeof import('element-plus/es')['ElTooltip'] + ElTree: typeof import('element-plus/es')['ElTree'] ErrorLog: typeof import('./src/components/ErrorLog/index.vue')['default'] GithubCorner: typeof import('./src/components/GithubCorner/index.vue')['default'] Hamburger: typeof import('./src/components/Hamburger/index.vue')['default'] + HdwCard: typeof import('./src/components/HdwCard/index.vue')['default'] + HdwTree: typeof import('./src/components/HdwTree/index.vue')['default'] HeaderSearch: typeof import('./src/components/HeaderSearch/index.vue')['default'] ImageCropper: typeof import('./src/components/ImageCropper/index.vue')['default'] Keyboard: typeof import('./src/components/Charts/Keyboard.vue')['default'] diff --git a/mock/demo/user.js b/mock/demo/user.js index 2fe385e..e9ecb00 100644 --- a/mock/demo/user.js +++ b/mock/demo/user.js @@ -26,7 +26,7 @@ export default [ // user login { - url: '/vue-element-admin/user/login', + url: '/user/login', method: 'post', response: config => { const { username } = config.body; diff --git a/src/api/user.js b/src/api/user.js index 37bc37f..a23c066 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -2,7 +2,7 @@ export function login(data) { return request({ - url: '/vue-element-admin/user/login', + url: '/user/login', method: 'post', data }); diff --git a/src/assets/images/user.png b/src/assets/images/user.png new file mode 100644 index 0000000..e16488e --- /dev/null +++ b/src/assets/images/user.png Binary files differ diff --git a/src/components/HdwCard/index.vue b/src/components/HdwCard/index.vue new file mode 100644 index 0000000..17d8a2a --- /dev/null +++ b/src/components/HdwCard/index.vue @@ -0,0 +1,57 @@ +<script lang="ts"> +import { defineComponent } from 'vue'; + +export default defineComponent({ + name: 'HdwCard', + props: { + isFull: { + type: Boolean, + default: false + }, + title: { + type: String, + default: '' + } + } +}); +</script> + +<template> + <div class="hdw-card" :class="[isFull && 'is-full', title && 'is-has-title']"> + <div v-if="title" class="hdw-card-title"> + {{title}} + </div> + <div class="hdw-card-content"> + <slot></slot> + </div> + </div> +</template> + +<style scoped lang="scss"> +.hdw-card { + box-shadow: 0 0 12px rgba(0,0,0,0.2); + padding: 8px; + border-radius: 4px; + &.is-full { + height: 100%; + .hdw-card-content { + padding-top: 8px; + height: 100%; + } + &.is-has-title { + .hdw-card-content { + height: calc(100% - 30px); + } + } + } + + .hdw-card-title { + margin-left: -8px; + margin-right: -8px; + padding: 4px 16px; + border-bottom: 1px solid rgba(128, 128, 128, 0.2); + font-weight: 700; + font-size: 14px; + } +} +</style> diff --git a/src/components/HdwTree/index.vue b/src/components/HdwTree/index.vue new file mode 100644 index 0000000..9dba1fa --- /dev/null +++ b/src/components/HdwTree/index.vue @@ -0,0 +1,69 @@ +<script lang="ts"> +import { defineComponent } from 'vue'; + +export default defineComponent({ + name: 'HdwTree', + data() { + return { + defaultProps: { + children: 'children', + label: 'label' + }, + data: [ + { + label: '娌冲崡鐪�', + children: [ + { + label: '椹婚┈搴楀競', + children: [ + { + label: '涓婅敗鍘�' + }, + { + label: '纭北鍘�' + } + ] + } + ] + }, + { + label: '婀栧寳鐪�', + children: [ + { + label: '姝︽眽甯�', + children: [ + { + label: '涓滆タ婀栧尯' + }, + { + label: '闈掑北鍖�' + } + ] + } + ] + } + ] + }; + }, + methods: { + handleNodeClick(data) { + console.log(data); + } + } +}); +</script> + +<template> + <el-scrollbar> + <el-tree + style="max-width: 600px" + :data="data" + :props="defaultProps" + @node-click="handleNodeClick" + /> + </el-scrollbar> +</template> + +<style scoped lang="scss"> + +</style> diff --git a/src/icons/svg/key-hdw.svg b/src/icons/svg/key-hdw.svg index f5ecd94..57f0e35 100644 --- a/src/icons/svg/key-hdw.svg +++ b/src/icons/svg/key-hdw.svg @@ -1 +1 @@ -<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728439454077" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="865" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M632.527307 498.500942q39.532957 14.463277 72.316384 39.532957t56.888889 58.335217 37.122411 73.280603 13.016949 83.404896q0 56.888889-21.212806 106.06403t-58.335217 85.815443-86.297552 57.853107-105.099812 21.212806-105.099812-21.212806-86.297552-57.853107-58.335217-85.815443-21.212806-106.06403q0-44.354049 13.499058-84.369115t37.60452-73.280603 57.370998-58.335217 72.798493-39.532957l0-404.971751q0-17.355932 6.26742-33.747646t17.838041-29.408663 27.480226-21.212806 34.229755-8.195857 35.676083 8.195857 30.854991 21.212806 21.212806 29.408663 7.713748 33.747646l0 405.93597zM542.854991 846.583804q38.568738 0 65.566855-26.998117t26.998117-66.531073q0-38.568738-26.998117-65.566855t-65.566855-26.998117q-39.532957 0-66.531073 26.998117t-26.998117 65.566855q0 39.532957 26.998117 66.531073t66.531073 26.998117zM751.126177 121.491525q61.709981 0 61.709981 57.853107l0 62.6742q0 33.747646-16.873823 46.764595t-37.122411 13.016949l-66.531073 0 0-180.308851 58.817326 0z" p-id="866"></path></svg> \ No newline at end of file +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728524053330" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1585" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M446.680407 513.704726h136.078739v510.295274h-136.078739z" p-id="1586"></path><path d="M532.410013 666.793308h115.666928v136.07874H532.410013zM532.410013 843.69567h149.686613v136.07874H532.410013zM511.998202 585.146065A290.528109 290.528109 0 0 1 219.428912 292.576775 290.528109 290.528109 0 0 1 511.998202 0.007484a290.528109 290.528109 0 0 1 292.56929 292.569291 290.528109 290.528109 0 0 1-292.56929 292.56929z m0-449.059841A153.768976 153.768976 0 0 0 355.507651 292.576775a153.768976 153.768976 0 0 0 156.490551 156.49055 153.768976 153.768976 0 0 0 156.49055-156.49055A153.768976 153.768976 0 0 0 511.998202 136.086224z" p-id="1587"></path></svg> \ No newline at end of file diff --git a/src/icons/svg/people-hdw.svg b/src/icons/svg/people-hdw.svg new file mode 100644 index 0000000..107944f --- /dev/null +++ b/src/icons/svg/people-hdw.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728459304110" class="icon" viewBox="0 0 1028 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1466" xmlns:xlink="http://www.w3.org/1999/xlink" width="128.5" height="128"><path d="M815.814506 299.350645c0 165.306834-134.011812 299.350645-299.350645 299.350645s-299.350645-134.011812-299.350645-299.350645c0-165.306834 134.011812-299.350645 299.350645-299.350645s299.350645 134.011812 299.350645 299.350645z" p-id="1467"></path><path d="M763.52814 612.780851c-69.75782 55.070279-156.219118 85.661323-247.064279 85.661323-91.901128 0-179.1944-31.295022-249.27221-87.421268-184.698228 67.805881-267.19165 304.758476-267.19165 412.979094l1027.711884 0c0-107.260648-83.133402-342.549295-264.183744-411.18715z" p-id="1468"></path></svg> \ No newline at end of file diff --git a/src/icons/svg/safe-lock-hdw.svg b/src/icons/svg/safe-lock-hdw.svg new file mode 100644 index 0000000..c35e18e --- /dev/null +++ b/src/icons/svg/safe-lock-hdw.svg @@ -0,0 +1 @@ +<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1728521944946" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1525" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M514.062027 1018.052384h-12.821041c-57.694685-18.936986-230.764712-113.621918-307.690959-195.682192-76.912219-88.372603-115.375342-170.432877-115.375342-265.117808v-378.739726c0-12.624658 6.410521-25.249315 19.217534-31.561644l403.848767-138.871233h19.217535l397.424219 138.871233c12.821041 6.312329 19.231562 18.936986 19.231561 31.561644v366.115068c0 100.99726-32.038575 183.057534-115.375342 265.117808-70.515726 94.684932-243.585753 189.369863-294.855891 208.30685h-12.821041z m161.52548-586.906302h-35.629589v-80.938082c0-67.766356-56.348055-122.82389-125.713534-122.82389-69.295342 0-125.727562 55.127671-125.727562 122.837917v80.938083h-35.629589c-17.099397 0-31.014575 13.606575-31.014575 30.299178v221.548712c0 16.776767 13.915178 30.383342 31.014575 30.383342h322.700274c17.169534 0 31.028603-13.606575 31.028603-30.383342V461.459288c0.070137-16.692603-13.859068-30.299178-31.028603-30.299178zM531.736548 578.026959v48.352438a4.067945 4.067945 0 0 1-4.081973 3.983781h-26.694137a4.067945 4.067945 0 0 1-4.067945-3.983781v-48.352438c-12.568548-6.256219-21.251507-18.852822-21.251507-33.52548 0-20.830685 17.295781-37.789808 38.673535-37.789808 21.363726 0 38.659507 16.959123 38.659506 37.775781 0 14.686685-8.668932 27.283288-21.237479 33.539507z m60.03726-146.866849H436.841205V352.227945c0-41.773589 34.787945-75.747945 77.529425-75.747945 42.755507 0 77.473315 33.974356 77.473315 75.747945l-0.070137 78.90411z" p-id="1526"></path></svg> \ No newline at end of file diff --git a/src/router/modules/system.ts b/src/router/modules/system.ts index 51459b6..ccd81a2 100644 --- a/src/router/modules/system.ts +++ b/src/router/modules/system.ts @@ -20,7 +20,7 @@ path: 'user', component: () => import('@/views/system/user/index.vue'), name: 'UserManage', - meta: { title: '鐢ㄦ埛绠$悊', icon: 'people', noCache: false } + meta: { title: '鐢ㄦ埛绠$悊', icon: 'people-hdw', noCache: false } } ] }; diff --git a/src/utils/resize.js b/src/utils/resize.js new file mode 100644 index 0000000..4126fb0 --- /dev/null +++ b/src/utils/resize.js @@ -0,0 +1,56 @@ +import { defineComponent } from 'vue'; +import { debounce } from '@/utils'; + +export default defineComponent({ + data() { + return { + sidebarElm: null, + resizeHandler: null + }; + }, + mounted() { + this.resizeHandler = debounce(() => { + if (this.chart) { + this.chart.resize(); + } + }, 100); + this.initResizeEvent(); + this.initSidebarResizeEvent(); + }, + beforeUnmount() { + this.destroyResizeEvent(); + this.destroySidebarResizeEvent(); + }, + // to fixed bug when cached by keep-alive + // https://github.com/PanJiaChen/vue-element-admin/issues/2116 + activated() { + this.initResizeEvent(); + this.initSidebarResizeEvent(); + }, + deactivated() { + this.destroyResizeEvent(); + this.destroySidebarResizeEvent(); + }, + methods: { + // do not use $_ for mixins properties + // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential + initResizeEvent() { + window.addEventListener('resize', this.resizeHandler); + }, + destroyResizeEvent() { + window.removeEventListener('resize', this.resizeHandler); + }, + sidebarResizeHandler(e) { + if (e.propertyName === 'width') { + this.resizeHandler(); + } + }, + initSidebarResizeEvent() { + this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]; + this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler); + }, + destroySidebarResizeEvent() { + this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler); + } + } +}); diff --git a/src/views/dashboard/components/LineChart.vue b/src/views/dashboard/components/LineChart.vue new file mode 100644 index 0000000..ebc8545 --- /dev/null +++ b/src/views/dashboard/components/LineChart.vue @@ -0,0 +1,119 @@ +<template> + <div :class="className" :style="{ height: height, width: width }" /> +</template> + +<script> +import * as echarts from 'echarts'; +import { defineComponent, shallowRef } from 'vue'; +import resize from '@/utils/resize'; + +export default defineComponent({ + name: 'LineChart', + mixins: [resize], + props: { + className: { + type: String, + default: 'chart' + }, + width: { + type: String, + default: '100%' + }, + height: { + type: String, + default: '100%' + }, + autoResize: { + type: Boolean, + default: true + }, + chartData: { + type: Object, + required: true + } + }, + data() { + return { + chart: null + }; + }, + watch: { + chartData: { + deep: true, + handler(val) { + this.setOptions(val); + } + } + }, + mounted() { + this.$nextTick(() => { + this.initChart(); + }); + }, + beforeUnmount() { + if (!this.chart) { + return; + } + this.chart.dispose(); + this.chart = null; + }, + methods: { + initChart() { + this.chart = shallowRef(echarts.init(this.$el)); + this.setOptions(this.chartData); + }, + setOptions() { + this.chart.setOption({ + grid: { + top: 20, + right: 20, + bottom: 20, + left: 20, + containLabel: true + }, + xAxis: { + type: 'category', + boundaryGap: false, + splitLine: { + show: true, + lineStyle: { + width: 1 + } + } + }, + yAxis: { + type: 'value', + axisLine: { + show: true + }, + splitLine: { + show: true, + lineStyle: { + width: 1, + type: 'dashed' + } + } + }, + series: [ + { + type: 'line', + smooth: 0.6, + symbol: 'none', + data: [ + ['2019-10-10', 2], + ['2019-10-11', 5], + ['2019-10-12', 7], + ['2019-10-13', 5], + ['2019-10-14', 2], + ['2019-10-15', 3], + ['2019-10-16', 4], + ['2019-10-17', 3], + ['2019-10-18', 1] + ] + } + ] + }); + } + } +}); +</script> diff --git a/src/views/dashboard/components/MenuCard.vue b/src/views/dashboard/components/MenuCard.vue new file mode 100644 index 0000000..54c2502 --- /dev/null +++ b/src/views/dashboard/components/MenuCard.vue @@ -0,0 +1,56 @@ +<script lang="ts"> +import { defineComponent } from 'vue'; +import SvgIcon from '@/components/SvgIcon/index.vue'; + +export default defineComponent({ + name: 'MenuCard', + components: { SvgIcon }, + props: { + title: { + type: String, + default: '鍖哄煙绠$悊' + }, + icon: { + type: String, + default: 'tree' + }, + url: { + type: String, + default: '/system/region' + } + }, + data() { + return {}; + }, + methods: { + changeRouter() { + this.$router.push(this.url); + } + } +}); +</script> + +<template> + <div class="menu-card" @click.prevent="changeRouter"> + <svg-icon style="font-size: 40px;" :icon-class="icon"></svg-icon> + <br /> + <br /> + <span class="menu-title">{{ title }}</span> + </div> +</template> + +<style scoped lang="scss"> +.menu-card { + display: inline-block; + color: #F6F6F6; + background-color: #9f80f5; + text-align: center; + min-width: 160px; + padding: 8px 16px; + border-radius: 4px; + cursor: pointer; + .menu-title { + font-weight: 700; + } +} +</style> diff --git a/src/views/dashboard/index.vue b/src/views/dashboard/index.vue index f6cce01..6e7da68 100644 --- a/src/views/dashboard/index.vue +++ b/src/views/dashboard/index.vue @@ -1,18 +1,307 @@ <template> - <div class="dashboard-container"></div> + <div class="dashboard-container"> + <hdw-card> + <div class="data-stats-header"> + <el-row :gutter="16"> + <el-col :span="8"> + <div class="user-info-wrapper"> + <el-avatar class="user-icon" :size="30" :src="userImg" /> + <span class="user-name">姝︽眽婧愮晠</span> + <span class="user-change">鍒囨崲</span> + </div> + </el-col> + <el-col :span="8"> + <div class="data-stats-time-wrapper"> + <span class="time-title">缁熻鏃堕棿锛�</span> + <el-radio-group class="radio-class" v-model="timeType" size="small"> + <el-radio-button label="鏈懆" :value="0" /> + <el-radio-button label="鏈湀" :value="1" /> + <el-radio-button label="鏈勾" :value="2" /> + </el-radio-group> + </div> + </el-col> + <el-col :span="8"> + <div class="data-stats-time-wrapper"> + <span class="time-title">鑷畾涔夋椂闂达細</span> + <el-date-picker + v-model="rangeTime" + type="daterange" + range-separator="鑷�" + start-placeholder="寮�濮嬫椂闂�" + end-placeholder="缁撴潫鏃堕棿" + size="small" + /> + </div> + </el-col> + </el-row> + </div> + + </hdw-card> + <div class="data-stats"> + <el-row :gutter="8"> + <el-col :span="8"> + <hdw-card> + <div class="data-stats-wrapper"> + <div class="data-stats-icon"> + <div class="data-stats-icon-content"> + <svg-icon icon-class="lock-hdw"/> + <br/> + <span class="icon-text">閿佸叿缁熻</span> + </div> + </div> + <div class="data-stats-content"> + <el-row :gutter="16"> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">宸插畨瑁�</div> + <div class="num-value">112</div> + </div> + </el-col> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">鏈畨瑁�</div> + <div class="num-value">2</div> + </div> + </el-col> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">钃濈墮閿�</div> + <div class="num-value">112</div> + </div> + </el-col> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">鏃犳簮閿�</div> + <div class="num-value">2</div> + </div> + </el-col> + </el-row> + </div> + </div> + </hdw-card> + </el-col> + <el-col :span="8"> + <hdw-card> + <div class="data-stats-wrapper"> + <div class="data-stats-icon"> + <div class="data-stats-icon-content"> + <svg-icon icon-class="key-hdw"/> + <br/> + <span class="icon-text">閽ュ寵缁熻</span> + </div> + </div> + <div class="data-stats-content"> + <el-row :gutter="16"> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">瀹炰綋閽ュ寵</div> + <div class="num-value">0</div> + </div> + </el-col> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">璁惧閽ュ寵</div> + <div class="num-value">0</div> + </div> + </el-col> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">钃濈墮閽ュ寵</div> + <div class="num-value">6</div> + </div> + </el-col> + </el-row> + </div> + </div> + </hdw-card> + </el-col> + <el-col :span="8"> + <hdw-card is-full> + <div class="data-stats-wrapper" style="height: 100%"> + <div class="data-stats-icon"> + <div class="data-stats-icon-content"> + <svg-icon icon-class="safe-lock-hdw"/> + <br/> + <span class="icon-text">浜嬩欢缁熻</span> + </div> + </div> + <div class="data-stats-content"> + <el-row :gutter="16"> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">寮�閿佹搷浣�</div> + <div class="num-value">0</div> + </div> + </el-col> + <el-col :span="12"> + <div class="num-stats-wrapper"> + <div class="num-title">鎶ヨ浜嬩欢</div> + <div class="num-value">0</div> + </div> + </el-col> + </el-row> + </div> + </div> + </hdw-card> + </el-col> + </el-row> + </div> + <div class="data-stats-footer"> + <el-row :gutter="8" style="height: 100%"> + <el-col :span="12" style="height: 100%"> + <hdw-card title="寮�閿佺粺璁�" is-full> + <div class="chart-wrapper"> + <line-chart :chart-data="unlockingData"></line-chart> + </div> + </hdw-card> + </el-col> + <el-col :span="12" style="height: 100%"> + <hdw-card title="蹇嵎鍏ュ彛" is-full> + <div class="fast-menu"> + <el-row :gutter="16"> + <el-col :span="6"> + <menu-card></menu-card> + </el-col> + <el-col :span="6"> + <menu-card url="/system/user" title="鐢ㄦ埛绠$悊" icon="people-hdw" style="background-color: #56e0c7"></menu-card> + </el-col> + <el-col :span="6"> + <menu-card url="/device/lock" title="閿佸叿绠$悊" icon="lock-hdw" style="background-color: #fe945f"></menu-card> + </el-col> + <el-col :span="6"> + <menu-card url="/device/key" title="閽ュ寵绠$悊" icon="key-hdw" style="background-color: #fdcc1c"></menu-card> + </el-col> + <el-col :span="6"> + <menu-card url="/general/authorize" title="鎺堟潈绠$悊" icon="auth-hdw" style="background-color: #5a84fd"></menu-card> + </el-col> + <el-col :span="6"> + <menu-card url="/general/log" title="鏃ュ織绠$悊" icon="log-hdw" style="background-color: #7997b3"></menu-card> + </el-col> + <el-col :span="6"> + <menu-card url="/general/map" title="鍦板浘瀹氫綅" icon="map-hdw" style="background-color: #1ab5b1"></menu-card> + </el-col> + </el-row> + </div> + </hdw-card> + </el-col> + </el-row> + </div> + </div> </template> <script> import { defineComponent } from 'vue'; +import MenuCard from '@/views/dashboard/components/MenuCard.vue'; +import HdwCard from '@/components/HdwCard/index.vue'; +import SvgIcon from '@/components/SvgIcon/index.vue'; +import LineChart from './components/LineChart.vue'; +import userImg from '@/assets/images/user.png'; export default defineComponent({ - name: 'Dashboard' + name: 'Dashboard', + components: { LineChart, SvgIcon, HdwCard, MenuCard }, + data() { + return { + unlockingData: [], + userImg, + timeType: 0, + rangeTime: '' + }; + } }); </script> -<style scoped> +<style scoped lang="scss"> .dashboard-container { height: 100%; overflow: auto; + padding: 8px; + .data-stats-footer { + min-height: 300px; + height: calc(100% - 265px); + } +} + +.user-info-wrapper { + display: inline-block; + .user-icon { + vertical-align: middle; + } + .user-name { + margin-left: 8px; + font-size: 14px; + } + .user-change { + margin-left: 8px; + font-size: 14px; + color: #409eff; + font-weight: 700; + cursor: pointer; + } +} + +.data-stats-time-wrapper { + .radio-class { + vertical-align: middle; + } + .time-title { + margin-right: 8px; + font-size: 14px; + display: inline-block; + } +} + +.data-stats { + margin-top: 8px; + padding-bottom: 8px; +} +.data-stats-wrapper { + display: flex; + flex-direction: row; + padding: 16px; + .data-stats-icon { + display: flex; + justify-content: center; + align-items: center; + text-align: center; + flex-direction: column; + .svg-icon { + font-size: 100px; + color: #5e5e5e; + } + .icon-text { + display: inline-block; + margin-top: 8px; + font-size: 14px; + font-weight: 700; + color: #5e5e5e; + } + } + .data-stats-content { + flex: 1; + } +; +} +.num-stats-wrapper { + padding: 12px; + text-align: center; + .num-title { + color: gray; + font-size: 14px; + } + .num-value { + font-size: 30px; + font-weight: 700; + } +} +.fast-menu { + text-align: center; + .el-col { + padding: 32px 0; + } +} +.chart-wrapper { + height: 100%; + overflow: hidden; } </style> diff --git a/src/views/device/lock/index.vue b/src/views/device/lock/index.vue index 0125370..4305d58 100644 --- a/src/views/device/lock/index.vue +++ b/src/views/device/lock/index.vue @@ -1,15 +1,163 @@ <script lang="ts"> import { defineComponent } from 'vue'; +import HdwCard from '@/components/HdwCard/index.vue'; export default defineComponent({ - name: 'LockManage' + name: 'LockManage', + components: { HdwCard }, + data() { + return { + tableData: [ + { + type: '钃濈墮', + lockName: '鏈烘煖钃濈墮閿�3', + associatedArea: '姝︽眽婧愮晠绉戞妧', + installState: '鏈畨瑁�' + } + ], + page: { + currentPage: 1, + pageSize: 20, + total: 0 + } + }; + }, + methods: { + + } }); </script> +<script lang="ts" setup> +import { + Search, + Plus +} from '@element-plus/icons-vue'; +import HdwTree from '@/components/HdwTree/index.vue'; +</script> + <template> - <div>閿佸叿绠$悊</div> + <div class="lock-wrapper"> + <div class="lock-header"> + <div class="hdw-card-container"> + <hdw-card title="鍖哄煙鍒楄〃" is-full> + <hdw-tree></hdw-tree> + </hdw-card> + </div> + </div> + <div class="lock-content"> + <hdw-card is-full> + <div class="lock-content-wrapper"> + <div class="lock-content-tools"> + <el-button type="primary" size="small" :icon="Search">鏌ヨ</el-button> + <el-button type="success" size="small" :icon="Plus">娣诲姞</el-button> + <el-button type="success" size="small" :icon="Plus">鎵归噺娣诲姞</el-button> + <div class="tools-filter"> + <div class="tools-filter-item"> + <div class="filter-label"></div> + <div class="filter-content"></div> + </div> + </div> + </div> + <div class="lock-content-table"> + <div class="pos-rel"> + <div class="pos-abs"> + <el-table :data="tableData" border style="width: 100%; height: 100%"> + <el-table-column type="index" width="50" /> + <el-table-column prop="type" label="绫诲瀷" width="180" /> + <el-table-column prop="lockName" label="閿佸叿鍚嶇О" width="180" /> + <el-table-column prop="associatedArea" label="鍏宠仈鍖哄煙" width="180" /> + <el-table-column prop="installState" label="瀹夎鐘舵��" width="180" /> + <el-table-column prop="lockImg" label="閿佸叿鍥剧墖" width="180" /> + <el-table-column prop="address" label="鍦板潃" /> + <el-table-column align="center" fixed="right" label="鎿嶄綔" width="180"> + <template #default> + <el-button type="primary" size="small">缂栬緫</el-button> + <el-button type="danger" size="small">鍒犻櫎</el-button> + </template> + </el-table-column> + </el-table> + </div> + </div> + </div> + <div class="lock-content-page"> + <div class="page-tool"></div> + <div class="el-page-container"> + <el-pagination + v-model:current-page="page.currentPage" + v-model:page-size="page.pageSize" + :page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" + size="small" + :disabled="disabled" + :background="background" + layout="total, sizes, prev, pager, next, jumper" + :total="page.total" + @size-change="handleSizeChange" + @current-change="handleCurrentChange" + /> + </div> + <div class="page-tool"></div> + </div> + </div> + </hdw-card> + </div> + <div class="lock-footer"></div> + </div> </template> <style scoped lang="scss"> +.lock-wrapper { + display: flex; + flex-direction: row; + padding: 8px; + height: 100%; + .lock-content { + flex: 1; + } +} +.lock-content-wrapper { + display: flex; + flex-direction: column; + height: 100%; + .lock-content-tools { + padding-bottom: 8px; + } + .lock-content-table { + flex: 1; + margin-left: -8px; + margin-right: -8px; + } + .lock-content-page { + padding: 8px 8px 0 8px; + text-align: center; + .el-page-container { + display: inline-block; + padding: 0 16px; + } + .page-tool { + display: inline-block; + } + } +} + +.hdw-card-container { + width: 320px; + padding-right: 8px; + height: 100%; +} +.pos-rel { + position: relative; + width: 100%; + height: 100%; + .pos-abs { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + width: 100%; + height: 100%; + } +} </style> diff --git a/vite.config.ts b/vite.config.ts index 9b74277..ef69852 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -24,6 +24,9 @@ return { base: '/', // 娉ㄦ剰锛屽繀椤讳互"/"缁撳熬锛孊ASE_URL閰嶇疆 + build: { + outDir: '../hm-lock-sys/public' + }, define: { 'process.env': env }, -- Gitblit v1.9.1