From 95fc665771abeb335b29e6d59fe74d69cf9c446f Mon Sep 17 00:00:00 2001
From: hanbaoshan <hanbaoshan@aiotlink.com>
Date: 星期四, 23 七月 2020 08:49:20 +0800
Subject: [PATCH] 首页更新,加入算法管理
---
public/images/app-mid/GB-config.png | 0
src/components/subComponents/FileUpload/list.vue | 42
public/images/app-mid/device.png | 0
public/images/app-mid/360.png | 0
src/components/subComponents/imgDown.vue | 93
src/pages/desktop/index/components/ToolsEntry.vue | 95
public/images/app-mid/data-push.png | 0
src/components/subComponents/IPInput.vue | 231 +
src/pages/desktop/index/components/Dock.vue | 14
public/images/header-icon/SmartAI.png | 0
src/assets/img/desktop/desktop.png | 0
src/components/subComponents/CardItem.vue | 881 +++++++
src/pages/desktop/index/components/Tools.vue | 124
public/images/app-mid/monitor.png | 0
public/images/app-mid/vindicate.png | 0
src/components/subComponents/FileUpload/unsupport.vue | 30
src/components/subComponents/VueCron.vue | 194 +
src/components/subComponents/FileUpload/file.vue | 452 +++
src/components/subComponents/FileUpload/btn.vue | 56
src/components/subComponents/RuleEditor.vue | 811 ++++++
src/components/subComponents/MultiRangeSlider.vue | 761 ++++++
public/images/header-icon/notice.png | 0
src/components/subComponents/LocalVedioList.vue | 129 +
public/images/app-mid/library.png | 0
public/images/header-icon/help.png | 0
public/images/app-mid/scene-config.png | 0
public/images/app-mid/poll.png | 0
public/images/app-mid/algorithm-manage.png | 0
public/images/app-mid/search.png | 0
public/images/app-mid/DVR-access.png | 0
src/components/subComponents/BoardCard.vue | 135 +
src/components/subComponents/ParticleNetwork.vue | 351 ++
src/pages/desktop/index/mock/userData.json | 7
public/images/app-mid/hashrate-manage.png | 0
src/components/subComponents/ModelCard.vue | 583 ++++
public/images/app-mid/log-manage.png | 0
public/images/app-mid/settings.png | 0
src/components/subComponents/FileUpload/common/mixins.js | 14
src/components/subComponents/FileUpload/drop.vue | 64
public/images/header-icon/search.png | 0
src/components/subComponents/FileUpload/index.vue | 230 +
src/components/subComponents/eChartsBar.vue | 174 +
public/images/logo.png | 0
src/components/subComponents/FileUpload/common/utils.js | 28
src/pages/index/app.vue | 5
src/components/subComponents/chartLiquid.vue | 141 +
src/components/subComponents/FileUpload/uploader.vue | 155 +
public/images/app-mid/camera-access.png | 0
src/pages/desktop/index/App.vue | 14
public/images/header-icon/system.png | 0
src/pages/algorithmManage/index/main.ts | 11
src/components/subComponents/FileUpload/common/file-events.js | 3
src/pages/algorithmManage/index/api.ts | 145 +
src/pages/algorithmManage/index/App.vue | 861 +++++++
src/components/subComponents/DataStackCard.vue | 158 +
package.json | 2
src/components/subComponents/FileUpload/files.vue | 42
src/components/subComponents/Card.vue | 163 +
public/images/app-mid/algorithm-store.png | 0
src/components/subComponents/LocalVedioCard.vue | 139 +
public/images/header-icon/user.png | 0
public/images/app-mid/datastack-config.png | 0
62 files changed, 7,285 insertions(+), 53 deletions(-)
diff --git a/package.json b/package.json
index 9dc2faf..e11d6ad 100644
--- a/package.json
+++ b/package.json
@@ -11,6 +11,8 @@
"axios": "^0.19.2",
"element-ui": "^2.4.6",
"qs": "^6.9.4",
+ "simple-uploader.js": "^0.5.4",
+ "spark-md5": "^3.0.1",
"vue": "^2.6.11",
"vue-qrcode-component": "^2.1.1",
"vuex": "^3.5.1"
diff --git a/public/images/app-mid/360.png b/public/images/app-mid/360.png
new file mode 100644
index 0000000..0bd5367
--- /dev/null
+++ b/public/images/app-mid/360.png
Binary files differ
diff --git a/public/images/app-mid/DVR-access.png b/public/images/app-mid/DVR-access.png
new file mode 100644
index 0000000..f99d3ac
--- /dev/null
+++ b/public/images/app-mid/DVR-access.png
Binary files differ
diff --git a/public/images/app-mid/GB-config.png b/public/images/app-mid/GB-config.png
new file mode 100644
index 0000000..c315518
--- /dev/null
+++ b/public/images/app-mid/GB-config.png
Binary files differ
diff --git a/public/images/app-mid/algorithm-manage.png b/public/images/app-mid/algorithm-manage.png
new file mode 100644
index 0000000..d71f14a
--- /dev/null
+++ b/public/images/app-mid/algorithm-manage.png
Binary files differ
diff --git a/public/images/app-mid/algorithm-store.png b/public/images/app-mid/algorithm-store.png
new file mode 100644
index 0000000..412f391
--- /dev/null
+++ b/public/images/app-mid/algorithm-store.png
Binary files differ
diff --git a/public/images/app-mid/camera-access.png b/public/images/app-mid/camera-access.png
new file mode 100644
index 0000000..35e41c7
--- /dev/null
+++ b/public/images/app-mid/camera-access.png
Binary files differ
diff --git a/public/images/app-mid/data-push.png b/public/images/app-mid/data-push.png
new file mode 100644
index 0000000..c4187c6
--- /dev/null
+++ b/public/images/app-mid/data-push.png
Binary files differ
diff --git a/public/images/app-mid/datastack-config.png b/public/images/app-mid/datastack-config.png
new file mode 100644
index 0000000..5d38c44
--- /dev/null
+++ b/public/images/app-mid/datastack-config.png
Binary files differ
diff --git a/public/images/app-mid/device.png b/public/images/app-mid/device.png
new file mode 100644
index 0000000..b0076d1
--- /dev/null
+++ b/public/images/app-mid/device.png
Binary files differ
diff --git a/public/images/app-mid/hashrate-manage.png b/public/images/app-mid/hashrate-manage.png
new file mode 100644
index 0000000..b755899
--- /dev/null
+++ b/public/images/app-mid/hashrate-manage.png
Binary files differ
diff --git a/public/images/app-mid/library.png b/public/images/app-mid/library.png
new file mode 100644
index 0000000..46681ff
--- /dev/null
+++ b/public/images/app-mid/library.png
Binary files differ
diff --git a/public/images/app-mid/log-manage.png b/public/images/app-mid/log-manage.png
new file mode 100644
index 0000000..4c90102
--- /dev/null
+++ b/public/images/app-mid/log-manage.png
Binary files differ
diff --git a/public/images/app-mid/monitor.png b/public/images/app-mid/monitor.png
new file mode 100644
index 0000000..5fa6242
--- /dev/null
+++ b/public/images/app-mid/monitor.png
Binary files differ
diff --git a/public/images/app-mid/poll.png b/public/images/app-mid/poll.png
new file mode 100644
index 0000000..8773201
--- /dev/null
+++ b/public/images/app-mid/poll.png
Binary files differ
diff --git a/public/images/app-mid/scene-config.png b/public/images/app-mid/scene-config.png
new file mode 100644
index 0000000..096c1b7
--- /dev/null
+++ b/public/images/app-mid/scene-config.png
Binary files differ
diff --git a/public/images/app-mid/search.png b/public/images/app-mid/search.png
new file mode 100644
index 0000000..e122fc9
--- /dev/null
+++ b/public/images/app-mid/search.png
Binary files differ
diff --git a/public/images/app-mid/settings.png b/public/images/app-mid/settings.png
new file mode 100644
index 0000000..02b36db
--- /dev/null
+++ b/public/images/app-mid/settings.png
Binary files differ
diff --git a/public/images/app-mid/vindicate.png b/public/images/app-mid/vindicate.png
new file mode 100644
index 0000000..038e685
--- /dev/null
+++ b/public/images/app-mid/vindicate.png
Binary files differ
diff --git a/public/images/header-icon/SmartAI.png b/public/images/header-icon/SmartAI.png
new file mode 100644
index 0000000..10b127b
--- /dev/null
+++ b/public/images/header-icon/SmartAI.png
Binary files differ
diff --git a/public/images/header-icon/help.png b/public/images/header-icon/help.png
new file mode 100644
index 0000000..e66a57f
--- /dev/null
+++ b/public/images/header-icon/help.png
Binary files differ
diff --git a/public/images/header-icon/notice.png b/public/images/header-icon/notice.png
new file mode 100644
index 0000000..ce93ca9
--- /dev/null
+++ b/public/images/header-icon/notice.png
Binary files differ
diff --git a/public/images/header-icon/search.png b/public/images/header-icon/search.png
new file mode 100644
index 0000000..b9ebcd8
--- /dev/null
+++ b/public/images/header-icon/search.png
Binary files differ
diff --git a/public/images/header-icon/system.png b/public/images/header-icon/system.png
new file mode 100644
index 0000000..4c37730
--- /dev/null
+++ b/public/images/header-icon/system.png
Binary files differ
diff --git a/public/images/header-icon/user.png b/public/images/header-icon/user.png
new file mode 100644
index 0000000..e97e46e
--- /dev/null
+++ b/public/images/header-icon/user.png
Binary files differ
diff --git a/public/images/logo.png b/public/images/logo.png
new file mode 100644
index 0000000..dabfdaa
--- /dev/null
+++ b/public/images/logo.png
Binary files differ
diff --git a/src/assets/img/desktop/desktop.png b/src/assets/img/desktop/desktop.png
new file mode 100644
index 0000000..7b9b347
--- /dev/null
+++ b/src/assets/img/desktop/desktop.png
Binary files differ
diff --git a/src/components/subComponents/BoardCard.vue b/src/components/subComponents/BoardCard.vue
new file mode 100644
index 0000000..ae1f688
--- /dev/null
+++ b/src/components/subComponents/BoardCard.vue
@@ -0,0 +1,135 @@
+<template>
+ <div class="board-card">
+ <div class="top-text">
+ <em>{{title}}</em>
+ <em style="color:#ff7733;font-size:13px">{{channelTotal}}</em>
+ </div>
+ <div class="bottom-icon">
+ <div style="height:45%;" class="flex-center">
+ <div class="right-bot-css">
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">鏈夎鍒�</div>
+ <span class="bottom-text">
+ <i class="el-icon-success" style="color:#149A46;" v-show="ValidCount.length"></i>
+ {{ValidCount}}
+ </span>
+ </el-tooltip>
+
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">鏃犺鍒�</div>
+ <span class="bottom-text">
+ <i class="el-icon-warning" style="color:orange;margin-left: 18px;" v-show="InValidCount.length"></i>
+ {{InValidCount}}
+ </span>
+ </el-tooltip>
+ </div>
+ </div>
+ <div style="width:100%;">
+ <el-divider></el-divider>
+ </div>
+ <div style="height:45%;" class="flex-center">
+ <div class="right-bot-css">
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">澶勭悊涓�</div>
+ <span class="bottom-text">
+ <i class="iconfont iconzhengzaichuli" style="color:#3D68E1;font-size:18px;" v-show="RunningCount.length"></i>
+ {{RunningCount}}
+ </span>
+ </el-tooltip>
+
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">鏈鐞�</div>
+ <span class="bottom-text">
+ <i class="iconfont iconchuli" title="鏈鐞�" style="margin-left:18px;font-size:18px;" v-show="NoDeal.length"></i>
+ {{NoDeal}}
+ </span>
+ </el-tooltip>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "BoardCard",
+ props: {
+ title: { type: String, default: "" },
+ total: { type: String, default: "" },
+ ValidCount: { type: String, default: "" },
+ InValidCount: { type: String, default: "" },
+ RunningCount: { type: String, default: "" },
+ channelTotal: { type: String, default: "" },
+ NoDeal: { type: String, default: "" },
+ width: { type: String, default: "126px"}
+ }
+}
+</script>
+<style lang="scss">
+.board-card {
+ height: 120px;
+ width: 100%;
+ display: inline-block;
+ margin: 10px;
+ background: #ffffff;
+ border: 1px solid #e2e2e2;
+ box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+ border-radius: 4px;
+ cursor: pointer;
+ .top-text {
+ line-height: 30px;
+ font-family: PingFangSC-Medium;
+ font-size: 14px;
+ color: #222222;
+ }
+ .bottom-icon {
+ width: 100%;
+ height: calc(100% - 30px);
+ }
+ .mid-text {
+ margin-bottom: 18px;
+ font-family: PingFangSC-Medium;
+ font-size: 18px;
+ color: #ff7733;
+ }
+ .bottom-text {
+ position: relative;
+ top: 3px;
+ left: 1px;
+ color: #666666;
+ font-size: 13px;
+ }
+ em {
+ font-weight: 700;
+ }
+ hr {
+ background: rgb(226, 226, 226);
+ border: 0;
+ height: 1px;
+ }
+ i {
+ font-size: 20px;
+ }
+ .divider-css{
+ height: 100%;
+ margin: 0;
+ }
+ .el-divider--horizontal {
+ display: block;
+ height: 1px;
+ width: 100%;
+ margin: 3px 0;
+ }
+ .right-top-css{
+ margin: 0px auto;
+ position: relative;
+ }
+ .right-bot-css{
+ margin: 0px auto;
+ position: relative;
+ }
+ .item {
+ margin: 4px;
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/Card.vue b/src/components/subComponents/Card.vue
new file mode 100644
index 0000000..7749870
--- /dev/null
+++ b/src/components/subComponents/Card.vue
@@ -0,0 +1,163 @@
+<template>
+ <el-card
+ class="my-card"
+ shadow="never"
+ :style="`height:${outHeight};width:${outWidth};max-height:160px;min-height:135px`"
+ :body-style="`height:${height};width:${width};`"
+ >
+ <el-carousel
+ ref="carousel"
+ :autoplay="false"
+ indicator-position="none"
+ :arrow="data.list.length > 1 ? 'always' : 'never'"
+ @change="changeHandle"
+ >
+ <el-carousel-item v-for="(item, index) in data.list" :key="index">
+ <card-item
+ :data="item"
+ :showType="showType"
+ @detailsClick="detailsClick"
+ @addToBase="toAdd"
+ ></card-item>
+ </el-carousel-item>
+ </el-carousel>
+ </el-card>
+</template>
+
+<script>
+import CardItem from "./CardItem";
+export default {
+ components: {
+ CardItem
+ },
+ props: {
+ data: {
+ type: Object,
+ default: null
+ },
+ showType: {
+ type: String,
+ default: ""
+ },
+ height: {
+ type: String,
+ default: "100%"
+ },
+ width: {
+ type: String,
+ default: "100%"
+ },
+ outHeight: {
+ type: String,
+ default: "100%"
+ },
+ outWidth: {
+ type: String,
+ default: "100%"
+ }
+ },
+ watch: {
+
+ },
+ data() {
+ return {
+ items: [],
+ filled: false
+ }
+ },
+ watch: {
+ data(newVal) {
+ this.len = this.data.list.length;
+ if (this.len > 3) {
+ this.data.list = this.data.list.slice(0, 3)
+ }
+ }
+ },
+ methods: {
+ detailsClick(ev) {
+ this.$emit("detailsClick", ev);
+ },
+ toAdd(item) {
+ this.$emit("addToBase", item);
+ },
+ changeHandle(e) {
+ // 鐐瑰嚮鍒囨崲鏃�, 浼氳Е鍙戣浜嬩欢, 姝ゆ椂閲嶆柊濉厖鍏ㄩ儴鏁版嵁, 缁勪欢浼氶噸鏂版覆鏌�, DOM鏇存柊鍚庢牴鎹偣鍑荤殑鎸夐挳,鎵嬪姩鍒囨崲
+ // filled 鎺у埗鍙湪绗竴娆$偣鍑绘椂瑙﹀彂.鐒跺悗涓嶅啀骞查璺戦┈鐏垏鎹�
+ if (this.len > 3 && !this.filled) {
+ this.items = this.data.list
+ this.filled = true
+
+ this.$nextTick(() => {
+ if (e == 1) { // 鐐瑰嚮浜嗕笅涓�寮�
+ this.$refs.carousel.next()
+ }
+ if (e == 2) { // 鐐瑰嚮浜嗕笂涓�寮�
+ this.$refs.carousel.prev()
+ }
+ })
+ }
+ }
+ }
+};
+</script>
+<style lang="scss">
+.my-active-card {
+ border: 2px solid #ff7733 !important;
+ // background: rgba(145,197,255, 0.6) !important;
+}
+.my-card {
+ box-sizing: border-box;
+ padding: 12px 10px;
+ cursor: default;
+ .el-carousel__arrow {
+ top: 90%;
+ }
+ .el-carousel__arrow {
+ height: 20px;
+ width: 20px;
+ }
+ .el-carousel__arrow:hover {
+ background-color: rgba(102, 102, 102);
+ }
+ .el-card__body {
+ padding: 0px !important;
+ }
+ .el-card:hover {
+ box-sizing: border-box;
+ }
+ // .el-carousel__arrow {
+ // top: inherit;
+ // bottom: 0px;
+ // }
+ .el-carousel {
+ height: 100% !important;
+ width: 100%;
+ .el-carousel__container {
+ height: 100% !important;
+ width: 100%;
+ }
+ }
+}
+.my-card:hover {
+ -webkit-box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.3);
+ box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.3);
+}
+</style>
+<style lang = "scss" scoped>
+.el-carousel__container {
+ height: 100% !important;
+ .el-carousel__arrow {
+ top: 70% !important;
+ }
+ .el-carousel__arrow {
+ height: 20px;
+ width: 20px;
+ }
+ .el-carousel__arrow--right {
+ right: 10px !important;
+ }
+ .el-carousel__arrow--left {
+ left: 10px !important;
+ }
+}
+</style>
diff --git a/src/components/subComponents/CardItem.vue b/src/components/subComponents/CardItem.vue
new file mode 100644
index 0000000..e6abb97
--- /dev/null
+++ b/src/components/subComponents/CardItem.vue
@@ -0,0 +1,881 @@
+<template>
+ <div class="box-card" ref="cardItem">
+ <!-- 宸︿晶鍥剧墖鍖哄煙 -->
+ <!-- 姣斿妯″紡 -->
+ <div class="s-card-left-isCompare" v-if="showType === 'compare' ">
+ <div class="card-img-box">
+ <div class="card-img-box-compear">
+ <div class="card-img-box-compear-left" ref="firstImg">
+ <img
+ :src="'/httpImage/'+data.targetInfo[0].picSmUrl+'?width=160'"
+ :id="'/compear/'+data.targetInfo[0].picSmUrl"
+ class="cursor-pointer"
+ @click="detailsClick($event)"
+ />
+ </div>
+ <el-carousel
+ @change="changeInitialIndex"
+ :initial-index="initialIndex"
+ :autoplay="false"
+ indicator-position="none"
+ :arrow="data.baseInfo.length > 1 ? 'always' : 'never'"
+ >
+ <el-carousel-item v-for="(item, index) in data.baseInfo" :key="index">
+ <img
+ :src="'/httpImage/'+item.targetPicUrl+'?width=160'"
+ class="cursor-pointer"
+ @click="detailsClick($event)"
+ />
+ </el-carousel-item>
+ </el-carousel>
+ </div>
+ <div
+ class="s-card-left-isCompare-div compareScore111"
+ style
+ :style="{
+ bottom: getBottom(),
+ background: getUrl(data.baseInfo[initialIndex].bwType)
+ }"
+ >
+ <b>{{ `${data.baseInfo[initialIndex].compareScore}%` }}</b>
+ </div>
+ </div>
+ </div>
+ <!-- 鏅�氭ā寮� -->
+ <div v-else class="s-card-left">
+ <!-- 姝e父鐨勬姄鎷嶅簱鍥剧墖 data.targetInfo == null 涓烘棤浜哄�煎畧 data.id == '' 涓哄姣斿嚭鏉ョ殑搴曞簱鍥剧墖-->
+ <div class="s-card-left-box" v-if="data.id !== ''">
+ <el-carousel
+ trigger="click"
+ height="100%"
+ indicator-position="none"
+ v-if="data.picMaxUrl.length > 1"
+ :autoplay="false"
+ @change="changeCarousel"
+ >
+ <el-carousel-item v-for="(item, index) in data.picMaxUrl" :key="index + 'img'">
+ <img
+ :src="'/httpImage/'+item+'?width=160'"
+ class="cursor-pointer"
+ @click="detailsClick($event)"
+ />
+ </el-carousel-item>
+ </el-carousel>
+ <img
+ v-else-if="data.targetInfo == null || data.targetInfo[0].picSmUrl == ''"
+ :src="'/httpImage/'+data.picMaxUrl[0]+'?width=160'"
+ class="cursor-pointer"
+ @click="detailsClick($event)"
+ />
+ <img
+ v-else
+ :src="'/httpImage/'+data.targetInfo[0].picSmUrl+'?width=160'"
+ class="cursor-pointer"
+ @click="detailsClick($event)"
+ />
+ </div>
+ <div class="s-card-left-box" v-else>
+ <img :src="'/httpImage/'+data.baseInfo[0].targetPicUrl+'?width=160'" class="cursor-pointer" />
+ </div>
+ </div>
+ <!-- 鍙充晶鏂囧瓧鍖哄煙 -->
+ <!-- 澶氬紶搴曞浘鍒囨崲 -->
+ <div class="s-card-right-isCompare" v-if="showType == 'compare'">
+ <div
+ class="person"
+ :style="overflowState ? 'overflow: hidden' : 'overflow: auto'"
+ @mouseenter="cardMouseenter($event)"
+ @mouseleave="cardMouseleave($event)"
+ >
+ <!-- <p :title="data.baseInfo[0].compareScore" class="score">
+ <span v-if="data.id">{{ data.compareScore }}%</span>
+ <span v-else>{{ data.baseInfo[0].compareScore }}%</span>
+ </p>-->
+ <p>
+ <span class="fontStyle color222">{{ data.picDate }}</span>
+ </p>
+ <p style="margin-bottom: 8px;">
+ <span class="fontStyle color222">{{ data.cameraAddr }}</span>
+ </p>
+ <el-tooltip placement="right" popper-class="atooltip">
+ <div slot="content">
+ <p v-for="(item,index) in data.alarmRules" :key="index+'rule'">
+ <span>{{data.taskName}}</span>
+ <span v-if="item.alarmLevel !== '鎾ら槻'"> {{item.alarmLevel}}</span>
+ <span v-if="item.linkInfo == '鑱斿姩浠诲姟'"> 鑱斿姩浠诲姟</span>
+ </p>
+ </div>
+ <el-button
+ style="line-height:17px;border:none;padding:0;overflow:hidden;text-overflow:ellipsis;cursor:default;width:100%;text-align:left"
+ >
+ <span
+ v-for="(item,index) in data.alarmRules"
+ :key="index+'rule1'"
+ style="text-overflow:ellipsis;max-width:100px"
+ >
+ <span class="fontStyle color666">{{data.taskName}}</span>
+ <span
+ class="fontStyle color666"
+ v-if="item.alarmLevel !== '鎾ら槻'"
+ > {{item.alarmLevel}}</span>
+ <span class="fontStyle color666" v-if="item.linkInfo == '鑱斿姩浠诲姟'"> 鑱斿姩浠诲姟</span>
+ <span v-if="index < data.alarmRules.length-1">/ </span>
+ </span>
+ </el-button>
+ </el-tooltip>
+ <el-tooltip placement="right" popper-class="atooltip">
+ <div slot="content">
+ <p>
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].tableName"
+ >{{ data.baseInfo[initialIndex].tableName }}</span>
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].targetName"
+ >/ {{ data.baseInfo[initialIndex].targetName }}</span>
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].labels"
+ >/ {{ data.baseInfo[initialIndex].labels.split("/")[1] }}</span>
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].monitorLevel"
+ >/ {{ data.baseInfo[initialIndex].monitorLevel }}</span>
+ </p>
+ </div>
+ <el-button
+ style="line-height:17px;border:none;padding:0;margin:0;overflow:hidden;text-overflow:ellipsis;cursor:default;width:100%;text-align:left"
+ >
+ <span
+ :style="data.baseInfo[initialIndex].bwType === '1'
+ ? 'color: red;font-size:12px;line-height:20px'
+ : 'font-size:12px;line-height:20px'"
+ >
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].tableName"
+ >{{ data.baseInfo[initialIndex].tableName }}</span>
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].targetName"
+ >/ {{ data.baseInfo[initialIndex].targetName }}</span>
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].labels"
+ >/ {{ data.baseInfo[initialIndex].labels.split("/")[1] }}</span>
+ <span
+ class="fontStyle"
+ v-if="data.baseInfo[initialIndex].monitorLevel"
+ >/ {{ data.baseInfo[initialIndex].monitorLevel }}</span>
+ </span>
+ </el-button>
+ </el-tooltip>
+ </div>
+ <div class="card-icon-box">
+ <el-tooltip content="璇︽儏" placement="top" popper-class="atooltip">
+ <i class="iconfont iconcaidan" @click="detailsClick($event)"></i>
+ </el-tooltip>
+ <el-tooltip content="鏌ユ壘姝や汉" placement="top" popper-class="atooltip">
+ <i class="iconfont iconsousuoren" @click="tosearch(data)"></i>
+ </el-tooltip>
+ <el-tooltip content="鍔犲叆搴曞簱" placement="top" popper-class="atooltip">
+ <i class="iconfont icontianjiaren" @click="toAdd(data)"></i>
+ </el-tooltip>
+ <el-tooltip content="鏀惰棌" placement="top" popper-class="atooltip">
+ <i class="iconfont iconshoucang2"></i>
+ </el-tooltip>
+ </div>
+ </div>
+ <!-- 搴曞簱浜哄憳妯″紡 -->
+ <div v-else-if="data.id == ''" class="s-card-right-isCompare">
+ <div
+ class="person"
+ :style="overflowState ? 'overflow: hidden' : 'overflow: auto'"
+ @mouseenter="cardMouseenter($event)"
+ @mouseleave="cardMouseleave($event)"
+ >
+ <p
+ :title="data.baseInfo[0].compareScore"
+ class="score"
+ style="font-family: PingFangSC-Medium;font-size: 20px;color: #3D68E1;letter-spacing: 0.4px;"
+ >
+ <span>{{ data.baseInfo[0].compareScore }}%</span>
+ </p>
+ <p
+ :style="data.baseInfo[0].bwType == '0' ? 'font-size:12px;line-height:20px' : 'color:red;font-size:12px;line-height:20px'"
+ >{{ data.baseInfo[0].tableName }}</p>
+ <p :style="data.baseInfo[0].bwType == '0' ? '' : 'color:red'">
+ <span>{{ data.baseInfo[0].targetName }}</span>
+ <span
+ v-if="data.baseInfo[0].labels"
+ >/ {{ data.baseInfo[0].labels.split("/")[1] }}</span>
+ </p>
+ </div>
+ <div class="card-icon-box">
+ <el-tooltip content="鏌ユ壘姝や汉" placement="top" popper-class="atooltip" style="margin-left:10px">
+ <i class="iconfont iconsousuoren" @click="tosearch(data)" title="鏌ユ壘姝や汉"></i>
+ </el-tooltip>
+ </div>
+ </div>
+ <!-- 娌℃湁搴曞簱 16锛�9鍥剧墖 鏈�姝e父鐨剏olo鎶撴媿 鏃犱汉鍊煎畧 姝e父yolo鎶撴媿娌℃湁灏忓浘-->
+ <div
+ v-else-if="data.targetInfo == null || data.targetInfo[0].picSmUrl == ''"
+ class="s-card-right-signal"
+ >
+ <div
+ class="signal-img-dev"
+ :style="overflowState ? 'overflow: hidden' : 'overflow: auto'"
+ @mouseenter="cardMouseenter($event)"
+ @mouseleave="cardMouseleave($event)"
+ >
+ <p :title="data.picDate">
+ <span class="fontStyle color222">{{ data.picDate }}</span>
+ </p>
+ <p :title="data.cameraAddr" style="margin-bottom: 8px;">
+ <span class="fontStyle color222">{{ data.cameraAddr }}</span>
+ </p>
+ <el-tooltip placement="right" popper-class="atooltip">
+ <div slot="content">
+ <p v-for="(item,index) in data.alarmRules" :key="index+'rule'">
+ <span>{{data.taskName}}</span>
+ <span v-if="item.alarmLevel !== '鎾ら槻'">{{item.alarmLevel}}</span>
+ <span v-if="item.linkInfo == '鑱斿姩浠诲姟'"> 鑱斿姩浠诲姟</span>
+ </p>
+ </div>
+ <el-button
+ style="border:none;padding:0;overflow:hidden;text-overflow:ellipsis;cursor:default;width:100%;text-align:left"
+ >
+ <span
+ v-for="(item,index) in data.alarmRules"
+ :key="index+'rule1'"
+ style="text-overflow:ellipsis;max-width:100px"
+ >
+ <span class="fontStyle color666">{{data.taskName}}</span>
+ <span
+ class="fontStyle color666"
+ v-if="item.alarmLevel !== '鎾ら槻'"
+ >{{item.alarmLevel}}</span>
+ <span class="fontStyle color666" v-if="item.linkInfo == '鑱斿姩浠诲姟'"> 鑱斿姩浠诲姟</span>
+ <span v-if="index < data.alarmRules.length-1">/ </span>
+ </span>
+ </el-button>
+ </el-tooltip>
+ </div>
+ <div class="right-bottom">
+ <div v-if="!data.id" class="card-icon-box">
+ <!-- <i class="iconfont systemxing ml50" title="鏀惰棌" ></i> -->
+ <el-tooltip content="鏌ユ壘姝や汉" placement="top" popper-class="atooltip">
+ <i class="iconfont iconsousuoren ml50" @click="tosearch(data)"></i>
+ </el-tooltip>
+ </div>
+ <div
+ v-if="data.targetInfo == null || data.targetInfo[0].picSmUrl == ''"
+ class="card-icon-box"
+ >
+ <el-tooltip content="璇︽儏" placement="top" popper-class="atooltip">
+ <i class="iconfont iconcaidan" @click="detailsClick($event)"></i>
+ </el-tooltip>
+ <el-tooltip content="鏀惰棌" placement="top" popper-class="atooltip">
+ <i class="iconfont iconshoucang2" @click="dialogVisible = true"></i>
+ </el-tooltip>
+ <!-- :class="
+ data.isAlarm ? 'iconfont systemmm' : 'iconfont systemxing'
+ "-->
+ </div>
+ <div class="card-icon-box" v-else>
+ <el-tooltip content="璇︽儏" placement="top" popper-class="atooltip">
+ <i class="iconfont iconcaidan" @click="detailsClick($event)"></i>
+ </el-tooltip>
+ <el-tooltip content="鏌ユ壘姝や汉" placement="top" popper-class="atooltip">
+ <i class="iconfont iconsousuoren" @click="tosearch(data)"></i>
+ </el-tooltip>
+ <el-tooltip content="鍔犲叆搴曞簱" placement="top" popper-class="atooltip">
+ <i class="iconfont icontianjiaren" @click="toAdd(data)"></i>
+ </el-tooltip>
+ <el-tooltip content="鏀惰棌" placement="top" popper-class="atooltip">
+ <i class="iconfont iconshoucang2" @click="dialogVisible = true"></i>
+ </el-tooltip>
+ </div>
+ </div>
+ </div>
+
+ <!-- 娌℃湁搴曞簱锛岄潪姣斿锛屾櫘閫氭ā寮� 涓�瀹氭湁targetInfo锛屽苟涓攖argetInfo涓暟涓�1-->
+ <div
+ v-else-if="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== '' && data.targetInfo.length == 1"
+ class="s-card-right-signal"
+ >
+ <div
+ class="signal-img-dev"
+ :style="overflowState ? 'overflow: hidden' : 'overflow: auto'"
+ @mouseenter="cardMouseenter($event)"
+ @mouseleave="cardMouseleave($event)"
+ >
+ <p
+ class="score"
+ v-if="VideoPhotoData.uploadType"
+ style="font-family: PingFangSC-Medium;font-size: 20px;color: #3D68E1;letter-spacing: 0.4px;"
+ >
+ <span v-if="data.id">{{ data.compareScore }}%</span>
+ <span v-else>{{ data.baseInfo[0].compareScore }}%</span>
+ </p>
+ <p :title="data.picDate">
+ <span class="fontStyle color222">{{ data.picDate }}</span>
+ </p>
+ <p :title="data.cameraAddr" style="margin-bottom: 8px;">
+ <span class="fontStyle color222">{{ data.cameraAddr }}</span>
+ </p>
+ <el-tooltip placement="right" popper-class="atooltip" v-if="!VideoPhotoData.uploadType">
+ <div slot="content">
+ <p v-for="(item,index) in data.alarmRules" :key="index+'rule2'">
+ <span class="fontStyle">{{data.taskName}}</span>
+ <span
+ class="fontStyle"
+ v-if="item.alarmLevel !== '鎾ら槻'"
+ >{{item.alarmLevel}}</span>
+ <span v-if="item.linkInfo == '鑱斿姩浠诲姟'" class="fontStyle"> 鑱斿姩浠诲姟</span>
+ <span v-if="index < data.alarmRules.length-1">/ </span>
+ </p>
+ </div>
+ <el-button
+ style="border:none;padding:0;margin:0px;overflow:hidden;text-overflow:ellipsis;cursor:default;width:100%;text-align:left"
+ >
+ <span v-for="(item,index) in data.alarmRules" :key="index+'rule3'">
+ <span class="fontStyle color666">{{data.taskName}}</span>
+ <span
+ class="fontStyle color666"
+ v-if="item.alarmLevel !== '鎾ら槻'"
+ >{{item.alarmLevel}}</span>
+ <span v-if="item.linkInfo == '鑱斿姩浠诲姟'" class="fontStyle color666"> 鑱斿姩浠诲姟</span>
+ <span v-if="index < data.alarmRules.length-1">/ </span>
+ </span>
+ </el-button>
+ </el-tooltip>
+ <!-- <p>
+ <span class="fontStyle color666">{{ data.sex }}</span> / <span class="fontStyle color666">{{ data.ageDescription }}</span> / <span class="fontStyle color666">{{ data.race }}</span>
+ </p>-->
+ <el-tooltip
+ placement="right"
+ popper-class="atooltip"
+ v-if="data.baseInfo && data.baseInfo[0].targetName != ''"
+ >
+ <div slot="content">
+ <p v-for="(item,index) in data.baseInfo" :key="index+'base1'">
+ <span class="fontStyle">{{item.tableName}}</span>
+ <span class="fontStyle" v-if="item.targetName !== ''">/ {{item.targetName}}</span>
+ <span
+ class="fontStyle"
+ v-if="item.labels !== '' && item.labels.split('/')[1] !== ''"
+ >/ {{item.labels.split("/")[1]}}</span>
+ <span
+ class="fontStyle"
+ v-if="item.labels !== '' && item.labels.split('/')[0] !== ''"
+ >/ {{item.labels.split("/")[0]}}</span>
+ </p>
+ </div>
+ <el-button
+ style="border:none;padding:0;margin:0px;overflow:hidden;text-overflow:ellipsis;cursor:default;width:100%;text-align:left"
+ >
+ <span
+ v-for="(item,index) in data.baseInfo"
+ :key="index+'base'"
+ :style="item.bwType == '1' ? 'color:red;font-size:12px;line-height:20px':'font-size:12px;line-height:20px'"
+ >
+ <span class="fontStyle">{{item.tableName}}</span>
+ <span class="fontStyle" v-if="item.targetName !== ''">/ {{item.targetName}}</span>
+ <span
+ class="fontStyle"
+ v-if="item.labels !== '' && item.labels.split('/')[1] !== ''"
+ >/ {{item.labels.split("/")[1]}}</span>
+ <span
+ class="fontStyle"
+ v-if="item.labels !== '' && item.labels.split('/')[0] !== ''"
+ >/ {{item.labels.split("/")[0]}}</span>
+ </span>
+ </el-button>
+ </el-tooltip>
+
+ <el-tooltip
+ placement="right"
+ popper-class="atooltip"
+ v-if="data.baseInfo == null"
+ style="margin-top:5px"
+ >
+ <div slot="content">
+ <span :style="'color:red;font-size:14px;line-height:20px'">{{data.showLabels}}</span>
+ </div>
+ <el-button
+ style="border:none;padding:0;margin:0px;overflow:hidden;text-overflow:ellipsis;cursor:default;width:100%;text-align:left"
+ >
+ <span :style=" 'color:red;font-size:14px;line-height:20px'">{{data.showLabels}}</span>
+ </el-button>
+ </el-tooltip>
+ </div>
+ <div class="right-bottom">
+ <div v-if="!data.id" class="card-icon-box">
+ <!-- 搴曞簱浜哄憳 -->
+ <!-- <i class="iconfont systemxing ml50" title="鏀惰棌" ></i> -->
+ <el-tooltip content="鏌ユ壘姝や汉" placement="top" popper-class="atooltip">
+ <i class="iconfont iconsousuoren ml50" @click="tosearch(data)"></i>
+ </el-tooltip>
+ </div>
+ <div v-if="data.targetInfo[0].picSmUrl == ''" class="card-icon-box">
+ <!-- yolo -->
+ <el-tooltip content="璇︽儏" placement="top" popper-class="atooltip">
+ <i class="iconfont iconcaidan" @click="detailsClick($event)"></i>
+ </el-tooltip>
+ <el-tooltip content="鏀惰棌" placement="top" popper-class="atooltip">
+ <i class="iconfont iconshoucang2"></i>
+ </el-tooltip>
+ <!-- :class="
+ data.isAlarm ? 'iconfont systemmm' : 'iconfont systemxing'
+ "-->
+ </div>
+ <div class="card-icon-box" v-else>
+ <!-- 姝e父浜鸿劯 -->
+ <el-tooltip content="璇︽儏" placement="top" popper-class="atooltip">
+ <i class="iconfont iconcaidan" @click="detailsClick($event)"></i>
+ </el-tooltip>
+ <el-tooltip
+ content="鏌ユ壘姝や汉"
+ placement="top"
+ popper-class="atooltip"
+ v-if="data.targetInfo[0].targetType == 'FaceDetect'"
+ >
+ <i class="iconfont iconsousuoren" @click="tosearch(data)"></i>
+ </el-tooltip>
+ <el-tooltip
+ content="鍔犲叆搴曞簱"
+ placement="top"
+ popper-class="atooltip"
+ v-if="data.targetInfo[0].targetType == 'FaceDetect'"
+ >
+ <i class="iconfont icontianjiaren" @click="toAdd(data)"></i>
+ </el-tooltip>
+ <el-tooltip content="鏀惰棌" placement="top" popper-class="atooltip">
+ <i class="iconfont iconshoucang2"></i>
+ </el-tooltip>
+ </div>
+ </div>
+ </div>
+ <!-- 鎸佺画鏃堕棿妯″紡锛屽寮犲浘 -->
+ <div v-else class="s-card-right-double">
+ <transition name="fade">
+ <div
+ class="double-person"
+ :style="overflowState ? 'overflow: hidden' : 'overflow: auto'"
+ @mouseenter="cardMouseenter($event)"
+ @mouseleave="cardMouseleave($event)"
+ >
+ <div>
+ <p :title="data.picDate">
+ <span class="fontStyle color222">{{ data.picDate }}</span>
+ </p>
+ <p :title="data.cameraAddr" style="margin-bottom: 8px;">
+ <span class="fontStyle color222">{{ data.cameraAddr }}</span>
+ </p>
+ <p v-for="(item,index) in data.alarmRules" :key="index+'rule'">
+ <span class="fontStyle color666">{{data.taskName}}</span> /
+ <span class="fontStyle color666">{{item.alarmLevel}}</span> /
+ <span v-if="item.linkInfo == '鑱斿姩浠诲姟'" class="fontStyle color666">鑱斿姩浠诲姟</span>
+ <span v-if="index < data.alarmRules.length-1">/ </span>
+ </p>
+ </div>
+ </div>
+ </transition>
+ </div>
+ </div>
+</template>
+
+<script>
+import cardType from "../../mockData/cardType.ts";
+import bus from "@/main";
+
+export default {
+ mounted() {
+ bus.$on('refreshCompareImg', () => {
+ // this.tempShowType = false
+ })
+ window.addEventListener("resize", this.watchWindow);
+ },
+ props: {
+ data: {
+ type: Object,
+ default: null
+ },
+ showType: {
+ type: String,
+ default: "search"
+ }
+ },
+ watch: {
+ data: {
+ handler(val, oldVal) {
+ console.log('鏁版嵁鍙戠敓鍙樺寲')
+ this.$forceUpdate()
+ },
+ deep: true
+ }
+ },
+ computed: {
+ isId() {
+ return this.data.id
+ }
+ },
+ data() {
+ return {
+ tempShowType: true,
+ initialIndex: 0,
+ cardType,
+ carouselIndex: 0,
+ dialogVisible: false,
+ overflowState: true
+ };
+ },
+ methods: {
+ watchWindow() {
+ // console.log('height')
+ // this.$nextTick(() => {
+ // document.querySelectorAll('.compareScore111').forEach(ele => {
+ // ele.style.bottom = this.getBottom()
+ // console.log("鍏冪礌鐨勬牱寮忓�硷細",ele.style.bottom)
+ // });
+ // this.$forceUpdate()
+ // })
+ },
+ getBottom() {
+ // let imgDom = document.getElementById(str)
+ let imgDom = this.$refs.firstImg
+ if (imgDom) {
+ let num = (imgDom.offsetHeight - imgDom.offsetWidth) / 2
+ return `${num}px`;
+ }
+ return `4px`;
+ },
+ getUrl(bwtype) {
+ if (bwtype == 1) {
+ return `url(${require("@/assets/bg/red.png")})`
+ } else {
+ return `url(${require("@/assets/bg/green.png")})`
+ }
+ },
+ changeInitialIndex(index) {
+ this.initialIndex = index;
+ },
+ cardMouseenter(ev) {
+ this.overflowState = false;
+ },
+ cardMouseleave(ev) {
+ this.overflowState = true;
+ },
+ changeCarousel(index) {
+ this.carouselIndex = index;
+ },
+ detailsClick(ev) {
+ this.$emit("detailsClick", ev);
+ },
+ toAdd(item) {
+ console.log("瑙﹀彂鍔犲叆搴曞簱")
+ this.$emit("addToBase", item);
+ },
+ tosearch(item) {
+ var curWwwPath = window.document.location.href;
+ var pathname = window.document.location.pathname;
+ var pos = curWwwPath.indexOf(pathname);
+ var localhostPath = curWwwPath.substring(0, pos); //ip+port
+ var href = localhostPath + "/Layout/Searching"
+ let captureId = item.id == "" ? item.baseInfo[0].targetId : item.id
+ var url = item.targetInfo ? item.targetInfo[0].picSmUrl : item.baseInfo[0].targetPicUrl
+ console.log("璺宠浆鍦板潃", href, "url", url)
+ var compType = 1 // 鏁版嵁鏉ヨ嚜浜巈s
+ if (!item.id || item.id == "") {
+ compType = 0 // 鏁版嵁鏉ヨ嚜浜庡簳搴�
+ }
+ window.open(href + '?showType=findByPic&targetId=' + captureId + '&picSmUrl=' + url + '&compType=' + compType)
+ }
+ }
+};
+</script>
+<style lang="scss">
+.fontStyle {
+ font-family: PingFangSC-Medium;
+}
+.color222 {
+ font-size: 0.75rem;
+ font-weight: 600;
+ line-height: 1rem;
+ color: #222222;
+}
+.color666 {
+ color: #666666;
+ font-size: 0.75rem;
+ line-height: 1.25rem;
+}
+.box-card {
+ cursor: default;
+ .el-carousel__arrow {
+ height: 20px;
+ width: 20px;
+ }
+ height: 100%;
+ .el-card__body {
+ height: 100%;
+ padding: 5px;
+ box-sizing: border-box;
+ }
+ .s-card-left-isCompare {
+ float: left;
+ height: 100%;
+ width: calc(60% - 10px);
+ margin-right: 10px;
+ .card-img-box {
+ box-sizing: border-box;
+ width: 100%;
+ height: 100%;
+ position: relative;
+ overflow: hidden;
+ .card-img-box-compear {
+ height: 100%;
+ width: 100%;
+ display: flex;
+ .card-img-box-compear-left {
+ display: inline-block;
+ display: flex;
+ justify-content: center;
+ align-items: Center;
+ overflow: hidden;
+ width: 100%;
+ height: 100%;
+ }
+ .el-carousel__item {
+ display: flex;
+ justify-content: center;
+ align-items: Center;
+ overflow: hidden;
+ }
+ .el-carousel__container {
+ height: 100% !important;
+ .el-carousel__arrow {
+ top: 50% !important;
+ }
+ .el-carousel__arrow {
+ height: 20px;
+ width: 20px;
+ }
+ .el-carousel__arrow--right {
+ right: 5px !important;
+ }
+ .el-carousel__arrow--left {
+ left: 5px !important;
+ }
+ }
+ }
+ }
+ .card-icon-box {
+ width: 100%;
+ text-align: left;
+ position: absolute;
+ bottom: 0px;
+ i {
+ font-size: 20px !important;
+ padding-right: 10px;
+ cursor: pointer;
+ }
+ }
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ }
+ .s-card-left-isCompare-div {
+ width: 60px;
+ position: absolute;
+ left: calc(50% - 35px);
+ bottom: 16px;
+ padding: 0px 8px;
+ height: 20px;
+ line-height: 20px;
+ color: white;
+ //background-color: red;
+ z-index: 2;
+ border-top-right-radius: 5px;
+ border-top-left-radius: 5px;
+ background-size: 100% 100%;
+ }
+ }
+ .s-card-left {
+ float: left;
+ height: 100%;
+ width: calc(50% - 10px);
+ margin-right: 10px;
+ .s-card-left-box {
+ overflow: hidden;
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ .el-carousel__arrow {
+ top: 50%;
+ bottom: inherit;
+ }
+ }
+ .card-icon-box {
+ height: 30px;
+ width: 100%;
+ text-align: left;
+ margin-left: 10px;
+ padding-top: 10px;
+ i {
+ color: #3d68e1;
+ font-size: 20px !important;
+ padding-right: 10px;
+ cursor: pointer;
+ }
+ }
+ .el-carousel {
+ height: 100%;
+ width: 100%;
+ .el-carousel__container {
+ height: 100 !important;
+ width: 100%;
+ }
+ .el-carousel__item {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background-color: #fff;
+ }
+ }
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ }
+ }
+ .s-card-right-isCompare {
+ width: 40%;
+ height: 100%;
+ float: left;
+ padding-left: 10px;
+ box-sizing: border-box;
+ position: relative;
+ .active-pull {
+ height: 100% !important;
+ overflow: auto !important;
+ position: relative;
+ z-index: 1;
+ }
+ .overflow {
+ overflow: auto !important;
+ }
+ .person {
+ height: calc(100% - 25px);
+ overflow: hidden;
+ background-color: #fff;
+ text-align: left;
+ .score {
+ font-size: 25px;
+ }
+ p {
+ width: 100%;
+ overflow: hidden;
+ padding: 3px 0px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ // cursor: pointer;
+ b {
+ display: inline-block;
+ width: 48px;
+ }
+ }
+ }
+ .card-icon-box {
+ width: 100%;
+ text-align: left;
+ position: absolute;
+ bottom: 0px;
+ i {
+ color: #3d68e1;
+ font-size: 20px !important;
+ padding-right: 10px;
+ cursor: pointer;
+ }
+ }
+ }
+ .s-card-right-signal {
+ width: 50%;
+ height: 100%;
+ float: left;
+ overflow: hidden;
+ background-color: #fff;
+ text-align: left;
+ padding-left: 10px;
+ box-sizing: border-box;
+ position: relative;
+ .el-carousel__arrow {
+ top: 50%;
+ }
+ p {
+ width: 100%;
+ overflow: hidden;
+ padding: 3px 0px;
+ text-overflow: ellipsis;
+ // cursor: pointer;
+ white-space: nowrap;
+ b {
+ display: inline-block;
+ width: 48px;
+ }
+ }
+ .signal-img-dev {
+ height: 100%;
+ width: 100%;
+ //overflow: auto;
+ }
+ .right-bottom {
+ width: 100%;
+ text-align: left;
+ position: absolute;
+ bottom: 0px;
+ i {
+ color: #3d68e1;
+ font-size: 20px !important;
+ padding-right: 10px;
+ cursor: pointer;
+ }
+ }
+ }
+ .s-card-right-double {
+ width: 50%;
+ height: 100%;
+ float: left;
+ overflow: hidden;
+ background-color: #fff;
+ text-align: left;
+ box-sizing: border-box;
+ .double-person {
+ padding: 10px;
+ box-sizing: border-box;
+ overflow: auto;
+ p {
+ width: 100%;
+ overflow: hidden;
+ padding: 3px 0px;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ // cursor: pointer;
+ b {
+ display: inline-block;
+ width: 48px;
+ }
+ }
+ }
+ .double-person,
+ div {
+ height: 100%;
+ width: 100%;
+ }
+ }
+}
+</style>
diff --git a/src/components/subComponents/DataStackCard.vue b/src/components/subComponents/DataStackCard.vue
new file mode 100644
index 0000000..0cd0054
--- /dev/null
+++ b/src/components/subComponents/DataStackCard.vue
@@ -0,0 +1,158 @@
+<template>
+ <div class="s-board-card flex-center">
+ <div style="width:38%;">
+ <div class="top-text">
+ <em>{{title}}</em>
+ </div>
+ <div class="mid-text">
+ <em>{{total}}</em>
+ </div>
+ </div>
+ <div style="height:86px;">
+ <el-divider class="divider-css" direction="vertical"></el-divider>
+ </div>
+ <div style="width:61%;height:100%;">
+ <div style="height:50%;" class="flex-center right-bot-css">
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">鍏ㄩ儴鎵撳紑鍒嗘瀽寮�鍏�</div>
+ <span class="bottom-text">
+ <i class="iconfont iconquanbu" style="color:#3D68E1;" v-show="ValidCount.length"></i>
+ {{ValidCount}}
+ </span>
+ </el-tooltip>
+
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">绠楁硶閰嶇疆涓嶅叏</div>
+ <span class="bottom-text">
+ <i
+ class="iconfont iconicon-test6"
+ style="color:#3D68E1;margin-left: 15px;"
+ v-show="InValidCount.length"
+ ></i>
+ {{InValidCount}}
+ </span>
+ </el-tooltip>
+ </div>
+ <div style="width:100%;">
+ <el-divider></el-divider>
+ </div>
+ <div style="height:40%;" class="flex-center right-bot-css">
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">姝e湪鎵ц鍒嗘瀽澶勭悊</div>
+ <span class="bottom-text">
+ <i class="iconfont iconicon-test11" style="color:#3D68E1" v-show="RunningCount.length"></i>
+ {{RunningCount}}
+ </span>
+ </el-tooltip>
+
+ <el-tooltip effect="dark" placement="top">
+ <div slot="content">{{fourTip}}</div>
+ <span class="bottom-text">
+ <i
+ :class="`iconfont ${fourIcon}`"
+ style="color:#3D68E1;margin-left:15px;"
+ v-show="NoDeal.length"
+ ></i>
+ {{NoDeal}}
+ </span>
+ </el-tooltip>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "BoardCard",
+ props: {
+ title: { type: String, default: "" },
+ total: { type: String, default: "" },
+ ValidCount: { type: String, default: "" },
+ InValidCount: { type: String, default: "" },
+ RunningCount: { type: String, default: "" },
+ NoDeal: { type: String, default: "" },
+ width: { type: String, default: "126px" },
+ fourTip: { type: String, default: "" },
+ fourIcon: { type: String, default: "" }
+ }
+}
+</script>
+<style lang="scss">
+.s-board-card {
+ height: 120px;
+ width: 100%;
+ display: inline-block;
+ margin: 10px;
+ background: #ffffff;
+ border: 1px solid #e2e2e2;
+ box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+ border-radius: 4px;
+ cursor: pointer;
+ .top-text {
+ line-height: 30px;
+ font-family: PingFangSC-Medium;
+ font-size: 14px;
+ color: #222222;
+ }
+ .mid-text {
+ margin-bottom: 18px;
+ font-family: PingFangSC-Medium;
+ font-size: 18px;
+ color: #ff7733;
+ }
+ .bottom-text {
+ word-break: keep-all;
+ text-align: right;
+ // position: relative;
+ // top: 3px;
+ // left: 1px;
+ // color: #666666;
+ // font-size: 13px;
+ }
+ em {
+ font-weight: 700;
+ }
+ hr {
+ background: rgb(226, 226, 226);
+ border: 0;
+ height: 1px;
+ }
+ i {
+ font-size: 20px;
+ }
+ .divider-css {
+ height: 100%;
+ margin: 0;
+ }
+ .el-divider--horizontal {
+ display: block;
+ height: 1px;
+ width: 100%;
+ margin: 3px 0;
+ }
+ .right-top-css {
+ margin: 0px auto;
+ position: relative;
+ }
+ .right-bot-css {
+ margin: 0px 5px;
+ position: relative;
+ }
+ .out-div-33 {
+ width: 33%;
+ height: 100%;
+ .txt-css {
+ width: 100%;
+ height: 50%;
+ position: relative;
+ top: 30px;
+ }
+ .icon-css {
+ width: 100%;
+ height: 30%;
+ margin-top: 10px;
+ position: relative;
+ }
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/FileUpload/btn.vue b/src/components/subComponents/FileUpload/btn.vue
new file mode 100644
index 0000000..7ea24ff
--- /dev/null
+++ b/src/components/subComponents/FileUpload/btn.vue
@@ -0,0 +1,56 @@
+<template>
+ <label class="uploader-btn" ref="btn" v-show="support">
+ <slot></slot>
+ </label>
+</template>
+
+<script>
+import { uploaderMixin, supportMixin } from './common/mixins'
+
+const COMPONENT_NAME = 'uploader-btn'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin, supportMixin],
+ props: {
+ directory: {
+ type: Boolean,
+ default: false
+ },
+ single: {
+ type: Boolean,
+ default: false
+ },
+ attrs: {
+ type: Object,
+ default() {
+ return {}
+ }
+ }
+ },
+ mounted() {
+ this.$nextTick(() => {
+ this.uploader.uploader.assignBrowse(this.$refs.btn, this.directory, this.single, this.attrs)
+ })
+ }
+}
+</script>
+
+<style>
+.uploader-btn {
+ display: inline-block;
+ position: relative;
+ padding: 4px 8px;
+ font-size: 100%;
+ line-height: 1.4;
+ color: #666;
+ border: 1px solid #666;
+ cursor: pointer;
+ border-radius: 2px;
+ background: none;
+ outline: none;
+}
+.uploader-btn:hover {
+ background-color: rgba(0, 0, 0, 0.08);
+}
+</style>
diff --git a/src/components/subComponents/FileUpload/common/file-events.js b/src/components/subComponents/FileUpload/common/file-events.js
new file mode 100644
index 0000000..2aba807
--- /dev/null
+++ b/src/components/subComponents/FileUpload/common/file-events.js
@@ -0,0 +1,3 @@
+const events = ['fileProgress', 'fileSuccess', 'fileComplete', 'fileError']
+
+export default events
diff --git a/src/components/subComponents/FileUpload/common/mixins.js b/src/components/subComponents/FileUpload/common/mixins.js
new file mode 100644
index 0000000..efab3b0
--- /dev/null
+++ b/src/components/subComponents/FileUpload/common/mixins.js
@@ -0,0 +1,14 @@
+export const uploaderMixin = {
+ inject: ['uploader']
+}
+
+export const supportMixin = {
+ data () {
+ return {
+ support: true
+ }
+ },
+ mounted () {
+ this.support = this.uploader.uploader.support
+ }
+}
diff --git a/src/components/subComponents/FileUpload/common/utils.js b/src/components/subComponents/FileUpload/common/utils.js
new file mode 100644
index 0000000..92c775a
--- /dev/null
+++ b/src/components/subComponents/FileUpload/common/utils.js
@@ -0,0 +1,28 @@
+export function secondsToStr(temp) {
+ const years = Math.floor(temp / 31536000)
+ if (years) {
+ return years + ' 骞�' + numberEnding(years)
+ }
+ const days = Math.floor((temp %= 31536000) / 86400)
+ if (days) {
+ return days + ' 澶�' + numberEnding(days)
+ }
+ const hours = Math.floor((temp %= 86400) / 3600)
+ if (hours) {
+ return hours + ' 灏忔椂' + numberEnding(hours)
+ }
+ const minutes = Math.floor((temp %= 3600) / 60)
+ if (minutes) {
+ return minutes + ' 鍒�' + numberEnding(minutes)
+ }
+ const seconds = temp % 60
+ return seconds + ' 绉�' + numberEnding(seconds)
+ function numberEnding(number) {
+ // return (number > 1) ? 's' : ''
+ return ''
+ }
+}
+
+export function kebabCase(s) {
+ return s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)
+}
diff --git a/src/components/subComponents/FileUpload/drop.vue b/src/components/subComponents/FileUpload/drop.vue
new file mode 100644
index 0000000..9c88666
--- /dev/null
+++ b/src/components/subComponents/FileUpload/drop.vue
@@ -0,0 +1,64 @@
+<template>
+ <div class="uploader-drop" :class="dropClass" ref="drop" v-show="support">
+ <slot></slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin, supportMixin } from './common/mixins'
+
+const COMPONENT_NAME = 'uploader-drop'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin, supportMixin],
+ data() {
+ return {
+ dropClass: ''
+ }
+ },
+ methods: {
+ onDragEnter() {
+ this.dropClass = 'uploader-dragover'
+ },
+ onDragLeave() {
+ this.dropClass = ''
+ },
+ onDrop() {
+ this.dropClass = 'uploader-droped'
+ }
+ },
+ mounted() {
+ this.$nextTick(() => {
+ const dropEle = this.$refs.drop
+ const uploader = this.uploader.uploader
+ uploader.assignDrop(dropEle)
+ uploader.on('dragenter', this.onDragEnter)
+ uploader.on('dragleave', this.onDragLeave)
+ uploader.on('drop', this.onDrop)
+ })
+ },
+ beforeDestroy() {
+ const dropEle = this.$refs.drop
+ const uploader = this.uploader.uploader
+ uploader.off('dragenter', this.onDragEnter)
+ uploader.off('dragleave', this.onDragLeave)
+ uploader.off('drop', this.onDrop)
+ uploader.unAssignDrop(dropEle)
+ }
+}
+</script>
+
+<style>
+.uploader-drop {
+ position: relative;
+ padding: 10px;
+ overflow: hidden;
+ border: 1px dashed #ccc;
+ background-color: #f5f5f5;
+}
+.uploader-dragover {
+ border-color: #999;
+ background-color: #f7f7f7;
+}
+</style>
diff --git a/src/components/subComponents/FileUpload/file.vue b/src/components/subComponents/FileUpload/file.vue
new file mode 100644
index 0000000..43034f2
--- /dev/null
+++ b/src/components/subComponents/FileUpload/file.vue
@@ -0,0 +1,452 @@
+<template>
+ <div class="uploader-file" :status="status">
+ <slot
+ :file="file"
+ :list="list"
+ :status="status"
+ :paused="paused"
+ :error="error"
+ :response="response"
+ :average-speed="averageSpeed"
+ :formated-average-speed="formatedAverageSpeed"
+ :current-speed="currentSpeed"
+ :is-complete="isComplete"
+ :is-uploading="isUploading"
+ :size="size"
+ :formated-size="formatedSize"
+ :uploaded-size="uploadedSize"
+ :progress="progress"
+ :progress-style="progressStyle"
+ :progressing-class="progressingClass"
+ :time-remaining="timeRemaining"
+ :formated-time-remaining="formatedTimeRemaining"
+ :type="type"
+ :extension="extension"
+ :file-category="fileCategory"
+ >
+ <div class="uploader-file-progress" :class="progressingClass" :style="progressStyle"></div>
+ <div class="uploader-file-info">
+ <div class="uploader-file-name">
+ <i class="uploader-file-icon" :icon="fileCategory"></i>
+ {{file.name}}
+ </div>
+ <div class="uploader-file-size">{{formatedSize}}</div>
+ <div class="uploader-file-meta"></div>
+ <div class="uploader-file-status">
+ <span v-show="status !== 'uploading'">{{statusText}}</span>
+ <span v-show="status === 'uploading'">
+ <!-- <span>{{progressStyle.progress}}</span> -->
+ <em>{{formatedAverageSpeed}}</em>
+
+ <i> {{formatedTimeRemaining}}</i>
+ </span>
+ </div>
+ <div class="uploader-file-actions">
+ <span class="uploader-file-pause" @click="pause"></span>
+ <span class="uploader-file-resume" @click="resume">锔�</span>
+ <span class="uploader-file-retry" @click="retry"></span>
+ <span class="uploader-file-remove" @click="remove"></span>
+ </div>
+ </div>
+ </slot>
+ </div>
+</template>
+
+<script>
+import Uploader from 'simple-uploader.js'
+import events from './common/file-events'
+import { secondsToStr } from './common/utils'
+
+const COMPONENT_NAME = 'uploader-file'
+
+export default {
+ name: COMPONENT_NAME,
+ props: {
+ file: {
+ type: Object,
+ default() {
+ return {}
+ }
+ },
+ list: {
+ type: Boolean,
+ default: false
+ }
+ },
+ data() {
+ return {
+ response: null,
+ paused: false,
+ error: false,
+ averageSpeed: 0,
+ currentSpeed: 0,
+ isComplete: false,
+ isUploading: false,
+ size: 0,
+ formatedSize: '',
+ uploadedSize: 0,
+ progress: 0,
+ timeRemaining: 0,
+ type: '',
+ extension: '',
+ progressingClass: ''
+ }
+ },
+ computed: {
+ fileCategory() {
+ const extension = this.extension
+ const isFolder = this.file.isFolder
+ let type = isFolder ? 'folder' : 'unknown'
+ const categoryMap = this.file.uploader.opts.categoryMap
+ const typeMap = categoryMap || {
+ image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'],
+ video: ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'],
+ audio: ['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac'],
+ document: ['doc', 'txt', 'docx', 'pages', 'epub', 'pdf', 'numbers', 'csv', 'xls', 'xlsx', 'keynote', 'ppt', 'pptx']
+ }
+ Object.keys(typeMap).forEach((_type) => {
+ const extensions = typeMap[_type]
+ if (extensions.indexOf(extension) > -1) {
+ type = _type
+ }
+ })
+ return type
+ },
+ progressStyle() {
+ const progress = Math.floor(this.progress * 100)
+ const style = `translateX(${Math.floor(progress - 100)}%)`
+ return {
+ progress: `${progress}%`,
+ webkitTransform: style,
+ mozTransform: style,
+ msTransform: style,
+ transform: style
+ }
+ },
+ formatedAverageSpeed() {
+ return `${Uploader.utils.formatSize(this.averageSpeed)} / s`
+ },
+ status() {
+ const isUploading = this.isUploading
+ const isComplete = this.isComplete
+ const isError = this.error
+ const paused = this.paused
+ if (isComplete) {
+ return 'success'
+ } else if (isError) {
+ return 'error'
+ } else if (isUploading) {
+ return 'uploading'
+ } else if (paused) {
+ return 'paused'
+ } else {
+ return 'waiting'
+ }
+ },
+ statusText() {
+ const status = this.status
+ const fileStatusText = this.file.uploader.fileStatusText
+ let txt = status
+ if (typeof fileStatusText === 'function') {
+ txt = fileStatusText(status, this.response)
+ } else {
+ txt = fileStatusText[status]
+ }
+ return txt || status
+ },
+ formatedTimeRemaining() {
+ const timeRemaining = this.timeRemaining
+ const file = this.file
+ if (timeRemaining === Number.POSITIVE_INFINITY || timeRemaining === 0) {
+ return ''
+ }
+ let parsedTimeRemaining = secondsToStr(timeRemaining)
+ const parseTimeRemaining = file.uploader.opts.parseTimeRemaining
+ if (parseTimeRemaining) {
+ parsedTimeRemaining = parseTimeRemaining(timeRemaining, parsedTimeRemaining)
+ }
+ return parsedTimeRemaining
+ }
+ },
+ watch: {
+ status(newStatus, oldStatus) {
+ if (oldStatus && newStatus === 'uploading' && oldStatus !== 'uploading') {
+ this.tid = setTimeout(() => {
+ this.progressingClass = 'uploader-file-progressing'
+ }, 200)
+ } else {
+ clearTimeout(this.tid)
+ this.progressingClass = ''
+ }
+ }
+ },
+ methods: {
+ _actionCheck() {
+ this.paused = this.file.paused
+ this.error = this.file.error
+ this.isUploading = this.file.isUploading()
+ },
+ pause() {
+ this.file.pause()
+ this._actionCheck()
+ this._fileProgress()
+ },
+ resume() {
+ this.file.resume()
+ this._actionCheck()
+ },
+ remove() {
+ this.file.cancel()
+ },
+ retry() {
+ this.file.retry()
+ this._actionCheck()
+ },
+ processResponse(message) {
+ debugger
+ let res = message
+ try {
+ res = JSON.parse(message)
+ } catch (e) { }
+ this.response = res
+ },
+ fileEventsHandler(event, args) {
+ const rootFile = args[0]
+ const file = args[1]
+ const target = this.list ? rootFile : file
+ if (this.file === target) {
+ if (this.list && event === 'fileSuccess') {
+ this.processResponse(args[2])
+ return
+ }
+ this[`_${event}`].apply(this, args)
+ }
+ },
+ _fileProgress() {
+ this.progress = this.file.progress()
+ this.averageSpeed = this.file.averageSpeed
+ this.currentSpeed = this.file.currentSpeed
+ this.timeRemaining = this.file.timeRemaining()
+ this.uploadedSize = this.file.sizeUploaded()
+ this._actionCheck()
+ },
+ _fileSuccess(rootFile, file, message) {
+ if (rootFile) {
+ this.processResponse(message)
+ }
+ this._fileProgress()
+ this.error = false
+ this.isComplete = true
+ this.isUploading = false
+ console.log('rootFile, file, message',rootFile, file, message)
+ debugger
+ },
+ _fileComplete() {
+ this._fileSuccess()
+ },
+ _fileError(rootFile, file, message) {
+ this._fileProgress()
+ console.log('rootFile, file, message',rootFile, file, message)
+ debugger
+ this.processResponse(message)
+ this.error = true
+ this.isComplete = false
+ this.isUploading = false
+ }
+ },
+ mounted() {
+ const staticProps = ['paused', 'error', 'averageSpeed', 'currentSpeed']
+ const fnProps = [
+ 'isComplete',
+ 'isUploading',
+ {
+ key: 'size',
+ fn: 'getSize'
+ },
+ {
+ key: 'formatedSize',
+ fn: 'getFormatSize'
+ },
+ {
+ key: 'uploadedSize',
+ fn: 'sizeUploaded'
+ },
+ 'progress',
+ 'timeRemaining',
+ {
+ key: 'type',
+ fn: 'getType'
+ },
+ {
+ key: 'extension',
+ fn: 'getExtension'
+ }
+ ]
+ staticProps.forEach(prop => {
+ this[prop] = this.file[prop]
+ })
+ fnProps.forEach((fnProp) => {
+ if (typeof fnProp === 'string') {
+ this[fnProp] = this.file[fnProp]()
+ } else {
+ this[fnProp.key] = this.file[fnProp.fn]()
+ }
+ })
+
+ const handlers = this._handlers = {}
+ const eventHandler = (event) => {
+ handlers[event] = (...args) => {
+ this.fileEventsHandler(event, args)
+ }
+ return handlers[event]
+ }
+ events.forEach((event) => {
+ this.file.uploader.on(event, eventHandler(event))
+ })
+ },
+ destroyed() {
+ events.forEach((event) => {
+ this.file.uploader.off(event, this._handlers[event])
+ })
+ this._handlers = null
+ }
+}
+</script>
+
+<style>
+.uploader-file {
+ position: relative;
+ height: 49px;
+ line-height: 49px;
+ overflow: hidden;
+ border-bottom: 1px solid #cdcdcd;
+}
+.uploader-file[status="waiting"] .uploader-file-pause,
+.uploader-file[status="uploading"] .uploader-file-pause {
+ display: block;
+}
+.uploader-file[status="paused"] .uploader-file-resume {
+ display: block;
+}
+.uploader-file[status="error"] .uploader-file-retry {
+ display: block;
+}
+.uploader-file[status="success"] .uploader-file-remove {
+ display: none;
+}
+.uploader-file[status="error"] .uploader-file-progress {
+ background: #ffe0e0;
+}
+.uploader-file-progress {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background: #e2eeff;
+ transform: translateX(-100%);
+}
+.uploader-file-progressing {
+ transition: all 0.4s linear;
+}
+.uploader-file-info {
+ position: relative;
+ z-index: 1;
+ height: 100%;
+ overflow: hidden;
+}
+.uploader-file-info:hover {
+ background-color: rgba(240, 240, 240, 0.2);
+}
+.uploader-file-info i,
+.uploader-file-info em {
+ font-style: normal;
+}
+.uploader-file-name,
+.uploader-file-size,
+.uploader-file-meta,
+.uploader-file-status,
+.uploader-file-actions {
+ float: left;
+ position: relative;
+ height: 100%;
+}
+.uploader-file-name {
+ width: 50%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ text-indent: 14px;
+ text-align: left;
+}
+.uploader-file-icon {
+ width: 24px;
+ height: 24px;
+ display: inline-block;
+ vertical-align: top;
+ margin-top: 13px;
+ margin-right: 8px;
+}
+.uploader-file-icon::before {
+ content: "馃搩";
+ display: block;
+ height: 100%;
+ font-size: 24px;
+ line-height: 1;
+ text-indent: 0;
+}
+.uploader-file-icon[icon="folder"]::before {
+ content: "馃搨";
+}
+.uploader-file-icon[icon="image"]::before {
+ content: "馃寙";
+}
+.uploader-file-icon[icon="video"]::before {
+ content: "馃幀";
+}
+.uploader-file-icon[icon="audio"]::before {
+ content: "馃幍";
+}
+.uploader-file-icon[icon="document"]::before {
+ content: "馃搵";
+}
+.uploader-file-size {
+ width: 11%;
+ text-indent: 10px;
+}
+.uploader-file-meta {
+ width: 8%;
+}
+.uploader-file-status {
+ width: 24%;
+ text-indent: 20px;
+}
+.uploader-file-actions {
+ width: 6%;
+}
+.uploader-file-actions > span {
+ display: none;
+ float: left;
+ width: 16px;
+ height: 16px;
+ margin-top: 16px;
+ margin-right: 10px;
+ cursor: pointer;
+ background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAABkCAYAAAD0ZHJ6AAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAJcEhZcwAACxMAAAsTAQCanBgAAARkSURBVGje7ZnfS1NRHMAH4ptPkvQSuAdBkCxD8FUQJMEULUgzy1KyyPVQ4JMiiP4Bvg6EwUQQfMmwhwRDshwaKUjDVCgoSdDNHkzTJZ6+Z37Purve8+PeTb2TM/ggu+ew89l33x8H9BBCPG7GowXTJej3+wnDvEm0JuLC04+EYWftVAUv+fiCvDUdQR1BHUEdQR3BTIygvixoQS14XgTtthLVdpNWwXRLqvQ724LplFRtyrYF0yVpFLQrKRVMh6RZ0I6kkmCqklaCqpKZH0FX56Crq9jVfdDVk0RfFrSgFsxkQVmLcdKCVrKySCrryhPEyYShhzOcrFtG0EoilfHHk1CRU5rF6ZjNZhlVOW6RnMSVyyilKies4pO41diVy8wIujoHXV3FGdMHXTtJKLFYTLhZtq4vC1rwXApCZTIqgR6g1PBMCO9DL3bMMSqBHqDU8EyISDAHiGKvWwcCQG2KgjlAFCDAOhAAap0K5gKLphk8mqJgLrCIgoxRJ4J5wKpJ7gAoMkn5EBXBPGDVJHcAFJmkfIhQcAql1oBpTvTol9gG9pm4RHAKpdaAaU706JfYBvaZuJVgPQrt4sFlnOh5MC/p3lmJYD0K7eLBZZzoeTAv6d5ZnuAYHjpgEOnk5F0ufhG6v1ggOIaHDhhEOjl5l4tfhO4vthLcwAMrFNvLJO5vEwhu4IEViu1lEve3WQmyoihQFBzG/V0CQVYUBYqCw7i/SxTBcpsRbFeIYLnNCLZbCY5b5KAnxRwct8hBj9McZFVMW0ihRNBuFdMWUigRlFaxuQ9WWYjRMTiIe5z0wSoLMToGB3GPsA9aTZIJoB+nRgBnM1tzOkkmgH6cGgGczWzNpzqLx3n/aULJJgezeNw07oxQySbVywKjBOgFRnDs+VEsx8FlgVEC9AIjOPb8KJYjvSzoG7UW1IJaUAtqQS14toLNM5fN5APdwBJA8G83Pk/aK/rgzVvXzeQD3cASQPBvNz5P2ssTzAaGUIrHEO6zI5gNDKEUjyHcxxWkh4Ylcowwk1QQpIeGJXKMMJO0EgwqyjGCioJBJvDrxRMSuVOTJEXfbz1/bHwWtBL0yoQehK6RucgE+bGzanzulQh6E3IgQV+xpc8kcrfuSO7eTfJ3ZYmQw0Oy9azVKOk1C/bJ5D5F38YPeLfx0rjWJxHsS0SqsSYuxySjj5qO5Oj7xQWy2VBtFOwzCy6ryH3YfE3uh64Y1xckgstJPydEjkkeHv07Iy4Xaao15+KCWTBx6M/db+T9xivSErqaJDdzXI6yLRE8Vgg0coex/SPJvT0SbWu0KpZtbgSpCH3NRt7I5OxHkObc6heU+/M/J5vrpBFM5GBLqCQux14COXs5CNXK5OjPGm1tSMrJSOMNYQ4mVTGV/L6zTL7+DovkbFUxbSW0Wo05l8hJWsU+cRWfSh+Mt5Lb1ck/J1TvVsdDaR/MiEni+llsdZuZp62EViu+96bpNjNPWwmtVnzvFd5m9IVVC54x/wA7gNvqFG9vXQAAAABJRU5ErkJggg==")
+ no-repeat 0 0;
+}
+.uploader-file-actions > span:hover {
+ background-position-x: -21px;
+}
+.uploader-file-actions .uploader-file-pause {
+ background-position-y: 0;
+}
+.uploader-file-actions .uploader-file-resume {
+ background-position-y: -17px;
+}
+.uploader-file-actions .uploader-file-retry {
+ background-position-y: -53px;
+}
+.uploader-file-actions .uploader-file-remove {
+ display: block;
+ background-position-y: -34px;
+}
+</style>
diff --git a/src/components/subComponents/FileUpload/files.vue b/src/components/subComponents/FileUpload/files.vue
new file mode 100644
index 0000000..1380ba9
--- /dev/null
+++ b/src/components/subComponents/FileUpload/files.vue
@@ -0,0 +1,42 @@
+<template>
+ <div class="uploader-files">
+ <slot :files="files">
+ <ul>
+ <li v-for="file in files" :key="file.id">
+ <uploader-file :file="file"></uploader-file>
+ </li>
+ </ul>
+ </slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin } from './common/mixins'
+import UploaderFile from './file.vue'
+
+const COMPONENT_NAME = 'uploader-files'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin],
+ computed: {
+ files() {
+ return this.uploader.files
+ }
+ },
+ components: {
+ UploaderFile
+ }
+}
+</script>
+
+<style>
+.uploader-files {
+ position: relative;
+}
+.uploader-files > ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+</style>
diff --git a/src/components/subComponents/FileUpload/index.vue b/src/components/subComponents/FileUpload/index.vue
new file mode 100644
index 0000000..97c4562
--- /dev/null
+++ b/src/components/subComponents/FileUpload/index.vue
@@ -0,0 +1,230 @@
+<template>
+ <div class="file-uploader">
+ <uploader
+ v-if="single"
+ ref="uploader"
+ :options="options"
+ :file-status-text="statusText"
+ class="uploader-single"
+ @file-added="onFileAdded"
+ @complete="onComplete"
+ >
+ <el-input :placeholder="uploadPlaceholder" size="small" :readonly="true" v-model="fileName">
+ <uploader-btn slot="suffix" >
+ <el-tooltip :content="tipWords" placement="top" v-if="tip">
+ <i class="el-icon-upload2" style="font-size:18px; color:#0088ff"></i>
+ </el-tooltip>
+ <i v-else class="el-icon-upload2" style="font-size:18px; color:#0088ff"></i>
+ </uploader-btn>
+ </el-input>
+ <uploader-list />
+ </uploader>
+
+ <uploader
+ v-else
+ ref="uploader"
+ :options="options"
+ :file-status-text="statusText"
+ class="uploader-example"
+ @file-added="onFileAdded"
+ @file-complete="fileComplete"
+ @complete="onComplete"
+ @close="closeHandle"
+ >
+ <uploader-btn ref="button">
+ <i class="el-icon-upload2" style="font-size:18px; color:#0088ff"></i>
+ 涓婁紶
+ </uploader-btn>
+ <uploader-list />
+ </uploader>
+ </div>
+</template>
+
+<script>
+import uploader from "./uploader"
+import SparkMD5 from 'spark-md5';
+import UploaderBtn from "./btn"
+import UploaderList from "./list"
+
+export default {
+ components: {
+ uploader,
+ UploaderBtn,
+ UploaderList
+ },
+ props: {
+ tip: {
+ type: Boolean,
+ default: false
+ },
+ tipWords: {
+ type: String,
+ default: ''
+ },
+ single: {
+ type: Boolean,
+ default: false
+ },
+ uploadPlaceholder: {
+ type: String,
+ default: ''
+ },
+ url: {
+ type: String,
+ default: "/data/api-f/file/upload" //"//192.168.20.10:3000/upload"
+ },
+ },
+ data() {
+ return {
+ fileName: "",
+ fileMd5: "",
+ attrs: {
+ accept: 'image/*'
+ },
+ statusText: {
+ success: '涓婁紶鎴愬姛',
+ error: '涓婁紶澶辫触',
+ uploading: '涓婁紶涓�',
+ paused: '鏆傚仠涓�',
+ waiting: '绛夊緟涓�'
+ }
+ }
+ },
+ computed: {
+ uploader() {
+ return this.$refs.uploader.uploader;
+ },
+ options() {
+ return {
+ target: this.url,
+ testChunks: true,
+ headers: {
+ Authorization: sessionStorage.getItem('loginedInfo') && JSON.parse(sessionStorage.getItem('loginedInfo')).access_token
+ }
+ }
+ }
+ },
+ methods: {
+ onFileAdded(file) {
+ if (this.single) {
+ this.uploader.fileList = this.uploader.fileList.slice([-1]);
+ this.$emit("file-added")
+ }
+ this.computeMD5(file);
+ },
+ computeMD5(file) {
+ let fileReader = new FileReader();
+ let time = new Date().getTime();
+ let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
+ let currentChunk = 0;
+ const chunkSize = 10 * 1024 * 1000;
+ let chunks = Math.ceil(file.size / chunkSize);
+ let spark = new SparkMD5.ArrayBuffer();
+ // 鏂囦欢鐘舵�佽涓�"璁$畻MD5"
+ this.statusText.paused = "鍑嗗涓婁紶,姝e湪妫�鏌ユ枃浠�"
+ file.pause();
+ loadNext();
+ fileReader.onload = (e => {
+ spark.append(e.target.result);
+ if (currentChunk < chunks) {
+ currentChunk++;
+ loadNext();
+ } else {
+ let md5 = spark.end();
+ this.computeMD5Success(md5, file);
+ this.fileName = file.name;
+ this.fileMd5 = md5;
+ // console.log(`MD5璁$畻瀹屾瘯锛�${file.name} \nMD5锛�${md5} \n鍒嗙墖锛�${chunks} 澶у皬:${file.size} 鐢ㄦ椂锛�${new Date().getTime() - time} ms`);
+ }
+ });
+ fileReader.onerror = function () {
+ this.error(`鏂囦欢${file.name}璇诲彇鍑洪敊锛岃妫�鏌ヨ鏂囦欢`)
+ file.cancel();
+ };
+ function loadNext() {
+ let start = currentChunk * chunkSize;
+ let end = ((start + chunkSize) >= file.size) ? file.size : start + chunkSize;
+ fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
+ }
+ },
+ computeMD5Success(md5, file) {
+ // 灏嗚嚜瀹氫箟鍙傛暟鐩存帴鍔犺浇uploader瀹炰緥鐨刼pts涓�
+ if (this.$route.path.indexOf("VideoManage") >= 0) {
+ Object.assign(this.uploader.opts, {
+ query: {
+ stackId: this.DataStackPool.selectedDir.id
+ // ...this.params,
+ }
+ })
+ }
+ file.uniqueIdentifier = md5;
+ file.resume();
+ this.statusText.paused = "鏆傚仠涓�";
+ },
+ onComplete() {
+ debugger
+ this.$emit("complete", { filename: this.fileName, identifier: this.fileMd5 });
+ },
+ fileComplete() {
+ // console.log('file complete', arguments)
+ },
+ closeHandle() {
+ this.$emit("close")
+ }
+ },
+ mounted() {
+ this.$nextTick(() => {
+ window.uploader = this.$refs.uploader.uploader
+ })
+ }
+}
+</script>
+
+<style lang="scss">
+.file-uploader {
+ .el-input__suffix,.el-input__suffix-inner{
+ outline: none!important;
+ }
+ .el-tooltip.focusing{
+ outline: none;
+ }
+ .uploader-example {
+ width: 99%;
+ // padding: 15px;
+ // margin: 40px auto 0;
+ font-size: 12px;
+ // box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
+ background-color: #fff;
+ }
+ .uploader-example .uploader-btn {
+ position: relative;
+ display: none;
+ // float: right;
+ // top: -45px;
+ }
+ .uploader-example .uploader-list {
+ max-height: 440px;
+ overflow: auto;
+ overflow-x: hidden;
+ overflow-y: auto;
+ }
+ .uploader-single {
+ position: unset;
+ .close {
+ display: none;
+ }
+ .uploader-btn {
+ border: 0px;
+ }
+ .uploader-file {
+ height: 2px;
+ .uploader-file-progress {
+ background: #3d68e1;
+ }
+ .uploader-file-info {
+ display: none;
+ }
+ }
+ }
+}
+</style>>
diff --git a/src/components/subComponents/FileUpload/list.vue b/src/components/subComponents/FileUpload/list.vue
new file mode 100644
index 0000000..b572727
--- /dev/null
+++ b/src/components/subComponents/FileUpload/list.vue
@@ -0,0 +1,42 @@
+<template>
+ <div class="uploader-list">
+ <slot :file-list="fileList">
+ <ul>
+ <li v-for="file in fileList" :key="file.id">
+ <uploader-file :file="file" :list="true"></uploader-file>
+ </li>
+ </ul>
+ </slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin } from './common/mixins'
+import UploaderFile from './file.vue'
+
+const COMPONENT_NAME = 'uploader-list'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin],
+ computed: {
+ fileList() {
+ return this.uploader.fileList
+ }
+ },
+ components: {
+ UploaderFile
+ }
+}
+</script>
+
+<style>
+.uploader-list {
+ position: relative;
+}
+.uploader-list > ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+</style>
diff --git a/src/components/subComponents/FileUpload/unsupport.vue b/src/components/subComponents/FileUpload/unsupport.vue
new file mode 100644
index 0000000..59626ee
--- /dev/null
+++ b/src/components/subComponents/FileUpload/unsupport.vue
@@ -0,0 +1,30 @@
+<template>
+ <div class="uploader-unsupport" v-show="!support">
+ <slot>
+ <p>
+ Your browser, unfortunately, is not supported by Uploader.js. The library requires support for
+ <a href="http://www.w3.org/TR/FileAPI/">the HTML5 File API</a> along with
+ <a href="http://www.w3.org/TR/FileAPI/#normalization-of-params">file slicing</a>.
+ </p>
+ </slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin, supportMixin } from './common/mixins'
+
+const COMPONENT_NAME = 'uploader-unsupport'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin, supportMixin]
+}
+</script>
+
+<style>
+.uploader-unsupport {
+ position: relative;
+ z-index: 10;
+ overflow: hidden;
+}
+</style>
diff --git a/src/components/subComponents/FileUpload/uploader.vue b/src/components/subComponents/FileUpload/uploader.vue
new file mode 100644
index 0000000..2df8221
--- /dev/null
+++ b/src/components/subComponents/FileUpload/uploader.vue
@@ -0,0 +1,155 @@
+<template>
+ <div class="uploader">
+ <!-- <div class="close" @click="closeHandle">x</div> -->
+ <slot :files="files" :file-list="fileList" :started="started">
+ <uploader-unsupport></uploader-unsupport>
+ <uploader-drop>
+ <!-- <p>鎷栧姩鏂囦欢鍒拌鍖哄煙涓婁紶</p> -->
+ <uploader-btn>閫夋嫨鏂囦欢</uploader-btn>
+ <uploader-btn :directory="true">閫夋嫨鏂囦欢澶�</uploader-btn>
+ </uploader-drop>
+ <uploader-list></uploader-list>
+ </slot>
+ </div>
+</template>
+
+<script>
+import Uploader from 'simple-uploader.js'
+import { kebabCase } from './common/utils'
+import UploaderBtn from './btn.vue'
+import UploaderDrop from './drop.vue'
+import UploaderUnsupport from './unsupport.vue'
+import UploaderList from './list.vue'
+
+const COMPONENT_NAME = 'uploader'
+const FILE_ADDED_EVENT = 'fileAdded'
+const FILES_ADDED_EVENT = 'filesAdded'
+const UPLOAD_START_EVENT = 'uploadStart'
+
+export default {
+ name: COMPONENT_NAME,
+ provide() {
+ return {
+ uploader: this
+ }
+ },
+ props: {
+ options: {
+ type: Object,
+ default() {
+ return {}
+ }
+ },
+ autoStart: {
+ type: Boolean,
+ default: true
+ },
+ fileStatusText: {
+ type: [Object, Function],
+ default() {
+ return {
+ success: 'success',
+ error: 'error',
+ uploading: 'uploading',
+ paused: 'paused',
+ waiting: 'waiting'
+ }
+ }
+ }
+ },
+ data() {
+ return {
+ started: false,
+ files: [],
+ fileList: []
+ }
+ },
+ methods: {
+ uploadStart() {
+ this.started = true
+ },
+ fileAdded(file) {
+ this.$emit(kebabCase(FILE_ADDED_EVENT), file)
+ if (file.ignored) {
+ // is ignored, filter it
+ return false
+ }
+ },
+ filesAdded(files, fileList) {
+ this.$emit(kebabCase(FILES_ADDED_EVENT), files, fileList)
+ if (files.ignored || fileList.ignored) {
+ // is ignored, filter it
+ return false
+ }
+ },
+ fileRemoved(file) {
+ this.files = this.uploader.files
+ this.fileList = this.uploader.fileList
+ },
+ filesSubmitted(files, fileList) {
+ this.files = this.uploader.files
+ this.fileList = this.uploader.fileList
+ if (this.autoStart) {
+ this.uploader.upload()
+ }
+ },
+ allEvent(...args) {
+ const name = args[0]
+ const EVENTSMAP = {
+ [FILE_ADDED_EVENT]: true,
+ [FILES_ADDED_EVENT]: true,
+ [UPLOAD_START_EVENT]: 'uploadStart'
+ }
+ const handler = EVENTSMAP[name]
+ if (handler) {
+ if (handler === true) {
+ return
+ }
+ this[handler].apply(this, args.slice(1))
+ }
+ args[0] = kebabCase(name)
+ this.$emit.apply(this, args)
+ },
+ closeHandle() {
+ this.$emit("close")
+ }
+ },
+ created() {
+ this.options.initialPaused = !this.autoStart
+ const uploader = new Uploader(this.options)
+ this.uploader = uploader
+ this.uploader.fileStatusText = this.fileStatusText
+ uploader.on('catchAll', this.allEvent)
+ uploader.on(FILE_ADDED_EVENT, this.fileAdded)
+ uploader.on(FILES_ADDED_EVENT, this.filesAdded)
+ uploader.on('fileRemoved', this.fileRemoved)
+ uploader.on('filesSubmitted', this.filesSubmitted)
+ },
+ destroyed() {
+ const uploader = this.uploader
+ uploader.off('catchAll', this.allEvent)
+ uploader.off(FILE_ADDED_EVENT, this.fileAdded)
+ uploader.off(FILES_ADDED_EVENT, this.filesAdded)
+ uploader.off('fileRemoved', this.fileRemoved)
+ uploader.off('filesSubmitted', this.filesSubmitted)
+ this.uploader = null
+ },
+ components: {
+ UploaderBtn,
+ UploaderDrop,
+ UploaderUnsupport,
+ UploaderList
+ }
+}
+</script>
+
+<style lang="scss">
+.uploader {
+ .close {
+ position: absolute;
+ right: 5px;
+ top: 3px;
+ cursor: pointer;
+ }
+}
+</style>
diff --git a/src/components/subComponents/IPInput.vue b/src/components/subComponents/IPInput.vue
new file mode 100644
index 0000000..4f59322
--- /dev/null
+++ b/src/components/subComponents/IPInput.vue
@@ -0,0 +1,231 @@
+<template>
+ <div class="ip-input-container">
+ <div class="ip-segment" v-for="(segment, index) in segments" :key="index">
+ <input
+ type="text"
+ maxlength="3"
+ class="ip-segment-input"
+ :value="segment"
+ :placeholder="placeholder"
+ :disabled="disabled"
+ v-on:keydown="onInputKeydown($event, index)"
+ v-on:input="onInput($event, index)"
+ v-on:blur="onInputBlur()"
+ v-on:paste="onPaste($event, index)"
+ />
+ <i v-show="index != segments.length - 1">.</i>
+ </div>
+ </div>
+</template>
+
+<script>
+/* global document*/
+/**
+ * get the cursor position of the element
+ * @param {Element} el the element
+ * @return {Integer} the position fo the cursor
+ */
+function getRange(el) {
+ var cuRange;
+ var tbRange;
+ var headRange;
+ var range;
+ var dupRange;
+ var ret = {};
+ if (el.setSelectionRange) {
+ // standard
+ ret.begin = el.selectionStart;
+ ret.end = el.selectionEnd;
+ ret.result = el.value.substring(ret.begin, ret.end);
+ } else if (document.selection) {
+ // ie
+ if (el.tagName.toLowerCase() === "input") {
+ cuRange = document.selection.createRange();
+ tbRange = el.createTextRange();
+ tbRange.collapse(true);
+ tbRange.select();
+ headRange = document.selection.createRange();
+ headRange.setEndPoint("EndToEnd", cuRange);
+ ret.begin = headRange.text.length - cuRange.text.length;
+ ret.end = headRange.text.length;
+ ret.result = cuRange.text;
+ cuRange.select();
+ } else if (el.tagName.toLowerCase() === "textarea") {
+ range = document.selection.createRange();
+ dupRange = range.duplicate();
+ dupRange.moveToElementText(el);
+ dupRange.setEndPoint("EndToEnd", range);
+ ret.begin = dupRange.text.length - range.text.length;
+ ret.end = dupRange.text.length;
+ ret.result = range.text;
+ }
+ }
+ el.focus();
+ return ret;
+}
+export default {
+ props: {
+ ip: {
+ type: String,
+ defalut: ""
+ },
+ item: {},
+ placeholder: String,
+ onChange: Function,
+ onBlur: Function,
+ onItemChange: Function,
+ disabled: {
+ type: Boolean,
+ default: false
+ }
+ },
+ data() {
+ return {
+ segments: ["", "", "", ""]
+ };
+ },
+ watch: {
+ ip(ip) {
+ this.syncIp(ip);
+ }
+ },
+ methods: {
+ onInputKeydown(event, index) {
+ var keyCode = event.keyCode || event.which;
+ var value = event.target.value;
+ if (keyCode === 8 || keyCode === 37) {
+ // move the cursor to previous input if backspace and left arrow is pressed at the begin of one input
+ if (
+ (value.length === 0 || getRange(event.target).end === 0) &&
+ index > 0
+ ) {
+ this.$el.getElementsByTagName("input")[index - 1].focus();
+ // When jump to pre input(enter "backspace"), thr cursor should in the end.
+ // before fix: 127.|0.0.0 => 12|7.0.0.1
+ // after fix: 127.|0.0.0 = > 127|.0.0.0
+ // notes: "|" mean the cursor position.
+ event.preventDefault();
+ }
+ } else if (keyCode === 39 && keyCode === 110) {
+ if (getRange(event.target).end === value.length && index < 3) {
+ // move to cursor to the next input if right arrow is pressed at the end of one input
+ this.$el.getElementsByTagName("input")[index + 1].focus();
+ }
+ }
+ },
+ onInput(event, index) {
+ var value = event.target.value;
+ event.target.value = this.segments[index];
+ var segment = Number(value);
+ if (isNaN(segment)) {
+ return;
+ } else if (value === "") {
+ this.segments.splice(index, 1, "");
+ } else if (segment > 255 || segment < 0) {
+ // set the segment to 255 if out of ip range
+ this.segments.splice(index, 1, 255);
+ } else {
+ this.segments.splice(index, 1, segment);
+ }
+ // jump to next input
+ if (
+ (value.length === 3 && index < 3) ||
+ value[value.length - 1] === "."
+ ) {
+ this.$el.getElementsByTagName("input")[index + 1].focus();
+ }
+ },
+ onInputBlur() {
+ setTimeout(() => {
+ this.$emit("on-blur", this.segments.join("."));
+ if (this.onBlur) {
+ this.onBlur(this.segments.join("."));
+ }
+ if (this.onItemChange) {
+ this.onItemChange(this.segments.join("."), this.item)
+ }
+ }, 50);
+ },
+ onPaste(e, index) {
+ var pasteText = e.clipboardData.getData("text/plain");
+ var segments = pasteText.split(".");
+ segments.forEach((segment, i) => {
+ if (
+ index + i < 4 &&
+ !isNaN(segment) &&
+ segment >= 0 &&
+ segment <= 255
+ ) {
+ this.segments.splice(index + i, 1, segment);
+ }
+ });
+ e.preventDefault();
+ },
+ syncIp(ip) {
+ if (ip && ip.indexOf(".") !== -1) {
+ ip.split(".").map((segment, index) => {
+ if (isNaN(segment) || segment < 0 || segment > 255) {
+ segment = 255;
+ }
+ this.segments.splice(index, 1, segment);
+ return segment;
+ });
+ }
+ }
+ },
+ mounted() {
+ this.syncIp(this.ip);
+ this.$watch(
+ () => {
+ return this.segments.join(".");
+ },
+ (val, oldValue) => {
+ if (val !== oldValue) {
+ if (val === "...") {
+ val = "";
+ }
+ if (this.onChange) {
+ this.onChange(val);
+ }
+ }
+ }
+ );
+ }
+};
+</script>
+
+<style lang="scss" scoped>
+.ip-input-container {
+ display: inline-block;
+ width: 100%;
+ height: 32px;
+ line-height: normal;
+ border: 1px solid #dcdfe6;
+ box-sizing: border-box;
+ background-color: #fff;
+ text-align: left;
+ max-width: 360px;
+}
+.ip-segment {
+ display: inline-block;
+ width: 25%;
+ height: 32px;
+ line-height: normal;
+ input {
+ width: 90%;
+ height: 32px;
+ line-height: normal;
+ border: none;
+ outline: none;
+ text-align: center;
+ text-indent: 0px;
+ margin: 0px;
+ padding: 0px;
+ background-color: transparent;
+ }
+ i {
+ display: inline-block;
+ font-size: 18px;
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/LocalVedioCard.vue b/src/components/subComponents/LocalVedioCard.vue
new file mode 100644
index 0000000..a1c5bd1
--- /dev/null
+++ b/src/components/subComponents/LocalVedioCard.vue
@@ -0,0 +1,139 @@
+<template>
+ <div class="board-card flex-center">
+ <div style="width:40%;">
+ <div class="top-text">
+ <em>{{title}}</em>
+ </div>
+ <div class="mid-text">
+ <em>{{total}}</em>
+ </div>
+ </div>
+ <div style="height:86px;">
+ <el-divider class="divider-css" direction="vertical"></el-divider>
+ </div>
+ <div style="width:59%;height:100%;" class="flex-center">
+ <div class="out-div-33">
+ <div class="txt-css">
+ <span>瑙嗛</span>
+ </div>
+ <el-tooltip v-if="total" effect="dark" placement="top" content="蹇欑">
+ <div class="icon-css">
+ <i class="iconfont iconmanglu"></i>
+ </div>
+ </el-tooltip>
+ <el-tooltip v-else effect="dark" placement="top" content="绛夊緟">
+ <div class="icon-css">
+ <i class="iconfont icondengdai1"></i>
+ </div>
+ </el-tooltip>
+ </div>
+ <div style="height:86px;">
+ <el-divider class="divider-css" direction="vertical"></el-divider>
+ </div>
+ <div class="out-div-33">
+ <div class="txt-css">
+ <span>鍥剧墖</span>
+ </div>
+ <el-tooltip effect="dark" placement="top" content="绛夊緟">
+ <div class="icon-css">
+ <i class="iconfont icondengdai1"></i>
+ </div>
+ </el-tooltip>
+ </div>
+ <div style="height:86px;">
+ <el-divider class="divider-css" direction="vertical"></el-divider>
+ </div>
+ <div class="out-div-33">
+ <div class="txt-css">
+ <span>闊抽</span>
+ </div>
+ <el-tooltip effect="dark" placement="top" content="绛夊緟">
+ <div class="icon-css">
+ <i class="iconfont icondengdai1"></i>
+ </div>
+ </el-tooltip>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "BoardCard",
+ props: {
+ title: { type: String, default: "" },
+ total: { type: String, default: "" },
+ success: { type: String, default: "" },
+ warning: { type: String, default: "" }
+ }
+}
+</script>
+<style lang="scss">
+.board-card {
+ height: 120px;
+ width: 100%;
+ display: inline-block;
+ margin: 10px;
+ background: #ffffff;
+ border: 1px solid #e2e2e2;
+ box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
+ border-radius: 4px;
+ cursor: pointer;
+ .top-text {
+ line-height: 30px;
+ font-family: PingFangSC-Medium;
+ font-size: 14px;
+ color: #222222;
+ }
+ .mid-text {
+ margin-bottom: 18px;
+ font-family: PingFangSC-Medium;
+ font-size: 18px;
+ color: #ff7733;
+ }
+ .bottom-text {
+ position: relative;
+ top: 3px;
+ left: 1px;
+ color: #666666;
+ font-size: 13px;
+ }
+ em {
+ font-weight: 700;
+ }
+ hr {
+ background: rgb(226, 226, 226);
+ border: 0;
+ height: 1px;
+ }
+ i {
+ font-size: 20px;
+ }
+ .divider-css{
+ height: 100%;
+ margin: 0;
+ }
+ .el-divider--horizontal {
+ display: block;
+ height: 1px;
+ width: 100%;
+ margin: 3px 0;
+ }
+ .out-div-33{
+ width: 33%;
+ height: 100%;
+ .txt-css{
+ width: 100%;
+ height: 50%;
+ position: relative;
+ top: 30px;
+ }
+ .icon-css{
+ width: 100%;
+ height: 30%;
+ margin-top: 10px;
+ position: relative;
+ }
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/LocalVedioList.vue b/src/components/subComponents/LocalVedioList.vue
new file mode 100644
index 0000000..511f87c
--- /dev/null
+++ b/src/components/subComponents/LocalVedioList.vue
@@ -0,0 +1,129 @@
+<template>
+ <div id="realTimeList" class="out-div-rt">
+ <div class="top-menu">
+ <span class="iconfont iconku" style="font-size:20px;"></span>
+ <span style="font-size:14px; margin-left: 5px;font-weight: 600;">鏁版嵁鏍�</span>
+ </div>
+ <ul>
+ <li
+ v-for="(item,index) in DataStackPool.dirs"
+ :key="index"
+ @click="handleClick(item)"
+ :class="DataStackPool.selectedDir.id == item.id ? 'bg' : ''"
+ >
+ <!-- 鏂囦欢澶瑰浘鏍� -->
+ <span class="iconfont iconshipinwenjianjia-new folder" v-if="item.type === 1"></span>
+ <span class="iconfont icontupianwenjianjia-copy folder" v-else-if="item.type === 2"></span>
+ <span class="iconfont iconshipinwenjianjia1 folder" v-else-if="item.type === 3"></span>
+ <span class="iconfont iconwenjian folder" v-else></span>
+
+ <span class="folder-name">{{item.name}}</span>
+
+ <!-- 绠楁硶閰嶇疆涓嶅叏 -->
+ <i class="iconfont iconicon-test6 folder-status" v-if="item.status === 0"></i>
+ <!-- 姝e湪澶勭悊 -->
+ <i class="iconfont iconicon-test11 folder-status" v-else-if="item.status === 2"></i>
+ <!-- 绛夊緟澶勭悊 -->
+ <i class="iconfont iconicon-test5 folder-status" v-else-if="item.status === 1"></i>
+ <!-- 鏈煡鍘熷洜 -->
+ <i class="iconfont iconicon-test5 folder-status" v-else></i>
+ <!-- <i class="iconfont iconicon-test11 folder-status"></i> -->
+ <el-switch
+ size="mini"
+ style="float:right; margin:2px 5px;"
+ v-model="item.enable"
+ @change="switchEnable(item)"
+ ></el-switch>
+ </li>
+ </ul>
+ </div>
+</template>
+<script>
+import { switchDir } from "@/api/localVedio"
+
+export default {
+ name: 'localVedioList',
+ props: {
+ isMutl: {
+ type: Boolean,
+ default: true
+ }
+ },
+ data() {
+ return {
+ list: [],
+ checkedVedio: [],
+ isShow: true,
+ dateMill: new Date(),
+ showCheckBox: false,
+ }
+ },
+ methods: {
+ handleClick(item) {
+ this.DataStackPool.selectedDir = item;
+ },
+ switchEnable(item) {
+ switchDir({ enable: item.enable, id: item.id }).then(rsp => {
+ console.log(rsp)
+ })
+ }
+ }
+}
+</script>
+<style lang="scss">
+.out-div-rt {
+ width: 100%;
+ height: 100%;
+ .top-menu {
+ text-align: left;
+ }
+
+ .folder {
+ color: #3d68e1;
+ font-size: 20px;
+ float: left;
+ line-height: 25px;
+ }
+ .folder-name {
+ font-size: 14px;
+ margin-left: 5px;
+ float: left;
+ line-height: 27px;
+ }
+ .folder-status {
+ color: #3d68e1;
+ font-size: 18px;
+ float: right;
+ line-height: 25px;
+ }
+
+ ul {
+ margin: 10px 25px;
+ }
+ li {
+ width: 100%;
+ height: 25px;
+ margin-top: 2px;
+ cursor: pointer;
+ .el-switch__core {
+ width: 27px !important;
+ height: 14px;
+ }
+ .el-switch__core:after {
+ width: 10px;
+ height: 10px;
+ }
+ .el-switch.is-checked .el-switch__core::after {
+ left: 100%;
+ margin-left: -11px;
+ }
+ }
+}
+
+.bg {
+ background: #e1e1e1;
+}
+.clickStatus {
+ background: #e1e1e1;
+}
+</style>
diff --git a/src/components/subComponents/ModelCard.vue b/src/components/subComponents/ModelCard.vue
new file mode 100644
index 0000000..febadaf
--- /dev/null
+++ b/src/components/subComponents/ModelCard.vue
@@ -0,0 +1,583 @@
+<template>
+ <div class="model-card-box" :style="`height:${height};width:${width};`">
+ <el-tabs style="height: 100%;" @before-leave="changeTabs" v-model="VideoPhotoData.activeName">
+ <el-tab-pane label="澶у浘" name="pic">
+ <div
+ class="model-card-box-left"
+ :style="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+ ? 'width: 65%;padding: 5px;box-sizing: border-box'
+ : 'width: 100%;padding: 5px;box-sizing: border-box'"
+ >
+ <div class="img-box">
+ <p class="img-box-title">
+ <b>鍏ㄦ櫙鍥�</b>
+ </p>
+ <img-down
+ v-if="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''"
+ :url="data.picMaxUrl[0]"
+ ></img-down>
+ <!-- 浜鸿劯绫诲瀷 -->
+ <img-down
+ v-else-if="(data.targetInfo == null || data.targetInfo[0].picSmUrl == '') && data.picMaxUrl.length == 1"
+ :url="data.picMaxUrl[0]"
+ ></img-down>
+ <!-- 鏅�歽olo绫� -->
+ <el-carousel
+ v-else-if="(data.targetInfo == null || data.targetInfo[0].picSmUrl == '') && data.picMaxUrl.length > 1"
+ trigger="click"
+ height="100%"
+ :autoplay="false"
+ >
+ <el-carousel-item v-for="(item, index) in data.picMaxUrl" :key="index">
+ <img-down :url="item"></img-down>
+ </el-carousel-item>
+ </el-carousel>
+ <!-- 鎸佺画鏃堕棿yolo绫� -->
+ <div
+ class="describe"
+ v-if="data.targetInfo == null || data.targetInfo[0].picSmUrl == ''"
+ >
+ <p>
+ <span class="fontStyleForModel">{{ data.picDate }}</span>
+ </p>
+ <p>
+ <span class="fontStyleForModel">{{ data.cameraAddr }}</span>
+ </p>
+ <p style="width:100%">
+ <span v-for="(item,index) in data.alarmRules" :key="index+'rule'">
+ <span class="fontStyleForModel">{{data.taskName}}</span>
+ <span
+ v-if="item.alarmLevel !== '鎾ら槻'"
+ class="fontStyleForModel"
+ >{{item.alarmLevel}}</span>
+ <span v-if="item.isLink" class="fontStyleForModel">鑱斿姩浠诲姟</span>
+ <span v-if="index < data.alarmRules.length-1">/ </span>
+ </span>
+ </p>
+ </div>
+ <!-- yolo绫诲ぇ鍥� -->
+ <div class="describeBigImage" v-else>
+ <p>
+ <span class="fontStyleForModel">{{ data.picDate }}</span>
+ </p>
+ <p>
+ <span class="fontStyleForModel">{{ data.cameraAddr }}</span>
+ </p>
+ <p style="width:100%">
+ <span v-for="(item,index) in data.alarmRules" :key="index+'rule'">
+ <span class="fontStyleForModel">{{data.taskName}}</span>
+ <span
+ v-if="item.alarmLevel !== '鎾ら槻'"
+ class="fontStyleForModel"
+ >{{item.alarmLevel}}</span>
+ <span v-if="item.isLink" class="fontStyleForModel">鑱斿姩浠诲姟</span>
+ <span v-if="index < data.alarmRules.length-1">/ </span>
+ </span>
+ </p>
+ <p style="width:100%">
+ <span class="fontStyleForModel">{{data.showLabels}}</span>
+ </p>
+ </div>
+ <!-- 浜鸿劯绫诲ぇ鍥� -->
+ </div>
+ </div>
+ <div
+ v-if="data.targetInfo && data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''"
+ class="model-card-box-right"
+ :style="data.targetInfo && data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+ ? 'width: 35%;box-sizing: border-box;'
+ : ''"
+ >
+ <p class="img-box-title">
+ <b>鎶撴媿鍥�</b>
+ </p>
+ <!-- 宸﹀彸涓ゅ紶鐨勪汉鑴稿姣旀ā寮� -->
+ <div class="img-box" v-if="data.baseInfo && data.baseInfo.length >= 1" ref="picSmBox">
+ <div class="card-img-box-compear-left">
+ <!-- <img :src="'/httpImage/'+data.targetInfo[0].picSmUrl" ref="picSm" /> -->
+ <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+ </div>
+ <el-carousel
+ @change="changeInitialIndex"
+ :initial-index="initialIndex"
+ :autoplay="false"
+ indicator-position="none"
+ :arrow="data.baseInfo.length > 1 ? 'always' : 'never'"
+ v-if="data.baseInfo[0].targetPicUrl != ''"
+ class="card-img-box-compear-right"
+ >
+ <el-carousel-item v-for="(item, index) in data.baseInfo" :key="index">
+ <!-- <img :src="'/httpImage/'+item.targetPicUrl" /> -->
+ <img-down :url="item.targetPicUrl" :isPreview="false"></img-down>
+ </el-carousel-item>
+ </el-carousel>
+ <div
+ class="img-compareScore"
+ v-if="data.baseInfo[0].targetPicUrl != ''"
+ :style="
+ data.baseInfo[initialIndex].bwType === '1'
+ ? `background: red;`
+ : `background: green;`
+ "
+ >
+ <b>{{ data.baseInfo[initialIndex].compareScore | percentage }}</b>
+ </div>
+ </div>
+ <!-- 娌℃湁姣斿鐨勪汉鑴歌瘑鍒ā寮� -->
+ <div class="img-box" v-if="!data.baseInfo && data.targetInfo[0].picSmUrl !== '' ">
+ <div class="card-img-box-compear-left" style="width:60%;margin-top:5px">
+ <!-- <img :src="'/httpImage/'+data.targetInfo[0].picSmUrl" /> -->
+ <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+ </div>
+ </div>
+ <div class="baseInfo" v-if="data.baseInfo && data.baseInfo[0].targetPicUrl != ''">
+ <div class="baseInfo_left">
+ <p>
+ <span class="labelInfo">搴曞簱</span>
+ </p>
+ <p>
+ <span class="labelInfo">濮撳悕</span>
+ </p>
+ <p>
+ <span class="labelInfo">鎬у埆</span>
+ </p>
+ <p>
+ <span class="labelInfo">韬唤璇佸彿</span>
+ </p>
+ <p>
+ <span class="labelInfo">鎵嬫満鍙�</span>
+ </p>
+ <p>
+ <span class="labelInfo">浜哄憳绛夌骇</span>
+ </p>
+ </div>
+ <div class="baseInfo_right">
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].tableName"
+ >{{ data.baseInfo[initialIndex].tableName }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].targetName"
+ >{{ data.baseInfo[initialIndex].targetName }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].labels.split('/')[1]"
+ >{{ data.baseInfo[initialIndex].labels.split("/")[1] }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].labels.split('/')[2]"
+ >{{ data.baseInfo[initialIndex].labels.split("/")[2] }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].labels.split('/')[0]"
+ >{{ data.baseInfo[initialIndex].labels.split("/")[0] }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].monitorLevel"
+ >{{ data.baseInfo[initialIndex].monitorLevel }}</span>
+ </p>
+ </div>
+ </div>
+ </div>
+ </el-tab-pane>
+ <el-tab-pane label="瑙嗛" name="video" class="video-tabs">
+ <div
+ class="model-card-box-left"
+ :style="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+ ? 'width: 65%;padding: 5px;box-sizing: border-box'
+ : 'width: 70%;padding: 5px;box-sizing: border-box;margin-left:15%'"
+ >
+ <div class="img-box">
+ <video
+ :src="'/httpImage/' + data.videoUrl"
+ controls
+ style="margin-top: 12px;"
+ >鎮ㄧ殑娴忚鍣ㄤ笉鏀寔 video 鏍囩銆�</video>
+ </div>
+ <!-- <div class="merge">
+ <el-button type="primary" @click="mergeVideo">鍚堝苟瑙嗛</el-button>
+ <a name="download" @click="downloadfile">涓嬭浇</a>
+ <a href="/httpImage/192.168.20.112:6081/31,02c86c199cd9b1" download="panlei.mp4">涓嬭浇2</a>
+ </div>-->
+ </div>
+ <div
+ v-if="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''"
+ class="model-card-box-right"
+ :style="data.targetInfo !== null && data.targetInfo[0].picSmUrl !== ''
+ ? 'width: 35%;box-sizing: border-box;'
+ : ''"
+ >
+ <p class="img-box-title">
+ <b>鎶撴媿鍥�</b>
+ </p>
+ <!-- 宸﹀彸涓ゅ紶鐨勪汉鑴稿姣旀ā寮� -->
+ <div class="img-box" v-if="data.baseInfo && data.baseInfo.length >= 1" ref="picSmBox">
+ <div class="card-img-box-compear-left">
+ <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+ </div>
+ <el-carousel
+ @change="changeInitialIndex"
+ :initial-index="initialIndex"
+ :autoplay="false"
+ indicator-position="none"
+ v-if="data.baseInfo[0].targetPicUrl != ''"
+ class="card-img-box-compear-right"
+ :arrow="data.baseInfo.length > 1 ? 'always' : 'never'"
+ >
+ <el-carousel-item v-for="(item, index) in data.baseInfo" :key="index">
+ <!-- <img :src="'/httpImage/'+item.targetPicUrl" /> -->
+ <img-down :url="item.targetPicUrl" :isPreview="false"></img-down>
+ </el-carousel-item>
+ </el-carousel>
+ <div
+ class="img-compareScore"
+ v-if="data.baseInfo[0].targetPicUrl != ''"
+ :style="
+ data.baseInfo[initialIndex].bwType === '1'
+ ? `background: red;`
+ : `background: green;`
+ "
+ >
+ <b>{{ data.baseInfo[initialIndex].compareScore | percentage }}</b>
+ </div>
+ </div>
+ <!-- 娌℃湁姣斿鐨勪汉鑴歌瘑鍒ā寮� -->
+ <div class="img-box" v-if="!data.baseInfo && data.picMaxUrl ">
+ <div class="card-img-box-compear-left" style="width:60%;margin-top:5px">
+ <!-- <img :src="'/httpImage/'+data.targetInfo[0].picSmUrl" /> -->
+ <img-down :url="data.targetInfo[0].picSmUrl" :isPreview="false"></img-down>
+ </div>
+ </div>
+ <div class="baseInfo" v-if="data.baseInfo && data.baseInfo[0].targetPicUrl != ''">
+ <div class="baseInfo_left">
+ <p>
+ <span class="labelInfo">搴曞簱</span>
+ </p>
+ <p>
+ <span class="labelInfo">濮撳悕</span>
+ </p>
+ <p>
+ <span class="labelInfo">鎬у埆</span>
+ </p>
+ <p>
+ <span class="labelInfo">韬唤璇佸彿</span>
+ </p>
+ <p>
+ <span class="labelInfo">鎵嬫満鍙�</span>
+ </p>
+ <p>
+ <span class="labelInfo">浜哄憳绛夌骇</span>
+ </p>
+ </div>
+ <div class="baseInfo_right">
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].tableName"
+ >{{ data.baseInfo[initialIndex].tableName }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].targetName"
+ >{{ data.baseInfo[initialIndex].targetName }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].labels.split('/')[1]"
+ >{{ data.baseInfo[initialIndex].labels.split("/")[1] }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].labels.split('/')[2]"
+ >{{ data.baseInfo[initialIndex].labels.split("/")[2] }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].labels.split('/')[0]"
+ >{{ data.baseInfo[initialIndex].labels.split("/")[0] }}</span>
+ </p>
+ <p class="valueInfo">
+ <span
+ :title="data.baseInfo[initialIndex].monitorLevel"
+ >{{ data.baseInfo[initialIndex].monitorLevel }}</span>
+ </p>
+ </div>
+ </div>
+ </div>
+ </el-tab-pane>
+ </el-tabs>
+ </div>
+</template>
+<script>
+/* eslint-disable */
+import CameraPlayer from "@/components/player";
+import imgDown from "@/components/subComponents/imgDown"
+export default {
+ components: {
+ CameraPlayer,
+ imgDown
+ },
+ props: {
+ height: {
+ type: String,
+ default: "100%"
+ },
+ width: {
+ type: String,
+ default: "100%"
+ },
+ data: ""
+ },
+ filters: {
+ percentage(score) {
+ return score.toFixed(2) + "%"
+ }
+ },
+ mounted() {
+ this.VideoPhotoData.activeName = "pic"
+ },
+ data() {
+ return {
+ initialIndex: 0,
+ };
+ },
+ methods: {
+ changeTabs(activeName, oldActiveName) {
+ console.log(activeName, oldActiveName);
+ },
+ changeInitialIndex(index) {
+ this.initialIndex = index;
+ },
+ downloadfile() {
+ this.filecontent = "this is my file content";
+ let a = document.createElement('a');
+
+ a.href = "data:text/json;charset=utf-8," + this.filecontent;
+ // a.url = "http://192.168.20.112:6154/93,02c5aea4fc614e";
+ a.download = "video.mp4";
+ a.click();
+ }
+ },
+};
+</script>
+<style lang="scss">
+.fontStyleForModel {
+ font-family: PingFangSC-Medium;
+ font-size: 14px;
+ color: #222222;
+ font-weight: 600;
+ letter-spacing: 0.28px;
+}
+.model-card-box {
+ box-sizing: border-box;
+ padding: 5px;
+ .el-tabs {
+ .el-tabs__item {
+ font-size: 16px !important;
+ }
+ }
+ .el-tabs__content {
+ height: calc(100% - 55px);
+ .el-tab-pane {
+ height: 100%;
+ }
+ .model-card-box-left,
+ .model-card-box-right {
+ height: 100%;
+ float: left;
+ .baseInfo {
+ margin-top: 5px;
+ text-align: left;
+ .baseInfo_left {
+ float: left;
+ width: 30%;
+ text-align: left;
+ font-family: PingFangSC-Regular;
+ font-size: 12px;
+ color: #999999;
+ letter-spacing: 0.28px;
+ }
+ .baseInfo_right {
+ float: left;
+ width: 70%;
+ text-align: left;
+ font-family: PingFangSC-Regular;
+ font-size: 12px;
+ color: #101010;
+ letter-spacing: 0.28px;
+ line-height: 20px;
+ .valueInfo {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ max-width: 130px;
+ }
+ }
+ p {
+ line-height: 20px;
+ }
+ }
+ }
+ .model-card-box-left {
+ width: 60%;
+ .img-box {
+ .el-carousel__arrow {
+ bottom: inherit !important;
+ top: 50% !important;
+ }
+ .el-carousel__arrow--right {
+ right: 10px !important;
+ }
+ .el-carousel__arrow--left {
+ left: 10px !important;
+ }
+ .img-box-title {
+ text-align: left;
+ }
+ height: calc(100% - 100px);
+ .el-carousel {
+ width: 100%;
+ height: 100%;
+ float: left;
+ }
+ img {
+ float: left;
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ }
+ .describe {
+ width: 100%;
+ height: 50px;
+ float: left;
+ margin-left: 15%;
+ margin-top: 5px;
+ p {
+ b {
+ //color: #e43933;
+ }
+ width: 40%;
+ text-align: left;
+ float: left;
+ margin: 4px 0px;
+ }
+ }
+ .describeBigImage {
+ width: 100%;
+ height: 50px;
+ float: left;
+ margin-top: 5px;
+ p {
+ b {
+ //color: #e43933;
+ }
+ width: 50%;
+ text-align: left;
+ float: left;
+ margin: 4px 0px;
+ }
+ }
+ }
+ .merge {
+ margin-top: 30px;
+ float: left;
+ }
+ }
+ .model-card-box-right {
+ padding-left: 5px;
+ box-sizing: border-box;
+ width: 40%;
+ overflow: auto;
+ height: 100%;
+ .img-box-title {
+ text-align: left;
+ margin: 5px;
+ }
+ .img-box {
+ height: 32%;
+ width: 100%;
+ position: relative;
+ .card-img-box-compear-left {
+ float: left;
+ width: 50%;
+ height: 100%;
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ //border: 1px solid rgb(92, 91, 91);
+ padding: 0px 4px;
+ box-sizing: border-box;
+ border-radius: 5px;
+ }
+ }
+ .card-img-box-compear-right {
+ float: right;
+ width: 50%;
+ height: 100%;
+ .el-carousel__container {
+ height: 100% !important;
+ .el-carousel__arrow {
+ top: 50% !important;
+ }
+ .el-carousel__arrow {
+ height: 20px;
+ width: 20px;
+ }
+ .el-carousel__arrow--right {
+ right: 10px !important;
+ }
+ .el-carousel__arrow--left {
+ left: 10px !important;
+ }
+ }
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ //border: 1px solid rgb(92, 91, 91);
+ padding: 0px 4px;
+ box-sizing: border-box;
+ border-left: none;
+ border-radius: 5px;
+ }
+ }
+ .img-compareScore {
+ bottom: 0px;
+ width: 60px;
+ height: 20px;
+ line-height: 20px;
+ background-color: #e43933;
+ position: absolute;
+ left: calc(50% - 30px);
+ border-top-right-radius: 5px;
+ border-top-left-radius: 5px;
+ color: #ebeef5;
+ font-weight: 700;
+ z-index: 2;
+ }
+ .imgs {
+ width: 50%;
+ height: 50%;
+ float: left;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ overflow: hidden;
+ padding-right: 5px;
+ box-sizing: border-box;
+ background-color: #ebeef5;
+ img {
+ width: 100%;
+ }
+ }
+ }
+ }
+ }
+}
+</style>
diff --git a/src/components/subComponents/MultiRangeSlider.vue b/src/components/subComponents/MultiRangeSlider.vue
new file mode 100644
index 0000000..5b8c0ac
--- /dev/null
+++ b/src/components/subComponents/MultiRangeSlider.vue
@@ -0,0 +1,761 @@
+<template>
+ <div class="timeRangeSliderBox">
+ <canvas :id="mainId" :ref="mainId" width="700px" height="260px">鎶辨瓑,鎮ㄧ殑娴忚鍣ㄤ笉鏀寔canvas!璇锋洿鎹㈡祻瑙堝櫒</canvas>
+ <canvas
+ :id="`${mainId}Dummy`"
+ :ref="`${mainId}Dummy`"
+ width="700px"
+ height="260px"
+ @dblclick="handlerClick"
+ @mouseout="mouseout($event)"
+ @mousedown="mouseDown($event)"
+ @mousemove="mousemove($event)"
+ @mouseup="mouseup($event)"
+ >鎶辨瓑,鎮ㄧ殑娴忚鍣ㄤ笉鏀寔canvas!璇锋洿鎹㈡祻瑙堝櫒</canvas>
+ <div class="popup-box" :style="`top:${popPos.y + 10}px;left:${popPos.x - 70}px`" v-if="isPopup">
+ <div>
+ <b>寮�濮嬫椂闂�:</b>
+ <input
+ v-model="changeTime.startHour"
+ :min="0"
+ :max="changeTime.endHour"
+ type="number"
+ placeholder="鏃�"
+ />
+ <b>:</b>
+ <input v-model="changeTime.startMin" type="number" placeholder="鍒�" />
+ </div>
+ <div>
+ <b>缁撴潫鏃堕棿:</b>
+ <input
+ v-model="changeTime.endHour"
+ :min="changeTime.startHour"
+ :max="24"
+ type="number"
+ placeholder="鏃�"
+ />
+ <b>:</b>
+ <input v-model="changeTime.endMin" type="number" placeholder="鍒�" />
+ </div>
+ <div style="margin-top:5px;">
+ <el-button @click="deleteRange">鍒犻櫎</el-button>
+ <el-button @click="cancalPop">鍙栨秷</el-button>
+ <el-button @click="timeAck">纭畾</el-button>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ mounted() {
+
+ this.initMain();
+ this.initMainDummy();
+ },
+ data() {
+ return {
+ x: "",
+ y: "",
+ isMouseDown: false,
+ isCreate: false,
+ isResizeLeft: false,
+ isResizeRight: false,
+ actRange: "",
+ actGrid: "",
+ rangeArr: [],
+ gridArr: [],
+ currentPointX: "",
+ actRangeIndex: "",
+ noLimit: 0,
+ isPopup: false,
+ popPos: {
+ x: "",
+ y: ""
+ },
+ changeTime: {
+ startHour: "",
+ startMin: "",
+ endHour: "",
+ endMin: ""
+ },
+ rangeArrBackup: "",
+ styleClass: {
+ weekTextColor: "",
+ minutePerColor: "#cdcdcd",
+ minutePerTextColor: "#808080"
+ }
+ };
+ },
+ props: {
+ timeData: {
+ default: () => { },
+ type: Array
+ },
+ mainId: {
+ type: String,
+ default: ""
+ },
+ itemId: {
+ type: String,
+ default: ""
+ },
+ itemName: {
+ type: String,
+ default: ""
+ },
+ edit: {
+ type: Boolean,
+ default: false
+ }
+ },
+ watch: {
+ changeTime: {
+ handler(newVal, oldVal) {
+ if (newVal.startHour >= 24) {
+ newVal.startHour = 24;
+ newVal.startMin = 0;
+ }
+
+ if (newVal.endHour >= 24) {
+ newVal.endHour = 24;
+ newVal.endMin = 0;
+ }
+
+ if (newVal.startHour < 0) {
+ newVal.startHour = 0;
+ }
+
+ if (newVal.endHour < 0) {
+ newVal.endHour = newVal.startHour;
+ }
+
+ if (newVal.startMin > 60) {
+ newVal.startMin = 0
+ }
+ if (newVal.startMin < 0) {
+ newVal.startMin = 60
+ }
+ if (newVal.endMin > 60) {
+ newVal.endMin = 0
+ }
+ if (newVal.endMin < 0) {
+ newVal.endMin = 0
+ }
+
+ if (parseInt(newVal.startHour) == parseInt(newVal.endHour) && parseInt(newVal.startMin) > parseInt(newVal.endMin)) {
+ newVal.startMin = 0
+ }
+ },
+ deep: true
+ }
+ },
+ methods: {
+ timeAck() {
+ let rangeInfo = this.actRange.rangeInfo;
+ let perH = 600 / 24;
+ let perM = perH / 60;
+
+ let tempRangeInfo = this.rangeArr[rangeInfo.ownedIndex].rangeInfo;
+ tempRangeInfo.maxX = this.changeTime.endHour * perH + this.changeTime.endMin * perM + 50.5;
+ tempRangeInfo.minX = this.changeTime.startHour * perH + this.changeTime.startMin * perM + 50.5;
+ tempRangeInfo.width = tempRangeInfo.maxX - tempRangeInfo.minX;
+ for (let i = 0; i < this.gridArr.length; i++) {
+ let num = 0;
+ for (let j = 0; j < this.rangeArr.length; j++) {
+ if (this.gridArr[i].posIndex === this.rangeArr[j].rangeInfo.posIndex) {
+ this.gridArr[i].rangeList.splice(num, 1, this.rangeArr[j].rangeInfo);
+ num++;
+ }
+ }
+ }
+ this.cancalPop();
+ this.redraw(false);
+ this.export();
+ },
+ deleteRange() {
+ this.rangeArr.splice(this.actRangeIndex, 1);
+ for (let i = 0; i < this.rangeArr.length; i++) {
+ this.rangeArr[i].rangeInfo.ownedIndex = i;
+ }
+ for (let i = 0; i < this.gridArr.length; i++) {
+ let num = 0;
+ for (let j = 0; j < this.rangeArr.length; j++) {
+ if (
+ this.gridArr[i].posIndex === this.rangeArr[j].rangeInfo.posIndex
+ ) {
+ this.gridArr[i].rangeList.splice(
+ num,
+ 1,
+ this.rangeArr[j].rangeInfo
+ );
+ num++;
+ }
+ }
+ }
+ this.cancalPop();
+ this.redraw(false);
+ this.export();
+ },
+ getPopTime() {
+ let rangeInfo = this.actRange.rangeInfo;
+ if (!rangeInfo) {
+ return false;
+ }
+ let hourStart = parseInt((rangeInfo.minX - 50.5) / (600 / 24));
+ let minutetStart = Math.round(
+ ((rangeInfo.minX - 50.5) % (600 / 24)) / (600 / 24 / 60)
+ );
+ let hourEnd = parseInt((rangeInfo.maxX - 50.5) / (600 / 24));
+ let minuteEnd = Math.round(
+ ((rangeInfo.maxX - 50.5) % (600 / 24)) / (600 / 24 / 60)
+ );
+ minuteEnd = minuteEnd < 10 ? "0" + minuteEnd : minuteEnd;
+ this.changeTime.startHour = hourStart < 10 ? "0" + hourStart : hourStart;
+ this.changeTime.startMin = minutetStart === 60 ? "00" : minutetStart;
+ this.changeTime.endHour = hourEnd < 10 ? "0" + hourEnd : hourEnd;
+ this.changeTime.endMin = minuteEnd === 60 ? "00" : minuteEnd;
+ return true;
+ },
+ cancalPop() {
+ this.isPopup = false;
+ this.actRange = "";
+ this.actGrid = "";
+ this.actRangeIndex = "";
+ },
+ handlerClick() {
+ if (this.getPopTime()) {
+ this.isPopup = true;
+ this.popPos.x = Number(JSON.stringify(this.x));
+ this.popPos.y = Number(JSON.stringify(this.y >= 180 ? 170 : this.y));
+ }
+ },
+ mouseout(e) {
+ this.isMouseDown = false;
+ this.isCreate = false;
+ this.noLimit = 0;
+ },
+ mouseup(e) {
+ this.isMouseDown = false;
+ this.isCreate = false;
+ // this.actRange = ''
+ // this.actGrid = ''
+ // this.actRangeIndex = ''
+ this.noLimit = 0;
+ if (this.rangeArrBackup !== JSON.stringify(this.rangeArr)) {
+ this.rangeArrBackup = JSON.stringify(this.rangeArr);
+ this.export();
+ }
+
+ this.redraw(false);
+ },
+ mouseDown(e) {
+ this.isPopup = false;
+ this.isMouseDown = true;
+ this.currentPointX = e.offsetX;
+ this.noLimit++;
+ for (let i = 0; i < this.rangeArr.length; i++) {
+ let rangeItem = this.rangeArr[i].rangeInfo;
+ if (
+ this.x > rangeItem.minX &&
+ this.x < rangeItem.maxX &&
+ this.y > rangeItem.minY &&
+ this.y < rangeItem.maxY
+ ) {
+ this.actRange = this.rangeArr[i];
+ this.actRangeIndex = i;
+ return;
+ }
+ }
+ for (let i = 0; i < this.gridArr.length; i++) {
+ if (
+ this.x > this.gridArr[i].minX &&
+ this.x < this.gridArr[i].maxX &&
+ this.y > this.gridArr[i].minY &&
+ this.y < this.gridArr[i].maxY
+ ) {
+ this.actGrid = this.gridArr[i];
+ return;
+ }
+ }
+ },
+ mousemove(e) {
+ if (!this.edit) {
+ return;
+ }
+
+ if (this.isPopup) {
+ return;
+ }
+ // let canvas = document.getElementById(`${this.mainId}Dummy`);
+ let canvas = this.$refs[`${this.mainId}Dummy`];
+ let ctx = canvas.getContext("2d");
+ this.x = e.offsetX;
+ this.y = e.offsetY;
+ if (
+ this.actRange &&
+ this.isMouseDown &&
+ !this.isCreate &&
+ !this.isResizeLeft &&
+ !this.isResizeRight
+ ) {
+ // console.log("move", this.actRange);
+ let diff = e.offsetX - this.currentPointX;
+ let tempMinxX = this.actRange.rangeInfo.minX + diff;
+ let limit = this.limit(this.actRange);
+ if (
+ tempMinxX <= limit.limitLeft ||
+ tempMinxX + this.actRange.rangeInfo.width >= limit.limitRight
+ ) {
+ return;
+ }
+ this.actRange.rangeInfo.minX = tempMinxX;
+ this.actRange.rangeInfo.maxX = tempMinxX + this.actRange.rangeInfo.width;
+ this.currentPointX = e.offsetX;
+ let tempRangeList = this.gridArr[this.actRange.rangeInfo.posIndex].rangeList;
+ this.redraw();
+ // console.log("move-ed");
+ } else if (
+ this.actGrid &&
+ this.isMouseDown &&
+ !this.isResizeLeft &&
+ !this.isResizeRight
+ ) {
+ // console.log("create");
+ if (this.isCreate) {
+ let limit = this.limit(this.actRange);
+ if (
+ this.actRange.rangeInfo.minX <= limit.limitLeft ||
+ this.actRange.rangeInfo.minX + this.actRange.rangeInfo.width >=
+ limit.limitRight
+ ) {
+ return;
+ }
+ let tempX
+ if (this.x < 50) {
+ tempX = 50
+ } else if (this.x > 650) {
+ tempX = 650
+ } else {
+ tempX = this.x
+ }
+ let temp = tempX - this.currentPointX > 0 ? true : false;
+ let newWith = 0;
+ if (temp) {
+ newWith = tempX - this.currentPointX;
+ this.actRange.rangeInfo.maxX = tempX;
+ } else {
+ newWith = this.currentPointX - tempX;
+ this.actRange.rangeInfo.maxX = this.currentPointX;
+ this.actRange.rangeInfo.minX = tempX;
+ }
+ this.actRange.rangeInfo.width = newWith;
+ this.redraw();
+ return;
+ }
+ let tempRangeList = this.actGrid.rangeList;
+ if (tempRangeList) {
+ let rangeObj = {
+ end: "",
+ start: "",
+ rangeInfo: {
+ minX: this.currentPointX,
+ minY: this.actGrid.minY,
+ maxX: this.currentPointX + 10,
+ maxY: this.actGrid.maxY,
+ width: 10,
+ height: 14,
+ posIndex: this.actGrid.posIndex,
+ ownedIndex: 0
+ }
+ };
+ let actRangeIndex = 0;
+ for (let i = 0; i < tempRangeList.length; i++) {
+ if (this.currentPointX > tempRangeList[i].minX) {
+ actRangeIndex++;
+ }
+ }
+ this.actRangeIndex = actRangeIndex;
+ this.rangeArr.splice(this.actRangeIndex, 0, rangeObj);
+ for (let i = 0; i < this.rangeArr.length; i++) {
+ this.rangeArr[i].rangeInfo.ownedIndex = i;
+ }
+ for (let i = 0; i < this.gridArr.length; i++) {
+ let num = 0;
+ for (let j = 0; j < this.rangeArr.length; j++) {
+ if (
+ this.gridArr[i].posIndex === this.rangeArr[j].rangeInfo.posIndex
+ ) {
+ this.gridArr[i].rangeList.splice(
+ num,
+ 1,
+ this.rangeArr[j].rangeInfo
+ );
+ num++;
+ }
+ }
+ }
+ this.actGrid.rangeList = this.gridArr[
+ this.actGrid.posIndex
+ ].rangeList;
+ this.actRange = this.rangeArr[this.actRangeIndex];
+ this.isCreate = true;
+ }
+ } else if (
+ this.isMouseDown &&
+ (this.isResizeLeft || this.isResizeRight) &&
+ this.actRange !== "" &&
+ this.actRangeIndex !== ""
+ ) {
+ // console.log("resize");
+ let limit = this.limit(this.actRange);
+ if (
+ (this.actRange.rangeInfo.minX <= limit.limitLeft ||
+ this.actRange.rangeInfo.minX + this.actRange.rangeInfo.width >=
+ limit.limitRight) &&
+ this.noLimit > 5
+ ) {
+ this.isResizeRight = false;
+ this.isResizeLeft = false;
+ this.actRange = "";
+ this.actRangeIndex = "";
+ return;
+ }
+ if (this.isResizeLeft) {
+ if (
+ this.x >
+ this.actRange.rangeInfo.width / 2 + this.actRange.rangeInfo.minX - 5
+ ) {
+ return;
+ }
+ this.actRange.rangeInfo.minX = this.x < 50 ? 50 : this.x;
+ this.actRange.rangeInfo.width = this.actRange.rangeInfo.maxX - this.x;
+ this.noLimit++;
+ this.redraw();
+ return;
+ } else if (this.isResizeRight) {
+ if (
+ this.x <
+ this.actRange.rangeInfo.width / 2 + this.actRange.rangeInfo.minX + 5
+ ) {
+ return;
+ }
+ this.actRange.rangeInfo.maxX = this.x > 650 ? 650 : this.x;
+ this.actRange.rangeInfo.width = this.actRange.rangeInfo.maxX - this.actRange.rangeInfo.minX;
+ this.noLimit++;
+ this.redraw();
+ return;
+ }
+ } else {
+ for (let i = 0; i < this.rangeArr.length; i++) {
+ let rangeItem = this.rangeArr[i].rangeInfo;
+ if (
+ this.x > rangeItem.minX &&
+ this.x < rangeItem.minX + 6 &&
+ this.y > rangeItem.minY &&
+ this.y < rangeItem.maxY
+ ) {
+ this.isResizeLeft = true;
+ document.documentElement.style.cursor = "col-resize";
+ this.actRange = this.rangeArr[i];
+ this.actRangeIndex = i;
+ return;
+ } else if (
+ this.x > rangeItem.maxX - 6 &&
+ this.x < rangeItem.maxX &&
+ this.y > rangeItem.minY &&
+ this.y < rangeItem.maxY
+ ) {
+ this.isResizeRight = true;
+ document.documentElement.style.cursor = "col-resize";
+ this.actRange = this.rangeArr[i];
+ this.actRangeIndex = i;
+ return;
+ } else {
+ this.isResizeRight = false;
+ this.isResizeLeft = false;
+ this.actRange = "";
+ this.actRangeIndex = "";
+ document.documentElement.style.cursor = "default";
+ }
+ }
+ }
+ },
+ limit(rangeObj) {
+ let before = this.rangeArr[this.actRangeIndex - 1];
+ let behind = this.rangeArr[this.actRangeIndex + 1];
+ let obj = {
+ limitLeft: 50,
+ limitRight: 650
+ };
+ if (before === undefined && behind === undefined) {
+ return obj;
+ }
+ if (before === undefined) {
+ obj.limitLeft = 50;
+ obj.limitRight =
+ behind.rangeInfo.posIndex === rangeObj.rangeInfo.posIndex
+ ? behind.rangeInfo.minX
+ : 650;
+ return obj;
+ } else if (behind === undefined) {
+ obj.limitLeft =
+ before.rangeInfo.posIndex === rangeObj.rangeInfo.posIndex
+ ? before.rangeInfo.maxX
+ : 50;
+ obj.limitRight = 650;
+ return obj;
+ }
+ if (
+ before.rangeInfo.posIndex === rangeObj.rangeInfo.posIndex &&
+ behind.rangeInfo.posIndex === rangeObj.rangeInfo.posIndex
+ ) {
+ obj.limitLeft = before.rangeInfo.maxX;
+ obj.limitRight = behind.rangeInfo.minX;
+ } else if (
+ before.rangeInfo.posIndex !== rangeObj.rangeInfo.posIndex &&
+ behind.rangeInfo.posIndex === rangeObj.rangeInfo.posIndex
+ ) {
+ obj.limitLeft = 50;
+ obj.limitRight = behind.rangeInfo.minX;
+ } else if (
+ before.rangeInfo.posIndex === rangeObj.rangeInfo.posIndex &&
+ behind.rangeInfo.posIndex !== rangeObj.rangeInfo.posIndex
+ ) {
+ obj.limitLeft = before.rangeInfo.maxX;
+ obj.limitRight = 650;
+ } else {
+ obj.limitLeft = 50;
+ obj.limitRight = 650;
+ }
+ return obj;
+ },
+ weekString(n) {
+ let base = "鏄熸湡";
+ switch (n) {
+ case 1:
+ return base + "涓�";
+ case 2:
+ return base + "浜�";
+ case 3:
+ return base + "涓�";
+ case 4:
+ return base + "鍥�";
+ case 5:
+ return base + "浜�";
+ case 6:
+ return base + "鍏�";
+ case 7:
+ return base + "鏃�";
+ }
+ },
+ initMain() {
+ // let canvas = document.getElementById(`${this.mainId}`);
+ let canvas = this.$refs[`${this.mainId}`];
+ let ctx = canvas.getContext("2d");
+ ctx.font = "12px Arial";
+ let height = 260;
+ let width = canvas.offsetWidth;
+ let per = height / 7;
+ for (let i = 0; i < 7; i++) {
+ // let weekText = `鏄熸湡${this.timeData[i].day}:`;
+ let weekText = this.weekString(this.timeData[i].day);
+ let mid = per * i + per / 2 + 6.5;
+ ctx.strokeStyle = this.styleClass.minutePerColor;
+ ctx.fillText(weekText, 10, mid);
+ let startX = 50.5;
+ let startY = mid - 10;
+ ctx.save();
+ ctx.strokeStyle = "#DCDFE6";
+ ctx.fillStyle = "#DCE9FF";
+ ctx.fillRect(startX, startY, 600, 14);
+ ctx.strokeRect(startX, startY, 600, 14);
+ ctx.restore();
+ let tempGrid = {
+ minX: startX,
+ minY: startY,
+ maxX: startX + 600,
+ maxY: startY + 14,
+ width: 600,
+ height: 14,
+ posIndex: i,
+ rangeList: []
+ };
+ this.gridArr.push(tempGrid);
+ let timePer = 600 / 24;
+ for (let j = 0; j < 25; j++) {
+ let x = startX + timePer * j;
+ let y = startY;
+ let delVar = j % 2 === 0 ? 6.5 : 3.5;
+ ctx.save();
+ ctx.moveTo(x, y - delVar);
+ ctx.lineTo(x, y);
+ ctx.stroke();
+ ctx.font = "10px Arial";
+ ctx.fillStyle = this.styleClass.minutePerTextColor;
+ ctx.fillText(j, x - (j > 9 ? 4.5 : 2.5), y - 8.5);
+ ctx.restore();
+ }
+ }
+ },
+ initMainDummy() {
+ let canvas = document.getElementById(`${this.mainId}Dummy`);
+ let ctx = canvas.getContext("2d");
+ let height = 260;
+ let startX = 50.5;
+ let per = height / 7;
+ let hourPer = 600 / 24;
+ let minutePer = hourPer / 60;
+ for (let i = 0; i < this.timeData.length; i++) {
+ let mid = per * i + per / 2 + 6.5;
+ let startY = mid - 10;
+ let rang = this.timeData[i].time_range;
+ for (let j = 0; j < rang.length; j++) {
+ let start = rang[j].start.split(":");
+ let end = rang[j].end.split(":");
+ let startRange =
+ hourPer * Number(start[0]) + minutePer * Number(start[1]);
+ let endRange = hourPer * Number(end[0]) + minutePer * Number(end[1]);
+ let diffRange = Math.abs(endRange - startRange);
+ let rectStartX =
+ (startRange > endRange ? endRange : startRange) + 50.5;
+ ctx.fillStyle = "#6B9EFF";
+ ctx.fillRect(rectStartX, startY, diffRange, 14);
+ let rangeInfo = {
+ minX: rectStartX,
+ minY: startY,
+ maxX: rectStartX + diffRange,
+ maxY: startY + 14,
+ width: diffRange,
+ height: 14,
+ posIndex: i,
+ ownedIndex: this.rangeArr.length
+ };
+ rang[j].rangeInfo = rangeInfo;
+ this.gridArr[i].rangeList.push(rangeInfo);
+ this.rangeArr.push(rang[j]);
+ }
+ }
+
+ this.rangeArrBackup = JSON.stringify(this.rangeArr);
+ },
+ redraw(onlyDraw = true) {
+ let canvas = document.getElementById(`${this.mainId}Dummy`);
+ let ctx = canvas.getContext("2d");
+ ctx.clearRect(0, 0, 700, 260);
+ if (onlyDraw) {
+ let rangeInfo = this.actRange.rangeInfo;
+ let hourStart = parseInt((rangeInfo.minX - 50) / (600 / 24));
+ let minutetStart = Math.round(
+ ((rangeInfo.minX - 50) % (600 / 24)) / (600 / 24 / 60)
+ );
+ let hourEnd = parseInt((rangeInfo.maxX - 50) / (600 / 24));
+ let minuteEnd = Math.round(
+ ((rangeInfo.maxX - 50) % (600 / 24)) / (600 / 24 / 60)
+ );
+ minuteEnd = minuteEnd < 10 ? "0" + minuteEnd : minuteEnd;
+ let textStart = `${hourStart < 10 ? "0" + hourStart : hourStart}:${
+ minutetStart === 60 ? "00" : minutetStart
+ }`;
+ let textEnd = `${hourEnd < 10 ? "0" + hourEnd : hourEnd}:${
+ minuteEnd === 60 ? "00" : minuteEnd
+ }`;
+ let startPointX = rangeInfo.minX - 14;
+ let startPointY = rangeInfo.maxY + 10;
+ let endPointX = rangeInfo.maxX - 13;
+ let endPointY = rangeInfo.maxY + 10;
+ ctx.fillStyle = "#303133";
+ ctx.fillText(textStart, startPointX, startPointY);
+ ctx.fillText(textEnd, endPointX, endPointY);
+ }
+ for (let i = 0; i < this.rangeArr.length; i++) {
+ ctx.fillStyle = "#6B9EFF";
+ ctx.fillRect(
+ this.rangeArr[i].rangeInfo.minX,
+ this.rangeArr[i].rangeInfo.minY,
+ this.rangeArr[i].rangeInfo.width,
+ this.rangeArr[i].rangeInfo.height
+ );
+ }
+ },
+ export() {
+ let timeRule = [];
+ for (let i = 0; i < 7; i++) {
+ timeRule.push({
+ day: i + 1,
+ time_range: (() => {
+ let range = [];
+ this.rangeArr.forEach(item => {
+ if (item.rangeInfo.posIndex === i) {
+ let rangeInfo = item.rangeInfo;
+ let hourStart = parseInt((rangeInfo.minX - 50.5) / (600 / 24));
+ let minutetStart = Math.round(
+ ((rangeInfo.minX - 50.5) % (600 / 24)) / (600 / 24 / 60)
+ );
+ let hourEnd = parseInt((rangeInfo.maxX - 50.5) / (600 / 24));
+ let minuteEnd = Math.round(
+ ((rangeInfo.maxX - 50.5) % (600 / 24)) / (600 / 24 / 60)
+ );
+ hourStart = hourStart < 10 ? "0" + hourStart : hourStart;
+ minutetStart =
+ minutetStart < 10 ? "0" + minutetStart : minutetStart;
+ hourEnd = hourEnd < 10 ? "0" + hourEnd : hourEnd;
+ minuteEnd = minuteEnd < 10 ? "0" + minuteEnd : minuteEnd;
+ range.push({
+ start: hourStart + ":" + minutetStart,
+ end: hourEnd + ":" + minuteEnd
+ });
+ }
+ });
+ return range;
+ })()
+ });
+ }
+
+ let obj = {
+ id: this.itemId,
+ name: this.itemName,
+ time_rule: timeRule
+ };
+ this.$emit("range-update", obj);
+ }
+ }
+};
+</script>
+
+<style lang="scss">
+.timeRangeSliderBox {
+ width: 700px;
+ height: 260px;
+ text-align: left;
+ margin: 10px auto;
+ position: relative;
+ canvas {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 700px;
+ height: 260px;
+ }
+ .popup-box {
+ width: 160px;
+ height: 80px;
+ background-color: rgba(0, 0, 0, 0.6);
+ border-radius: 5px;
+ position: relative;
+ padding: 5px;
+ box-sizing: border-box;
+ color: #fff;
+ input {
+ width: 33px;
+ }
+ div {
+ margin: 3px auto;
+ text-align: center;
+ }
+ button {
+ padding: 3px;
+ }
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/ParticleNetwork.vue b/src/components/subComponents/ParticleNetwork.vue
new file mode 100644
index 0000000..1989781
--- /dev/null
+++ b/src/components/subComponents/ParticleNetwork.vue
@@ -0,0 +1,351 @@
+<template>
+ <div class="particle-network-animation" :style="`height:${height}px;width:${width}px`">
+ <div style="display:none">
+ <img ref="conf0" src="../../assets/img/login/0.png" />
+ <img ref="conf1" src="../../assets/img/login/1.png" />
+ <img ref="conf2" src="../../assets/img/login/2.png" />
+ <img ref="conf3" src="../../assets/img/login/3.png" />
+ <img ref="conf4" src="../../assets/img/login/4.png" />
+ <img ref="conf5" src="../../assets/img/login/5.png" />
+ <img ref="conf6" src="../../assets/img/login/6.png" />
+ <img ref="conf7" src="../../assets/img/login/7.png" />
+ <img ref="conf8" src="../../assets/img/login/8.png" />
+ <img ref="conf9" src="../../assets/img/login/9.png" />
+ <img ref="conf10" src="../../assets/img/login/10.png" />
+ <img ref="conf11" src="../../assets/img/login/11.png" />
+ <img ref="conf12" src="../../assets/img/login/12.png" />
+ <img ref="conf13" src="../../assets/img/login/13.png" />
+ <img ref="conf14" src="../../assets/img/login/14.png" />
+ <img ref="conf15" src="../../assets/img/login/15.png" />
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "particleNetwork",
+ data() {
+ return {
+ imgNumber: 0,
+ destoryed: false
+ };
+ },
+ props: {
+ height: {
+ type: Number,
+ default: 800
+ },
+ width: {
+ type: Number,
+ default: 1000
+ }
+ },
+ mounted() {
+ this.createCavas();
+ },
+ beforeDestroy() {
+ this.destoryed = true
+ },
+ methods: {
+ createCavas() {
+ let that = this;
+ var ParticleNetworkAnimation, PNA;
+ ParticleNetworkAnimation = PNA = function () { };
+
+ PNA.prototype.init = function (element) {
+ // this.$el = $(element);
+
+ this.container = element;
+ this.canvas = document.createElement("canvas");
+ this.sizeCanvas();
+ this.container.appendChild(this.canvas);
+ this.ctx = this.canvas.getContext("2d");
+ this.particleNetwork = new ParticleNetwork(this);
+
+ return this;
+ };
+
+ PNA.prototype.sizeCanvas = function () {
+ this.canvas.width = this.container.offsetWidth;
+ this.canvas.height = this.container.offsetHeight;
+ };
+
+ var Particle = function (parent, x, y) {
+ this.network = parent;
+ this.imgNumber = that.imgNumber++;
+ this.canvas = parent.canvas;
+ this.ctx = parent.ctx;
+ this.particleColor = returnRandomArrayitem(
+ this.network.options.particleColors
+ );
+ // 鎺у埗澶у皬
+ this.radius = getLimitedRandom(10, 30);
+ this.opacity = 0;
+ // this.x = x || Math.random() * this.canvas.width;
+ // this.y = y || Math.random() * this.canvas.height;
+
+ // 鎺у埗鍒濆鍧愭爣锛屼笉瑕佽秴鍑鸿寖鍥�
+ this.x = x || getLimitedRandom(50, this.canvas.width - 50);
+ this.y = y || getLimitedRandom(50, this.canvas.height - 50);
+
+ this.velocity = {
+ x: (Math.random() - 0.5) * parent.options.velocity,
+ y: (Math.random() - 0.5) * parent.options.velocity
+ };
+ };
+
+ Particle.prototype.update = function () {
+ if (this.opacity < 0.8) {
+ this.opacity += 0.01;
+ } else {
+ this.opacity = 0.8;
+ }
+ // 绉诲姩鍒拌竟缂樻椂鍙嶅悜
+ if (this.x > this.canvas.width - 50 || this.x < 50) {
+ this.velocity.x = -this.velocity.x;
+ }
+ if (this.y > this.canvas.height - 50 || this.y < 50) {
+ this.velocity.y = -this.velocity.y;
+ }
+
+ // 鏇存柊鍧愭爣
+ this.x += this.velocity.x;
+ this.y += this.velocity.y;
+ };
+
+ Particle.prototype.draw = function () {
+ // Draw particle
+ if (that.destoryed) {
+ return;
+ }
+ this.ctx.beginPath();
+ this.ctx.fillStyle = this.particleColor;
+ this.ctx.globalAlpha = this.opacity;
+ this.ctx.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
+ this.ctx.fill();
+ var prop = this.radius;
+ // let imgOdr = parseInt(Math.random() * 16, 10);
+ var img = that.$refs["conf" + this.imgNumber];
+ // img.src = "../../assets/img/login/" + imgOdr + ".png";
+ this.ctx.drawImage(
+ img,
+ this.x - this.radius * 0.8,
+ this.y - this.radius * 0.8,
+ this.radius * 1.6,
+ this.radius * 1.6
+ );
+ };
+
+ var ParticleNetwork = function (parent) {
+ this.options = {
+ velocity: 1, // the higher the faster
+ density: 1500, // the lower the denser
+ netLineDistance: 300,
+ netLineColor: "#477bec",
+ particleColors: ["#7E8BFA"] // ['#6D4E5C', '#aaa', '#FFC458' ]
+ };
+ this.canvas = parent.canvas;
+ this.ctx = parent.ctx;
+
+ this.init();
+ };
+
+ ParticleNetwork.prototype.init = function () {
+ // Create particle objects
+ this.createParticles(true);
+
+ // Update canvas
+ this.animationFrame = requestAnimationFrame(this.update.bind(this));
+ };
+
+ ParticleNetwork.prototype.createParticles = function (isInitial) {
+ // Initialise / reset particles
+ var me = this;
+ this.particles = [];
+ // var quantity = this.canvas.width * this.canvas.height / this.options.density;
+ var quantity = 17;
+
+ if (isInitial) {
+ var counter = 0;
+ clearInterval(this.createIntervalId);
+ this.createIntervalId = setInterval(
+ function () {
+ if (counter < quantity - 1) {
+ // Create particle object
+ this.particles.push(new Particle(this));
+ } else {
+ clearInterval(me.createIntervalId);
+ }
+ counter++;
+ }.bind(this),
+ 250
+ );
+ } else {
+ // Create particle objects
+ for (var i = 0; i < quantity; i++) {
+ this.particles.push(new Particle(this));
+ }
+ }
+ };
+
+ ParticleNetwork.prototype.destory = function (isInitial) {
+ clearInterval(this.createIntervalId);
+ };
+ ParticleNetwork.prototype.update = function () {
+ if (this.canvas) {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+ this.ctx.globalAlpha = 1;
+
+ // Draw connections
+ for (var i = 0; i < this.particles.length; i++) {
+ for (var j = this.particles.length - 1; j > i; j--) {
+ var distance,
+ p1 = this.particles[i],
+ p2 = this.particles[j];
+
+ // check very simply if the two points are even a candidate for further measurements
+ distance = Math.min(Math.abs(p1.x - p2.x), Math.abs(p1.y - p2.y));
+ if (distance > this.options.netLineDistance) {
+ continue;
+ }
+
+ // the two points seem close enough, now let's measure precisely
+ distance = Math.sqrt(
+ Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)
+ );
+ if (distance > this.options.netLineDistance) {
+ continue;
+ }
+
+ this.ctx.beginPath();
+ this.ctx.strokeStyle = this.options.netLineColor;
+ this.ctx.globalAlpha =
+ ((this.options.netLineDistance - distance) /
+ this.options.netLineDistance) *
+ p1.opacity *
+ p2.opacity;
+ this.ctx.lineWidth = 1.7;
+ this.ctx.moveTo(p1.x, p1.y);
+ this.ctx.lineTo(p2.x, p2.y);
+ this.ctx.stroke();
+ }
+ }
+
+ // Draw particles
+ for (var i = 0; i < this.particles.length; i++) {
+ this.particles[i].update();
+ this.particles[i].draw();
+ }
+
+ if (this.options.velocity !== 0) {
+ this.animationFrame = requestAnimationFrame(this.update.bind(this));
+ }
+ } else {
+ cancelAnimationFrame(this.animationFrame);
+ }
+ };
+
+ var getLimitedRandom = function (min, max, roundToInteger) {
+ var number = Math.random() * (max - min) + min;
+ if (roundToInteger) {
+ number = Math.round(number);
+ }
+ return number;
+ };
+
+ var returnRandomArrayitem = function (array) {
+ return array[Math.floor(Math.random() * array.length)];
+ };
+
+ var elm = document.getElementsByClassName(
+ "particle-network-animation"
+ )[0];
+
+ this.pna = new ParticleNetworkAnimation();
+ this.pna.init(elm);
+ }
+ }
+};
+</script>
+
+<style lang="scss">
+.particle-network-animation {
+ position: fixed;
+ top: 20%;
+ left: 0;
+ right: 0;
+ // background-color: #171717;
+}
+.particle-network-animation::before {
+ z-index: -3;
+ content: "";
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background-size: cover;
+ opacity: 0.2;
+}
+
+.glow {
+ z-index: -2;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ background-image: radial-gradient(
+ circle closest-side,
+ rgba(255, 255, 255, 0.025),
+ transparent
+ );
+}
+
+.glow-1 {
+ width: 150vw;
+ height: 150vh;
+ margin-top: -75vh;
+ margin-left: -75vw;
+ animation: glow-1-move 25s linear infinite both;
+}
+
+@keyframes glow-1-move {
+ from {
+ transform: translate(-100%, 100%);
+ }
+ to {
+ transform: translate(100%, -100%);
+ }
+}
+.glow-2 {
+ width: 100vw;
+ height: 100vh;
+ margin-top: -50vh;
+ margin-left: -50vw;
+ animation: glow-2-move 25s linear 8.3333333333s infinite both;
+}
+
+@keyframes glow-2-move {
+ from {
+ transform: translate(-100%, 0%);
+ }
+ to {
+ transform: translate(100%, 100%);
+ }
+}
+.glow-3 {
+ width: 120vw;
+ height: 120vh;
+ margin-top: -60vh;
+ margin-left: -60vw;
+ animation: glow-3-move 25s linear 16.6666666667s infinite both;
+}
+
+@keyframes glow-3-move {
+ from {
+ transform: translate(100%, 100%);
+ }
+ to {
+ transform: translate(0%, -100%);
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/RuleEditor.vue b/src/components/subComponents/RuleEditor.vue
new file mode 100644
index 0000000..2f54f55
--- /dev/null
+++ b/src/components/subComponents/RuleEditor.vue
@@ -0,0 +1,811 @@
+<template>
+ <div class="edit-rules-box">
+ <p style="padding: 0">
+ <b style="font-size: 14px; line-height: 28px;">绛栫暐閰嶇疆</b>
+ <span class="btn" @click="createRule" v-if="groupRules.length === 0">
+ <i class="iconfont iconhebingxingzhuang" style="font-size:16px"></i>
+ 鏂板
+ </span>
+
+ <span class="btn" @click="cleanRule" v-if="groupRules.length > 0">
+ <i class="iconfont iconshanchu11" style="font-size:16px"></i>
+ 娓呯┖
+ </span>
+ </p>
+ <div class="sub-task-rules-box">
+ <span class="task-blank" v-show="groupRules.length == 0 ">鏆傛棤瑙勫垯锛岃閫夋嫨鏂板瑙勫垯閰嶇疆</span>
+ <div style=" text-align: left;" v-for="(rule, index) in groupRules" :key="index">
+ <div style="margin-left:10px;margin-top: 4px;" v-show="index > 0">
+ <el-select v-model="rule.rule_with_pre" placeholder="骞跺垪鍏崇郴" size="mini">
+ <el-option
+ v-for="subitem in VideoManageData.Dictionary.RULECOMPUTEBETWEEN"
+ :key="subitem.id"
+ :label="subitem.name"
+ :value="subitem.value"
+ :title="subitem.name"
+ ></el-option>
+ </el-select>
+ </div>
+
+ <div style="margin-left:10px;">
+ <!-- 閫夋嫨鍖哄煙 -->
+ <el-select
+ v-model="rule.polygonObj"
+ v-if="!isTemplate"
+ value-key="polygonId"
+ placeholder="閫夋嫨鍖哄煙"
+ size="mini"
+ @change="selectPolygonOption(rule)"
+ >
+ <el-option
+ v-for="subitem in allPolygonData"
+ :key="subitem.id"
+ :label="subitem.name"
+ :value="subitem"
+ :title="subitem.name"
+ ></el-option>
+ </el-select>
+
+ <!-- 閫夋嫨绠楁硶 -->
+ <el-select
+ v-model="rule.sdkObj"
+ value-key="id"
+ placeholder="閫夋嫨绠楁硶"
+ size="mini"
+ @change="selectSDKOption(rule, true)"
+ >
+ <el-option
+ v-for="subitem in rule.sdksOptions"
+ :key="subitem.id"
+ :label="subitem.sdk_name"
+ :value="subitem"
+ :title="subitem.sdk_name"
+ v-show="!subitem.delete"
+ ></el-option>
+ </el-select>
+
+ <!-- 閫夋嫨绫诲瀷 -->
+ <el-select
+ v-model="rule.sdk_arg_type"
+ placeholder="鐩爣"
+ size="mini"
+ style="width:90px;"
+ @change="selectArgTypeOption(rule)"
+ >
+ <el-option value="target" label="鐩爣"></el-option>
+ <el-option value="label" label="鏍囩"></el-option>
+ </el-select>
+
+ <!-- 閫夋嫨瑙勫垯 -->
+ <el-select
+ v-model="rule.argObj"
+ value-key="alias"
+ placeholder="閫夋嫨瑙勫垯"
+ size="mini"
+ @change="selectArgsOption(rule, true)"
+ >
+ <el-option
+ v-for="subitem in rule.argsOptions"
+ :key="subitem.alias"
+ :label="subitem.name"
+ :value="subitem"
+ :title="subitem.name"
+ ></el-option>
+ </el-select>
+
+ <!-- 閫夋嫨鏉′欢 -->
+ <el-select
+ v-model="rule.operatorObj"
+ value-key="value"
+ placeholder="閫夋嫨鏉′欢"
+ size="mini"
+ style="min-width:100px;width:8%"
+ @change="setOperator(rule)"
+ >
+ <el-option
+ v-for="subitem in VideoManageData.Dictionary.RULECOMPUTE"
+ :key="subitem.value"
+ :label="subitem.name"
+ :value="subitem"
+ ></el-option>
+ </el-select>
+
+ <!-- 鍊肩被鍨� -->
+ <el-select
+ v-show="false"
+ v-model="rule.operator_type"
+ placeholder="鍊肩被鍨�"
+ size="mini"
+ style="min-width:100px;width:8%"
+ @change="selectValueOption(rule)"
+ >
+ <el-option value="value" label="鍊�" :disabled="rule.argType === 'option'"></el-option>
+ <el-option value="option" label="琚�夐」" :disabled="rule.argType !== 'option'"></el-option>
+ <el-option value label="绌�" :disabled="rule.argType === 'option'"></el-option>
+ </el-select>
+
+ <!-- 鍊� -->
+ <el-input
+ v-if="rule.operator_type !== 'option'"
+ size="mini"
+ v-model="rule.sdk_arg_value"
+ :style="rule.valid ? `margin:3px 5px;min-width:100px;width:7%` : `margin:3px 5px;min-width:100px;width:7%;border:1px solid red`"
+ @change="setValue(rule)"
+ ></el-input>
+
+ <!-- 閫夐」鍊� -->
+ <el-select
+ v-else
+ v-model="rule.valueObj"
+ value-key="value"
+ size="mini"
+ style="width:8%;min-width:100px"
+ @change="setValue(rule)"
+ >
+ <el-option
+ v-for="subitem in rule.valueOptions"
+ :key="subitem.value"
+ :label="subitem.name"
+ :value="subitem"
+ :title="subitem.name"
+ ></el-option>
+ </el-select>
+
+ <!-- 鍗曚綅 -->
+ <span style="display:inline-block;width:15px;margin-right:10px;">{{ rule.unit }}</span>
+
+ <!-- 鏂板銆佸垹闄� 鎸夐挳 -->
+ <el-button type="text" @click="addRule(index)" class="iconfont iconhebingxingzhuang"></el-button>
+ <el-button
+ type="text"
+ style="color: #F53D3D;"
+ class="iconfont iconshanchu11"
+ @click="groupRules.splice(index, 1)"
+ ></el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+<script>
+import {
+ deleteCameraRules,
+ updateRuleDefence,
+ updateAlarmLevel
+} from "@/api/camera";
+
+export default {
+ name: "SceneRuleEditor",
+ props: {
+ Cameras: {
+ type: Array,
+ default: () => {
+ return []
+ }
+ },
+ isTemplate: {
+ type: Boolean,
+ default: false
+ },
+ isLinkRule: {
+ type: Boolean,
+ default: false
+ },
+ includeSdks: {
+ type: Array
+ },
+ ruleList: {
+ type: String,
+ default: "{}"
+ },
+ onSubmitRule: {
+ type: Function,
+ default: () => false
+ }
+ },
+ computed: {
+ allPolygonData() {
+ let polygon = [];
+ let cameras = [...this.Cameras];
+
+ for (let i = 0; i < cameras.length; i++) {
+ let polyOpt = cameras[i].polygonData.map(p => {
+ return {
+ defence_state: p.defence_state,
+ polygonId: p.id,
+ name: this.isLinkRule
+ ? cameras[i].cameraName + ":" + p.name
+ : p.name,
+
+ cameraId: cameras[i].cameraId
+ };
+ });
+
+ polygon = polygon.concat(polyOpt);
+ }
+ return polygon;
+ }
+ },
+ watch: {
+ ruleList: {
+ handler(newVal, oldVal) {
+ this.editHandle(newVal);
+ },
+ deep: true
+ },
+ },
+ mounted() {
+ this.editHandle(this.ruleList);
+ },
+ data() {
+ return {
+ tasksTable: {},
+ groupRules: [],
+ sdksOption: [],
+ baseRule: {
+ camera_id: "",
+ id: "",
+ operator: "",
+ operator_type: "",
+ polygon_id: "",
+ rule_with_pre: "",
+ sdk_id: "",
+ sdk_arg_alias: "",
+ sdk_arg_value: "",
+ sdk_arg_defaultValue: "",
+ select_time_rule: "",
+ sdk_arg_type: "",
+ // task_id: "",
+
+ polygonObj: {},
+ taskObj: "",
+
+ sdkObj: {},
+ argObj: {},
+ operatorObj: {},
+ valueObj: {},
+
+ sdksOptions: [],
+ argsOptions: [],
+ argType: "",
+ computeOptions: [],
+ valueOptions: [],
+
+ sdkDesc: "",
+ argDesc: "",
+ operatorDesc: "",
+ typeDesc: "",
+ valueDesc: "",
+
+ unit: "",
+ value: "",
+ valid: true
+ },
+ };
+ },
+ methods: {
+ setSdksOptions(rule) {
+ rule.sdksOptions = this.includeSdks;
+ },
+ setOperator(rule) {
+ rule.operator = rule.operatorObj.value;
+ rule.operatorDesc = rule.operatorObj.name;
+ },
+ setValue(rule) {
+ rule.valid = true
+
+ if (rule.operator_type === "option") {
+ rule.sdk_arg_value = rule.valueObj.value ? rule.valueObj.value : "";
+ rule.typeDesc = "琚�夐」";
+ rule.valueDesc = rule.valueObj.name ? rule.valueObj.name : "";
+ } else {
+ rule.typeDesc = "鍊�";
+ rule.valueDesc = rule.sdk_arg_value;
+ }
+ this.valideArgValue(rule)
+ },
+ selectPolygonOption(rule) {
+ rule.polygon_id = rule.polygonObj.polygonId ? rule.polygonObj.polygonId : rule.polygon_id;
+ rule.camera_id = rule.polygonObj.cameraId ? rule.polygonObj.cameraId : rule.camera_id;
+ rule.group_id = this.group_id;
+ },
+ selectSDKOption(rule, resetArgs) {
+ rule.sdk_id = rule.sdkObj.id;
+ rule.sdkDesc = `<span style="background-color:RGB(183,183,183);">${rule.sdkObj.sdk_name}</span>`;
+
+ // 閫夐」鍒囨崲鏃堕渶瑕佸埛鏂癮rg鑿滃崟椤�
+ this.selectArgTypeOption(rule, resetArgs)
+ },
+ selectArgTypeOption(rule, resetAlias) {
+ if (rule.sdk_arg_type == "") {
+ return
+ }
+
+ if (resetAlias) {
+ rule.sdk_arg_alias = "";
+ }
+
+ rule.argsOptions = rule.sdkObj.args;
+
+ // 鏍规嵁arg绫诲瀷鏄剧ず鍙傛暟, 褰撳墠鍏ㄩ儴褰掍负 target
+ // if (rule.sdkObj.args) {
+ // rule.argsOptions = rule.sdkObj.args.filter(ele => {
+ // return ele.arg_type === rule.sdk_arg_type
+ // });
+ // } else {
+ // rule.argsOptions = [];
+ // }
+
+ rule.argObj = {};
+ },
+ selectArgsOption(rule, resetArgValue) {
+ // rule.operator_type = "";
+ // console.log(rule, '閫夋嫨绠楁硶鍙傛暟')
+ rule.sdk_arg_alias = rule.argObj.alias;
+ rule.argDesc = rule.argObj.name;
+ rule.sdk_arg_defaultValue = rule.argObj.default_value
+ rule.unit = rule.argObj.unit ? rule.argObj.unit : "";
+ //rule.default_value = rule.argObj.default_value ? Number(rule.argObj.default_value) : 0;
+
+ //console.log("缃俊搴︾殑榛樿鍊间负",rule.sdk_arg_defaultValue)
+ // 淇濆瓨鍊肩被鍨�
+ rule.argType = rule.argObj.type;
+ if (rule.argType === "option") {
+ rule.operator_type = "option";
+ // 璁剧疆榛樿鏉′欢鍊�
+ this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
+ if (opt.value == "==") {
+ rule.operatorObj = opt;
+ }
+ });
+
+ this.setOperator(rule);
+
+ this.selectValueOption(rule);
+ } else {
+ // 璁剧疆榛樿鏉′欢鍊�
+ rule.operator_type = "value";
+ if (resetArgValue) {
+ rule.sdk_arg_value = ""
+
+ this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
+ if (opt.value == ">=") {
+ rule.operatorObj = opt;
+ }
+ });
+ } else {
+ // 缂栬緫瑙勫垯鍖归厤
+ this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
+ if (opt.value == rule.operator) {
+ rule.operatorObj = opt;
+ }
+ });
+ }
+ this.setOperator(rule);
+ }
+ },
+ selectValueOption(rule) {
+ if (rule.sdk_arg_alias === "time_rule") {
+ rule.valueOptions = this.VideoManageData.TimeRules.map(r => {
+ return {
+ name: r.name,
+ value: r.id
+ };
+ });
+ } else if (rule.sdk_arg_alias === "compareBase") {
+ rule.valueOptions = this.VideoManageData.TagList.map(r => {
+ return {
+ name: r.tableName,
+ value: r.id
+ };
+ });
+ } else {
+ let ops = this.VideoManageData.Dictionary[rule.sdk_arg_alias]
+ if (ops && ops instanceof (Array)) {
+ rule.valueOptions = ops.map(r => {
+ return {
+ name: r.name,
+ value: r.value
+ }
+ })
+ }
+ }
+ },
+ valideArgValue(rule) {
+ if (rule.sdk_arg_value == "") {
+ this.$notify({
+ type: 'warning',
+ message: "鍙傛暟璁惧畾鍊间笉鑳戒负绌�!"
+ })
+ rule.valid = false
+ return false
+ }
+
+ if (rule.argObj && rule.argObj.range) {
+ // 濡傛灉璁剧疆浜嗙畻娉曢粯璁ゅ�硷紝鍒欏垽鏂笉鑳藉皬浜庤鍊�
+ if (rule.argObj.default_value) {
+ if (parseInt(rule.sdk_arg_value) < parseInt(rule.sdk_arg_defaultValue)) {
+ rule.valid = false
+ this.$notify({
+ type: "warning",
+ message: "鍙傛暟璁惧畾鍊间笉鑳藉皬浜庣畻娉曞弬鏁伴粯璁ゅ�� " + rule.sdk_arg_defaultValue
+ })
+ rule.valueDesc = rule.sdk_arg_value = rule.argObj.default_value;
+ rule.valid = false
+ return false;
+ }
+ }
+
+ // let re = /(?<=,).*?(?=]|\))/
+ let re = /.*,(\d+)/
+ let max = rule.argObj.range.match(re)[1]
+ // console.log(max,'鑾峰彇鑼冨洿鏈�澶у��')
+ if (Number(rule.sdk_arg_value) > Number(max)) {
+ rule.valid = false
+ this.$notify({
+ type: 'warning',
+ message: "鍙傛暟璁惧畾鍊间笉鑳藉ぇ浜�" + max
+ })
+ return false
+ }
+ }
+
+ return true;
+ },
+ parataxis(rule_with_pre) {
+ let relation = "";
+ this.VideoManageData.Dictionary.RULECOMPUTEBETWEEN.forEach(pre => {
+ if (pre.value === rule_with_pre) {
+ relation = pre.name;
+ }
+ });
+
+ return relation;
+ },
+
+ generatDescription() {
+ let desc = "";
+ this.groupRules.forEach((r, index) => {
+ // console.log(r,index,'鎷兼帴')
+ if (index === 0) {
+ desc +=
+
+ r.sdkDesc +
+ r.argDesc +
+ r.operatorDesc +
+ r.valueDesc +
+ r.unit
+ } else {
+ desc +=
+ ' ' + this.parataxis(r.rule_with_pre) + ' ' +
+ r.sdkDesc +
+ r.argDesc +
+ r.operatorDesc +
+ r.valueDesc +
+ r.unit
+ }
+ });
+ // console.log(desc,'鎷兼帴')
+ return desc;
+ },
+ createRule() {
+ if (!this.isTemplate && this.Cameras.length > 0) {
+ // 鏈�変腑鎽勫儚鏈烘垨鑰呮湭閫変腑鎽勫儚鏈轰换鍔★紝涓嶆墽琛屽垱寤�
+ if (!this.Cameras[0].cameraId)
+ return false;
+ }
+
+ if (this.isLinkRule && this.TreeDataPool.selectedNodes.length < 2) {
+ this.$notify({
+ type: "warning",
+ message: "璇烽�夋嫨鑷冲皯2涓憚鍍忔満!"
+ })
+ return false;
+ }
+
+ this.group_id = "";
+
+ this.addRule(0);
+ },
+ cleanRule() {
+ this.groupRules.splice(0, this.groupRules.length);
+ },
+ addRule(index) {
+ let newRule = JSON.parse(JSON.stringify(this.baseRule));
+ newRule.sdksOptions = this.includeSdks;
+ if (!this.isLinkRule) {
+ // 璁剧疆榛樿鍏ㄩ儴鍖哄煙
+ // if (!this.isTemplate) {
+ // newRule.polygonObj = this.allPolygonData[0];
+ // this.selectPolygonOption(newRule)
+ // }
+
+ // 璁剧疆绠楁硶
+ // newRule.sdksOptions = this.includeSdks;
+ // 璁剧疆榛樿绠楁硶
+ // newRule.sdkObj = newRule.sdksOptions[0]
+ // this.selectSDKOption(newRule, false)
+
+ // newRule.sdk_arg_type = "target"
+ // this.selectArgTypeOption(newRule, true)
+ }
+
+ // this.groupRules.push(newRule);
+ // 鎻掑叆鍒版寚瀹氫綅缃�
+ this.groupRules.splice(index + 1, 0, newRule);
+ },
+ editHandle(ruleTxt) {
+ if (ruleTxt.length < 1) {
+ return;
+ }
+ let ruleInfo = JSON.parse(ruleTxt);
+ this.editRule(ruleInfo)
+ // 濡傛灉鏄仈鍔ㄤ换鍔�, 鏌ヨ鑱斿姩鎽勫儚鏈哄垪琛�, 灏嗘爲閫変腑鐨勫垪琛ㄦ洿鏀逛负璇ユ潯瑙勫垯鎵�闇�瑕佺殑鎽勫儚鏈�, 骞跺浠藉綋鍓嶇殑閫変腑鐘舵��, 瑙勫垯淇濆瓨鍚庢仮澶�
+ // if (this.isLinkRule) {
+ // this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule = [...this.TreeDataPool.selectedNodes]
+ // this.VideoRuleData.editLinkRuleRow = { ...ruleInfo }
+
+ // this.TreeDataPool.selectedNodes = ruleInfo.group_rules.map(r => {
+ // return r.camera_id
+ // })
+ // this.$nextTick(() => {
+ // setTimeout(() => {
+ // this.editRule(ruleInfo)
+ // }, 1000)
+ // })
+ // } else {
+ // this.editRule(ruleInfo)
+ // }
+ },
+ editRule(ruleGroup) {
+ this.group_id = "";
+
+ ruleGroup.forEach(rule => {
+ if (rule.group_id && rule.group_id != "") {
+ this.group_id = rule.group_id;
+ }
+
+ // 濉厖鍖哄煙閫夐」鍒楄〃
+ this.allPolygonData.forEach(p => {
+ if (p.polygonId === rule.polygon_id) {
+ rule.polygonObj = p;
+ }
+ });
+
+ if (!rule.polygonObj) {
+ rule.polygonObj = {
+ cameraId: rule.camera_id,
+ defence_state: 1,
+ name: "鏈煡鍖哄煙",
+ polygonId: rule.polygon_id,
+ }
+ }
+
+ // 璁剧疆鍖哄煙
+ this.selectPolygonOption(rule);
+
+ // 璁剧疆绠楁硶缁�
+ this.setSdksOptions(rule);
+
+ // 濉厖绠楁硶閫夐」鍒楄〃
+ if (rule.sdksOptions) {
+ rule.sdksOptions.forEach(s => {
+ if (s.id === rule.sdk_id) {
+ rule.sdkObj = s;
+ }
+ });
+ }
+ if (!rule.sdkObj || Object.keys(rule.sdkObj).length === 0) {
+ rule.sdkObj = {
+ id: rule.sdk_id,
+ sdk_name: "(宸插垹闄�)",
+ args: [],
+ delete: true
+ }
+ rule.sdksOptions.push(rule.sdkObj)
+ }
+
+ this.selectSDKOption(rule, false);
+ // 瑙勫垯淇濆瓨鏃舵暟鎹簱涓嶅瓨鍙傛暟绫诲瀷锛岄渶瑕佹牴鎹�煎弽鏌�
+ // rule.sdk_arg_type = ""
+ // if (rule.sdk_arg_alias === "time_rule") {
+ // rule.sdk_arg_type = "target"
+ // }
+ rule.sdk_arg_type = "target"
+ // rule.sdkObj.args.forEach(ele => {
+ // if (ele.alias === rule.sdk_arg_alias) {
+ // rule.sdk_arg_type = ele.arg_type
+ // }
+ // });
+ this.selectArgTypeOption(rule, false)
+
+ if (rule.argsOptions) {
+ rule.argsOptions.forEach(arg => {
+ if (arg.alias === rule.sdk_arg_alias) {
+ rule.argObj = arg;
+ }
+ });
+ this.selectArgsOption(rule, false);
+ }
+
+ this.VideoManageData.Dictionary.RULECOMPUTE.forEach(opt => {
+ if (opt.value == rule.operator) {
+ rule.operatorObj = opt;
+ }
+ });
+
+ this.setOperator(rule);
+ this.selectValueOption(rule);
+
+ if (rule.operator_type == "option") {
+ rule.valueOptions.forEach(val => {
+ if (val.value === rule.sdk_arg_value) {
+ rule.valueObj = val;
+ }
+ });
+ }
+ if (!rule.valueObj) {
+ rule.valueObj = {
+ name: rule.sdk_arg_value,
+ value: rule.sdk_arg_value
+ }
+ }
+ this.setValue(rule);
+ });
+ this.$nextTick(() => {
+ this.groupRules = ruleGroup;
+ });
+ },
+ delRule(rule) {
+ this.$confirm("鎻愮ず锛氬垹闄ゅ悗锛岃鏉¤鍒欏皢澶辨晥锛屾槸鍚﹀垹闄わ紵", {
+ center: true,
+ cancelButtonClass: "comfirm-class-cancle",
+ confirmButtonClass: "comfirm-class-sure"
+ })
+ .then(() => {
+ deleteCameraRules({ groupId: rule.group_id }).then(res => {
+ if (res && res.success) {
+ this.$notify({
+ type: "success",
+ message: "鍒犻櫎鎴愬姛"
+ });
+ this.$emit("delete-rule");
+ } else {
+ this.$notify({
+ type: "error",
+ message: "鍒犻櫎澶辫触锛�"
+ });
+ }
+ });
+ })
+ .catch(() => { });
+ },
+ submitRule() {
+ let groupRule = {};
+ let group_text = "";
+
+ if (this.isTemplate) {
+ groupRule.rules = this.groupRules.map(r => {
+ return {
+ sdk_id: r.sdk_id,
+ sdk_arg_alias: r.sdk_arg_alias,
+ operator: r.operator,
+ operator_type: r.operator_type,
+ sdk_arg_value: r.sdk_arg_value,
+ sort: 1,
+ rule_with_pre: r.rule_with_pre
+ };
+ })
+ } else {
+ groupRule.rules = this.groupRules.map(r => {
+ return {
+ camera_id: r.camera_id,
+ group_id: r.group_id,
+ id: r.id,
+ operator: r.operator,
+ operator_type: r.operator_type,
+ polygon_id: r.polygon_id,
+ rule_with_pre: r.rule_with_pre,
+ sdk_arg_alias: r.sdk_arg_alias,
+ sdk_arg_value: r.sdk_arg_value,
+ sdk_id: r.sdk_id,
+ };
+ })
+ }
+
+ groupRule.text = this.generatDescription();
+ groupRule.id = this.group_id;
+ return groupRule;
+
+ // 鏆傛椂鍏堜笉楠岃瘉
+ for (let i in this.groupRules) {
+ let rule = this.groupRules[i]
+ if (!rule.polygon_id || !rule.sdk_id || !rule.operator || !rule.operator_type || rule.sdk_arg_type == "") {
+ this.$notify({
+ type: "error",
+ message: "涓嶅厑璁搁厤缃笉瀹屾暣鐨勮鍒欙紝璇锋鏌ユ槸鍚︽湁鏈�夋嫨椤�"
+ })
+ return;
+ }
+ if (!this.valideArgValue(rule)) {
+ return;
+ }
+ }
+
+ if (this.isLinkRule) {
+ // 鍒ゆ柇瑙勫垯涓嚦灏戝寘鍚袱鎽勫儚鏈�
+ let cameraIds = Array.from(new Set(this.groupRules.map(r => {
+ return r.camera_id
+ })))
+ if (cameraIds.length < 2) {
+ this.$notify({
+ type: "error",
+ message: "闇�瑕�2涓笉鍚屾憚鍍忔満鎵嶈兘缁勬垚鑱斿姩瑙勫垯"
+ })
+ return
+ }
+
+ // 鑱斿姩瑙勫垯缂栬緫鍚庯紝鎭㈠涔嬪墠閫変腑鐨勬憚鍍忔満
+ // if (this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule.length) {
+ // this.TreeDataPool.selectedNodes = this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule
+ // this.VideoRuleData.treeSelectedNodesBackupOnEditLinkRule = []
+ // }
+ }
+
+ this.onSubmitRule(payload);
+ }
+ }
+};
+</script>
+
+<style lang="scss">
+.edit-rules-box {
+ width: 100%;
+ padding: 0px;
+ box-sizing: border-box;
+ .sub-task-rules-box {
+ width: 100%;
+ min-height: 50px;
+ border-top: 1px solid #eee;
+ padding-top: 7px;
+
+ box-sizing: border-box;
+ padding-bottom: 38px;
+ .task-rules-button {
+ text-align: right;
+ margin: 15px;
+ }
+
+ .el-select {
+ margin: 3px 8px;
+ min-width: 130px;
+ width: 12%;
+ }
+ }
+
+ .el-button--text {
+ text-decoration: unset;
+ }
+
+ p {
+ text-align: left;
+ // padding: 10px;
+ box-sizing: border-box;
+ }
+
+ .task-blank {
+ float: left;
+ font-family: PingFangSC-Regular;
+ font-size: 12px;
+ color: #cccccc;
+ margin-top: 5px;
+ }
+
+ .btn {
+ cursor: pointer;
+ color: #3d68e1;
+ margin-left: 10px;
+ font-size: 14px;
+ }
+}
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/VueCron.vue b/src/components/subComponents/VueCron.vue
new file mode 100644
index 0000000..d5d59a0
--- /dev/null
+++ b/src/components/subComponents/VueCron.vue
@@ -0,0 +1,194 @@
+<template>
+ <div>
+ <b style="padding-right:30px;">瀹氭椂閲嶅惎:</b>
+ <el-select v-model="every" placeholder="璇烽�夋嫨" size="small" @change="changeEvery">
+ <el-option label="鍏抽棴" value="never"></el-option>
+ <el-option label="姣忓ぉ" value="day"></el-option>
+ <el-option label="姣忓懆" value="week"></el-option>
+ <el-option label="姣忔湀" value="month"></el-option>
+ </el-select>
+
+ <el-select
+ v-show="every == 'month'"
+ v-model="cronValueObj.day"
+ placeholder="璇烽�夋嫨"
+ size="small"
+ style="margin-left: 20px"
+ @change="updateExpression"
+ >
+ <el-option v-for="item in days" :key="item.value" :label="item.label" :value="item.value"></el-option>
+ </el-select>
+
+ <el-select
+ v-show="every == 'week'"
+ v-model="cronValueObj.week"
+ placeholder="璇烽�夋嫨"
+ size="small"
+ style="margin-left: 20px"
+ @change="updateExpression"
+ >
+ <el-option label="鏄熸湡涓�" value="1"></el-option>
+ <el-option label="鏄熸湡浜�" value="2"></el-option>
+ <el-option label="鏄熸湡涓�" value="3"></el-option>
+ <el-option label="鏄熸湡鍥�" value="4"></el-option>
+ <el-option label="鏄熸湡浜�" value="5"></el-option>
+ <el-option label="鏄熸湡鍏�" value="6"></el-option>
+ <el-option label="鏄熸湡鏃�" value="7"></el-option>
+ </el-select>
+
+ <el-time-picker
+ v-show="every !== 'never'"
+ v-model="time"
+ :picker-options="{selectableRange: '00:00:00 - 23:59:59'}"
+ value-format="HH:mm"
+ format="HH:mm"
+ placeholder="浠绘剰鏃堕棿鐐�"
+ size="small"
+ style="margin-left: 20px"
+ @change="updateExpression"
+ ></el-time-picker>
+
+ <el-button
+ v-show="saveBtn"
+ type="primary"
+ size="small"
+ style="margin-left: 20px"
+ @click="save"
+ >淇濆瓨</el-button>
+ </div>
+</template>
+
+<script>
+export default {
+ name: "VueCrontab",
+ props: ["expression"],
+ computed: {
+ days: () => {
+ let arr = []
+ for (let i = 1; i < 32; i++) {
+ arr.push({
+ label: i + "鏃�",
+ value: i + ""
+ })
+ }
+
+ return arr
+ }
+ },
+ watch: {
+ expression: function () {
+ this.resolveExp()
+ }
+ },
+ data() {
+ return {
+ saveBtn: false,
+ every: "never",
+ time: "",
+ cronValueObj: {
+ min: "*",
+ hour: "*",
+ day: "*",
+ month: "*",
+ week: "*"
+ },
+ cronText: ""
+ }
+ },
+ mounted() {
+ this.resolveExp()
+ },
+ methods: {
+ resolveExp() {
+ //鍙嶈В鏋� 琛ㄨ揪寮�
+ "鍑嗗鍙嶈В鏋�", this.expression;
+ if (this.expression.length) {
+ let arr = this.expression.split(" ");
+ if (arr.length >= 5) {
+ //6 浣嶄互涓婃槸鍚堟硶琛ㄨ揪寮�
+ this.cronValueObj.min = arr[0]
+ this.cronValueObj.hour = arr[1]
+ this.cronValueObj.day = arr[2]
+ // this.cronValueObj.month = arr[3],
+ this.cronValueObj.month = "*"
+ this.cronValueObj.week = arr[4]
+ }
+
+ if (this.cronValueObj.week != "*") {
+ this.every = "week"
+ } else if (this.cronValueObj.day != "*") {
+ this.every = "month"
+ } else {
+ this.every = "day"
+ }
+ this.time = this.cronValueObj.hour + ":" + this.cronValueObj.min
+ } else {
+ //娌℃湁浼犲叆鐨勮〃杈惧紡 鍒欒繕鍘�
+ this.clearCron();
+ }
+ },
+ changeEvery() {
+ this.saveBtn = true;
+ if (this.every === "never") {
+ this.cronText = ""
+ return
+ }
+ if (this.every === "month") {
+ this.cronValueObj.week = "*"
+ this.cronValueObj.day = "1"
+ if (!this.time.length) {
+ this.time = "00:00"
+ }
+ }
+ if (this.every === "week") {
+ this.cronValueObj.day = "*"
+ this.cronValueObj.week = "1"
+ if (!this.time.length) {
+ this.time = "00:00"
+ }
+ }
+ if (this.every === "day") {
+ this.cronValueObj.day = "*"
+ this.cronValueObj.week = "*"
+ }
+ this.updateExpression()
+ },
+ updateExpression() {
+ this.saveBtn = true;
+ if (this.time.length) {
+ let arr = this.time.split(":");
+ this.cronValueObj.hour = arr[0]
+ this.cronValueObj.min = arr[1]
+ }
+ this.crontabValueString()
+ },
+ clearCron() {
+ this.cronValueObj.second = "*"
+ this.cronValueObj.min = "*"
+ this.cronValueObj.hour = "*"
+ this.cronValueObj.day = "*"
+ this.cronValueObj.month = "*"
+ this.cronValueObj.week = "*"
+ },
+ crontabValueString: function () {
+ let obj = this.cronValueObj;
+ this.cronText =
+ obj.min +
+ " " +
+ obj.hour +
+ " " +
+ obj.day +
+ " " +
+ obj.month +
+ " " +
+ obj.week
+ },
+ save() {
+ this.$emit("update", this.cronText)
+ }
+ }
+}
+</script>
+
+<style lang="scss">
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/chartLiquid.vue b/src/components/subComponents/chartLiquid.vue
new file mode 100644
index 0000000..4d7cdf5
--- /dev/null
+++ b/src/components/subComponents/chartLiquid.vue
@@ -0,0 +1,141 @@
+<template>
+ <div ref="ball" :style="{width: size + 'px', height: size + 'px', marginLeft: '10px'}"></div>
+</template>
+
+<script>
+import echarts from "echarts";
+import echartsLiquidfill from "echarts-liquidfill";
+
+export default {
+ name: "EchartsLiquidFill",
+ props: {
+ title: {
+ type: String,
+ defalut: ""
+ },
+ value: {
+ type: Number,
+ defalut: 0
+ },
+ size: {
+ type: Number,
+ defalut: 100
+ }
+ },
+ computed: {
+ fillColor() {
+ if (this.PollData.Thresholds.length > 0) {
+ for (let i = 0; i < this.PollData.Thresholds.length; i++) {
+ if (this.value <= this.PollData.Thresholds[i].Value) {
+ return this.PollData.Thresholds[i].Color;
+ }
+ }
+ }
+
+ if (this.value <= 60) {
+ return "#13ce66"
+ } else if (this.value > 60 && this.value <= 80) {
+ return "#FF9C4A"
+ } else if (this.value > 80 && this.value <= 95) {
+ return "#f53d3d"
+ } else {
+ return "#5d0000"
+ }
+ }
+ },
+ mounted() {
+ this.initChart()
+ },
+ watch: {
+ value: function (newVal, oldVal) {
+ if (newVal !== oldVal) {
+ this.initChart()
+ }
+ }
+ },
+ methods: {
+ initChart() {
+ let options = {
+ title: {
+ // 鏍囬
+ text: this.title,
+ textStyle: {
+ // 鏍囬鐨勬牱寮�
+ color: "#222", // 瀛椾綋棰滆壊
+ fontFamily: "Microsoft YaHei", // 瀛椾綋
+ fontSize: 14,
+ fontWeight: "800",
+ align: "center", // 鏂囧瓧鐨勬按骞虫柟寮�
+ baseline: "middle",
+ position: "inside",
+ verticalAlign: "middle" // 鏂囧瓧鐨勫瀭鐩存柟寮�
+ },
+ left: "center", // 瀹氫綅
+ top: "14%"
+ },
+
+ grid: {
+ left: 50,
+ },
+ series: [
+ {
+ type: "liquidFill",
+ radius: "95%",
+ waveAnimation: true,
+ data: [
+ {
+ value: this.value / 100,
+ direction: "left",
+ itemStyle: {
+ normal: {
+ color: this.fillColor
+ }
+ }
+ }
+ ],
+ outline: {
+ // show: true , //鏄惁鏄剧ず杞粨 甯冨皵鍊�
+ borderDistance: 1, // 澶栭儴杞粨涓庡浘琛ㄧ殑璺濈 鏁板瓧
+ itemStyle: {
+ borderColor: this.fillColor, // 杈规鐨勯鑹�
+ borderWidth: 3, // 杈规鐨勫搴�
+ shadowBlur: 1, //澶栭儴杞粨鐨勯槾褰辫寖鍥� 涓�鏃﹁缃簡鍐呭閮芥湁闃村奖
+ shadowColor: '#fff' //澶栭儴杞粨鐨勯槾褰遍鑹�
+ }
+ },
+ itemStyle: {
+ opacity: 0.9, // 娉㈡氮鐨勯�忔槑搴�
+ shadowBlur: 0 // 娉㈡氮鐨勯槾褰辫寖鍥�
+ },
+ backgroundStyle: {
+ color: "#fff" // 鍥捐〃鐨勮儗鏅鑹�
+ },
+ label: {
+ // 鏁版嵁灞曠ず鏍峰紡
+ show: true,
+ color: "#000",
+ insideColor: "#fff",
+ fontSize: 14,
+ fontWeight: 400,
+ align: "center",
+ baseline: "middle",
+ position: "inside",
+ normal: {
+ formatter: (this.value).toFixed(2) + '%',
+ textStyle: {
+ fontSize: 14,
+ fontWeight: 400,
+ color: "#000",
+ }
+ }
+ }
+
+ }
+ ]
+ }
+ let chart = echarts.init(this.$refs.ball);
+ chart.setOption(options);
+ }
+ }
+};
+</script>
\ No newline at end of file
diff --git a/src/components/subComponents/eChartsBar.vue b/src/components/subComponents/eChartsBar.vue
new file mode 100644
index 0000000..4cd7a99
--- /dev/null
+++ b/src/components/subComponents/eChartsBar.vue
@@ -0,0 +1,174 @@
+<template>
+ <div ref="cpuMenery" style="height:100%;"></div>
+</template>
+
+<script>
+import echarts from "echarts";
+
+export default {
+ name: "eChartsCpu",
+ props: {
+ title: {
+ type: String,
+ defalut: ""
+ },
+ value: {
+ type: Number,
+ defalut: 0
+ },
+ yAxisData: {
+ type: Array,
+ default: () => {
+ return ["纭洏", "CPU", "绠楀姏", "鍐呭瓨"]
+ }
+ },
+ xAxisData: {
+ type: Array,
+ default: () => {
+ return []
+ }
+ },
+ width: {
+ type: Number,
+ default: 500
+ },
+ size: {
+ type: Number,
+ defalut: 145
+ }
+ },
+ computed: {
+
+ },
+ data() {
+ return {
+ eChartsObj: {}
+ }
+ },
+ mounted() {
+ // console.log(this.$refs.cpuMenery.offsetWidth,'this.$refs.cpuMenery',this.$refs.cpuMenery.offsetHeight)
+ if (this.$refs.cpuMenery.offsetWidth && this.$refs.cpuMenery.offsetHeight) {
+ this.initChart()
+ }
+ window.addEventListener('resize', this.windowSizeChange)
+ },
+ watch: {
+ value: function (newVal, oldVal) {
+ if (newVal !== oldVal) {
+ this.initChart()
+ }
+ }
+ },
+ methods: {
+ initChart() {
+ let options = {
+ title: {
+ // 鏍囬
+ text: this.title
+ },
+ tooltip: {
+ formatter: (data) => {
+ return data.value + '%'
+ }
+ },
+ grid: {
+ top: 10,
+ right: 30,
+ bottom: 20,
+ left: 40,
+ },
+ xAxis: {
+ show: false,
+ type: 'value',
+ max: 100,
+ splitLine: {
+ show: false
+ },
+ axisLine: {
+ lineStyle: {
+ color: '#dfe6ec'
+ }
+ },
+ axisTick: {
+ lineStyle: {
+ color: '#606266'
+ }
+ },
+ axisLabel: {
+ color: '#606266'
+ },
+ },
+ yAxis: {
+ show: true,
+ type: 'category',
+ data: this.yAxisData,
+ axisLabel: {
+ interval: 0,
+ rotate: 0
+ },
+ axisLine: {
+ show: false,
+ lineStyle: {
+ color: '#dfe6ec'
+ }
+ },
+ axisTick: {
+ show: false,
+ lineStyle: {
+ color: '#606266'
+ }
+ },
+ axisLabel: {
+ color: '#606266',
+ align: 'right'
+ },
+ },
+ series: [
+ {
+ type: 'bar',
+ stack: 'chart',
+ z: 3,
+ itemStyle: {
+ normal: {
+ color: '#3D68E1'
+ },
+ emphasis: {
+ color: '#3D68E1'
+ }
+ },
+ data: this.xAxisData,
+ label: {
+ show: true,
+ position: 'right',
+ formatter: (data) => {
+ return data.value + '%'
+ }
+ },
+ },
+ {
+ type: 'bar',
+ stack: 'chart',
+ silent: true,
+ itemStyle: {
+ normal: {
+ color: 'rgb(248, 248, 248)'
+ }
+ },
+ data: this.xAxisData.map(function (i) {
+ return 100 - i;
+ }),
+ barMaxWidth: 15
+ }
+ ]
+ }
+ this.eChartsObj = echarts.init(this.$refs.cpuMenery);
+ this.eChartsObj.setOption(options);
+ },
+ windowSizeChange() {
+ this.eChartsObj.resize();
+ },
+ }
+};
+</script>
+<style lang="scss">
+</style>
\ No newline at end of file
diff --git a/src/components/subComponents/imgDown.vue b/src/components/subComponents/imgDown.vue
new file mode 100644
index 0000000..5b988c3
--- /dev/null
+++ b/src/components/subComponents/imgDown.vue
@@ -0,0 +1,93 @@
+<template>
+ <div class="imgBox">
+ <img
+ :src="'/httpImage/'+url"
+ class="cursor-pointer"
+ v-if="isPreview"
+ preview
+ />
+ <img
+ :src="'/httpImage/'+url"
+ v-if="!isPreview"
+ />
+ <el-button class="btn" @click="downloadIamge('/httpImage/'+url)">
+ <i class="iconfont iconxiazai"></i>
+ </el-button>
+ </div>
+</template>
+<script>
+import axios from "axios"
+export default {
+ props:{
+ url: {
+ default: "",
+ type: String
+ },
+ isPreview: {
+ default: true,
+ type: Boolean
+ }
+ },
+ methods:{
+ downloadIamge(url) {
+ axios({
+ method: "get",
+ url: url,
+ responseType: 'blob'
+ }).then(res => {
+ if (res.status == 200) {
+ var a = document.createElement('a')
+ var strs = url.split('/')
+ var href = new Blob([res.data],{type: 'image/jpeg'})
+ a.href = URL.createObjectURL(href);
+ a.download = strs[strs.length - 1]+'.jpg'
+ a.click()
+ }
+ }).catch(err => {
+ this.$notify({
+ type: "error",
+ message: "涓嬭浇澶辫触锛�"+err+"璇烽噸璇曪紒",
+ })
+ })
+ },
+ }
+
+}
+</script>
+<style lang="scss" scoped>
+.imgBox{
+ width: 100%;
+ height: 100%;
+ position: relative;
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain
+ }
+ .btn {
+ width: 30px;
+ height: 30px;
+ position: absolute;
+ padding: 0;
+ right: 20%;
+ opacity: 1;
+ bottom: 10px;
+ -webkit-animation: fadenum 0.7s ease;
+ display: none;
+ i {
+ font-size: 20px
+ }
+ }
+}
+.imgBox:hover .btn {
+ display: inline;
+}
+@-webkit-keyframes fadenum{ /*璁剧疆鍐呭鐢辨樉绀哄彉涓洪殣钘�*/
+
+ 0%{opacity: 0;}
+
+ 100%{opacity: 1;}
+
+}
+
+</style>
\ No newline at end of file
diff --git a/src/pages/algorithmManage/index/App.vue b/src/pages/algorithmManage/index/App.vue
new file mode 100644
index 0000000..34488d2
--- /dev/null
+++ b/src/pages/algorithmManage/index/App.vue
@@ -0,0 +1,861 @@
+<template>
+ <div class="s-task-manage">
+ <div style="height:100%;">
+ <div class="flex-box task-manage">
+ <div class="installModel" v-if="isInstall">
+ <div class="progress-bar">
+ <div class="inner-bar"></div>
+ </div>
+ </div>
+ <!-- 瓒呯骇绠$悊鍛樺彲瑙� -->
+ <div class="super" v-if="isSuperUser">
+ <div class="left-box">
+ <!-- <div class="title">
+ <label>绠楁硶搴�</label>
+ </div>-->
+ <el-tabs
+ v-model="activeName"
+ type="border-card"
+ @tab-click="handleTabClick"
+ style="height: calc(100% - 20px);"
+ >
+ <el-tab-pane label="鎴戠殑绠楁硶" name="myAlgorithm">
+ <div class="width-new-line task-list" v-show="activeName === 'myAlgorithm'">
+ <div class="flex-list">
+ <!-- <draggable
+ :list="installedList"
+ :group="{ name: 'article', pull: 'clone', put: false }"
+ :sort="false"
+ @start="startRight"
+ @end="endLeft"
+ style="display:inline"
+ >-->
+
+ <div class="wrap-box" v-for="item in ungradeList" :key="item.id">
+ <div class="list-choose-item-left">
+ <div class="mask">
+ <el-button type="primary" class="bot-btn" @click="donwload(item)">鍗囩骇</el-button>
+ </div>
+
+ <div class="list-complete-item-handle">
+ <div class="svg-wrap">
+ <svg class="icon" aria-hidden="true" style="font-size:7rem;">
+ <use :xlink:href="`#${item.icon}`" />
+ </svg>
+ </div>
+ <div class="alg-name">
+ <div style="padding:0px 10px 0px 10px;">
+ <span>{{ item.sdk_name }}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="wrap-box" v-for="(item) in installedList" :key="item.id">
+ <div class="list-choose-item-left">
+ <div class="mask" v-if="!item.isEdit">
+ <el-button
+ @click="commandAlgLib(item)"
+ type="primary"
+ class="bot-btn"
+ >缂栬緫鍚嶇О</el-button>
+ </div>
+ <div class="list-complete-item-handle">
+ <!-- <span :class="`iconfont ${item.icon}`" style="font-size:3rem;"></span> -->
+ <div class="svg-wrap">
+ <svg class="icon" aria-hidden="true" style="font-size:7rem;">
+ <use :xlink:href="`#${item.icon}`" />
+ </svg>
+ </div>
+ <div class="alg-name">
+ <div style="padding:0px 10px 0px 10px;">
+ <span v-if="!item.isEdit">{{ item.sdk_name }}</span>
+
+ <el-input
+ size="small"
+ v-model="item.sdk_name"
+ v-if="item.isEdit"
+ v-focus
+ :maxlength="15"
+ @blur="inputBlur(item)"
+ ></el-input>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- </draggable> -->
+ <div class="wrap-box" v-for="(item) in notInstalledList" :key="item.id">
+ <div
+ class="list-choose-item-left list-choose-item-left-uninstal"
+ v-loading="downloading && downloadItem == item.id"
+ >
+ <div class="mask">
+ <el-button type="primary" class="bot-btn" @click="donwload(item)">瀹夎</el-button>
+ </div>
+ <div class="click-download" title="涓嬭浇">
+ <span class="iconfont iconxiazai1"></span>
+ </div>
+ <div class="list-complete-item-handle">
+ <!-- <span :class="`iconfont ${item.icon}`" style="font-size:3rem;"></span> -->
+ <div class="svg-wrap">
+ <svg class="icon" aria-hidden="true" style="font-size:7rem;">
+ <use :xlink:href="`#${item.icon}`" />
+ </svg>
+ </div>
+ <div class="alg-name">
+ <div style="padding:0px 10px 0px 10px;">
+ <span class="list-choose-item-left-uninstal">{{ item.sdk_name }}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- 鏈笅杞� -->
+ </div>
+ </el-tab-pane>
+
+ <el-tab-pane
+ label="绂荤嚎鍗囩骇/瀹夎"
+ name="upgradeOrInstallation"
+ v-show="activeName==='upgradeOrInstallation'"
+ >
+ <div class="tab-content">
+ <div class="action-bar">
+ <file-uploader
+ single
+ tip
+ tipWords="涓婁紶绠楁硶"
+ uploadPlaceholder="绂荤嚎瀹夎绠楁硶"
+ url="/data/api-v/sdk/upload"
+ @complete="onFileUpload"
+ @file-added="onFileAdded"
+ />
+ </div>
+ </div>
+ </el-tab-pane>
+ <el-tab-pane label="绠楁硶鍟嗗煄" name="algorithmMall" v-show="activeName==='algorithmMall'">
+ <div class="tab-content">
+ <div class="store-list">
+ <div class="wrap-box">
+ <div class="inner">
+ <div class="mask" @click="actDrawerShow=true">
+ <svg class="icon" aria-hidden="true" style="font-size:2rem;">
+ <use xlink:href="#iconyunxiazai" />
+ </svg>
+ </div>
+ <div class="alg-icon">
+ <svg class="icon" aria-hidden="true" style="font-size:7rem;">
+ <use xlink:href="#iconrenyuanyidong" />
+ </svg>
+ </div>
+ <div class="alg-name">name</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <el-drawer title="涓嬭浇" :visible.sync="actDrawerShow" :direction="direction">
+ <div class="drawer-content">
+ <div class="current-step">
+ <el-steps align-center :active="actStep" finish-status="success">
+ <el-step title="娣诲姞婵�娲荤爜"></el-step>
+ <el-step title="婵�娲绘垚鍔�"></el-step>
+ </el-steps>
+ </div>
+
+ <div v-if="actStep==0">
+ <div class="act-code">
+ <p>浣跨敤婵�娲荤爜灏嗘柊鐨勭畻娉曟坊鍔犲埌鎮ㄧ殑璐︽埛</p>
+ <el-input
+ v-model="activeCode"
+ placeholder="00000-00000-00000-00000-00000"
+ @blur="getCodeDetail"
+ ></el-input>
+ </div>
+ <div class="text-right">
+ <el-button type="primary" @click="actived">婵�娲�</el-button>
+ </div>
+ </div>
+ <div v-else-if="actStep==1">
+ <ul class="desc">
+ <li>
+ <label>婵�娲荤爜:</label>
+ <span>YUAAA-AAAEU-QJQE3-ZRRXD-K9MWR</span>
+ </li>
+ <li>
+ <label>浜у搧鍚嶇О:</label>
+ <span>浜哄憳璺熻釜SDK</span>
+ </li>
+ <li>
+ <label>閰嶇疆璇︽儏:</label>
+ <span>鏃�</span>
+ </li>
+ <li>
+ <label>鏈嶅姟鍒版湡鏃�:</label>
+ <span>2021-03-04</span>
+ </li>
+ <li>
+ <label>璁稿彲璇�:</label>
+ <span>鏈澶�</span>
+ </li>
+ <li>
+ <label>璁惧ID:</label>
+ <span>3342-235f-ret55-fdsg</span>
+ </li>
+ </ul>
+ <div class="text-right">
+ <el-button type="primary" @click="checkMyAlgorith">纭畾</el-button>
+ <p class="tip">鎻愮ず锛氳鍦ㄢ�滄垜鐨勭畻娉曗�濅腑鏌ョ湅骞跺畨瑁呯畻娉�</p>
+ </div>
+ </div>
+ </div>
+ </el-drawer>
+ </el-tab-pane>
+ </el-tabs>
+ </div>
+
+ <!-- 绠楁硶绠$悊 -->
+ <!-- <div class="right-box" style="width:58%">
+ <div class="title">
+ <label>绠楁硶绠$悊</label>
+ <el-button size="small" type="primary" @click="addTask" style="float:right">娣诲姞浠诲姟</el-button>
+ </div>
+ <div id="taskArea" class="width-new-line task-manage-table">
+ <div
+ v-for="(row, Index) in TaskMange.list2"
+ :key="Index"
+ class="dic-border mb10 width-new-line"
+ >
+ <div class="flex-box" style="height:100%;">
+ <div class="task-name-google">
+ <div class="mask" v-if="!row.isSetting">
+ <el-tooltip
+ content="缂栬緫鍚嶇О"
+ transition="none"
+ placement="left"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont iconbianji1"
+ style="font-size:30px; left:14px; top:30px;"
+ @click="clickSet(row)"
+ ></i>
+ </el-tooltip>
+ <el-tooltip
+ content="鍒犻櫎浠诲姟"
+ transition="none"
+ placement="right"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont iconshanchu4"
+ style="font-size:30px; color:red; top:30px; left:28px;"
+ @click="clickDel(row, Index)"
+ ></i>
+ </el-tooltip>
+ <el-tooltip
+ :content="`${row.enable ? '鍏抽棴浠诲姟' : '寮�鍚换鍔�'}`"
+ placement="left"
+ popper-class="atooltip"
+ transition="none"
+ style="left: -45px; top: 65px;"
+ >
+ <el-switch
+ :active-value="true"
+ :inactive-value="false"
+ v-model="row.enable"
+ @change="updateTaskStatus(row)"
+ ></el-switch>
+ </el-tooltip>
+ <el-tooltip
+ content="淇敼鍥炬爣"
+ transition="none"
+ placement="right"
+ popper-class="atooltip"
+ >
+ <i class="iconfont icontupian1" style="font-size:12px; left:-20px; top:65px;"></i>
+ </el-tooltip>
+ </div>
+ <div class="list-choose-header flex-center">
+ <span class="iconfont iconrenwu" style="font-size:3rem;color:#fff;"></span>
+ </div>
+ <div class="task-name-div">
+ <span :title="row.name" v-if="!row.isSetting">{{ row.name }}</span>
+ <el-input
+ size="small"
+ v-model="row.name"
+ v-if="row.isSetting"
+ v-focus
+ :maxlength="15"
+ style="width:120px"
+ @blur="updateTaskName(row)"
+ ></el-input>
+ </div>
+ </div>
+
+ <div id="child" class="overflow-x">
+ <draggable
+ :id="row.id"
+ :list="row.child"
+ group="article"
+ filter=".mask"
+ class="dragAreaR flex-box"
+ @start="startRight"
+ @end="endLeft"
+ >
+ <div
+ v-for="(item, index) in row.child"
+ :key="index"
+ :title="item.sdk_name"
+ :class="
+ item.isSelect
+ ? 'list-choose-item alg-shadow'
+ : 'list-choose-item'
+ "
+ >
+ <div class="mask">
+ <el-tooltip
+ content="璁剧疆"
+ transition="none"
+ placement="top"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont iconshezhi"
+ style="font-size:15px; top:43px;"
+ @click="clickSetAlgo(row, item)"
+ ></i>
+ </el-tooltip>
+ <el-tooltip
+ content="鍒犻櫎绠楁硶"
+ transition="none"
+ placement="top"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont iconshanchu4"
+ style="font-size: 30px; color:red; left:12px;"
+ @click="clickDelSdk(row, item)"
+ ></i>
+ </el-tooltip>
+ </div>
+ <div class style="height:100%;padding: 20px 10px 10px 10px;">
+ <div class="flex-center" style>
+ <span
+ :class="`iconfont ${item.icon}`"
+ style="font-size:3rem;margin-left:5px;"
+ ></span>
+ </div>
+ <div
+ :class="item.isSelect?'select-color text-css':'task-name text-css'"
+ style
+ >{{ item.sdk_name }}</div>
+ </div>
+ </div>
+ <div style class="tc drag-info flex-center">
+ <div class="drag-info-text">
+ <span>鎷栧姩绠楁硶鍥炬爣鍒拌繖閲�</span>
+ </div>
+ </div>
+ </draggable>
+ </div>
+ </div>
+
+ <div class v-if="row.isShowSetAlgo">
+ <div class="b-top">
+ <div class="flex-box mt10">
+ <span class="alg-t ml10 mr10 fb">绠楁硶閰嶇疆</span>
+ </div>
+ <div style="border: 1px solid #EBEBEB;"></div>
+ <div>
+ <div class="p5">
+ <div v-for="(temp, index) in TaskMange.argsList" :key="index" class="p5 ml50">
+ <el-row :gutter="2">
+ <el-col :span="4">
+ <el-select
+ v-model="temp.value1"
+ placeholder="璇烽�夋嫨"
+ width="200px"
+ disabled
+ @change="selectChange($event, 'options1', temp)"
+ >
+ <el-option
+ v-for="item in temp.options1"
+ :key="item.id"
+ :label="item.name"
+ :value="item.value"
+ ></el-option>
+ </el-select>
+ </el-col>
+ <el-col :span="4">
+ <el-select
+ v-model="temp.value2"
+ placeholder="璇烽�夋嫨"
+ @change="selectChange($event, 'options2', temp)"
+ >
+ <el-option
+ v-for="item in temp.options2"
+ :key="item.id"
+ :label="item.name"
+ :value="item.value"
+ ></el-option>
+ </el-select>
+ </el-col>
+ <el-col :span="12">
+ <div v-if="temp.value2 === 'is'">
+ <el-select
+ v-model="temp.value3"
+ placeholder="璇烽�夋嫨"
+ @change="selectChange($event, 'options3', temp)"
+ >
+ <el-option
+ v-for="item in temp.options3"
+ :key="item.id"
+ :label="item.name"
+ :value="item.value"
+ ></el-option>
+ </el-select>
+ </div>
+ <div v-else class="flex-row-left">
+ <div>
+ <el-input
+ v-model="temp.value3"
+ placeholder="璇疯緭鍏�"
+ @blur="valiNum(temp.value3)"
+ ></el-input>
+ </div>
+ <div v-if="temp.unit" class="unit-class">
+ <span>(鍗曚綅锛歿{ temp.unit }})</span>
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+ </div>
+ </div>
+ </div>
+ <div class="flex-row-right" style="margin: 0px 25px 5px 0px;">
+ <a
+ style="font-family: PingFangSC-Medium;line-height: 32px;
+ font-size: 13px;text-decoration:underline;
+ color: #3D68E1;margin-right: 28px;"
+ @click="getDefault"
+ >鎭㈠榛樿鍊�</a>
+ <el-button type="info" size="small" class="mb10" @click="cancle(row)">鍙栨秷</el-button>
+ <el-button type="primary" size="small" class="mr50 mb10" @click="save">淇濆瓨</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>-->
+ </div>
+ <!-- 涓�鑸敤鎴峰彲瑙� -->
+ <div class="common" v-if="!isSuperUser">
+ <!-- 绠楁硶绠$悊 -->
+ <!-- <div class="right-box" style="width:84%;margin:auto 8%">
+ <div class="title">
+ <label>绠楁硶绠$悊</label>
+ <el-button
+ size="small"
+ type="primary"
+ @click="addTask"
+ style="float:right"
+ v-show="isSuperUser"
+ >娣诲姞浠诲姟</el-button>
+ </div>
+ <div id="taskArea" class="width-new-line task-manage-table">
+ <div
+ v-for="(row, Index) in TaskMange.list2"
+ :key="Index"
+ class="dic-border mb10 width-new-line"
+ >
+ <div class="flex-box" style="height:100%;">
+ <div class="task-name-google">
+ <div class="mask" v-if="row.isSetting">
+ <el-tooltip
+ content="缂栬緫鍚嶇О"
+ transition="none"
+ placement="left"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont iconbianji1"
+ style="font-size:30px; left:14px; top:30px;"
+ @click="clickSet(row)"
+ ></i>
+ </el-tooltip>
+ <el-tooltip
+ content="鍒犻櫎浠诲姟"
+ transition="none"
+ placement="right"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont iconshanchu4"
+ style="font-size:30px; color:red; top:30px; left:28px;"
+ @click="clickDel(row, Index)"
+ ></i>
+ </el-tooltip>
+ <el-tooltip
+ :content="`${row.enable ? '鍏抽棴浠诲姟' : '寮�鍚换鍔�'}`"
+ placement="left"
+ popper-class="atooltip"
+ transition="none"
+ style="left: -45px; top: 65px;"
+ >
+ <el-switch
+ :active-value="true"
+ :inactive-value="false"
+ v-model="row.enable"
+ @change="updateTaskStatus(row)"
+ ></el-switch>
+ </el-tooltip>
+ <el-tooltip
+ content="淇敼鍥炬爣"
+ transition="none"
+ placement="right"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont icontupian1"
+ style="font-size:12px; left:-20px; top:65px;"
+ ></i>
+ </el-tooltip>
+ </div>
+ <div class="list-choose-header flex-center">
+ <span class="iconfont iconrenwu" style="font-size:3rem;color:#fff;"></span>
+ </div>
+ <div class="task-name-div">
+ <span :title="row.name" v-if="!row.isSetting">{{ row.name }}</span>
+ <el-input
+ size="small"
+ v-model="row.name"
+ v-if="row.isSetting"
+ v-focus
+ :maxlength="15"
+ style="width:120px"
+ @blur="updateTaskName(row)"
+ ></el-input>
+ </div>
+ </div>
+
+ <div id="child" class="overflow-x">
+ <div
+ :id="row.id"
+ :list="row.child"
+ group="article"
+ filter=".child"
+ class="dragAreaR flex-box"
+ @start="startRight"
+ @end="endLeft"
+ >
+ <div
+ v-for="(item, index) in row.child"
+ :key="index"
+ :title="item.sdk_name"
+ :class="
+ item.isSelect
+ ? 'list-choose-item alg-shadow'
+ : 'list-choose-item'
+ "
+ >
+ <div class="mask">
+ <el-tooltip
+ content="璁剧疆"
+ transition="none"
+ placement="top"
+ popper-class="atooltip"
+ >
+ <i
+ class="iconfont iconshezhi"
+ style="font-size:15px; top:43px;"
+ @click="clickSetAlgo(row, item)"
+ ></i>
+ </el-tooltip>
+ <el-tooltip
+ content="鍒犻櫎绠楁硶"
+ transition="none"
+ placement="top"
+ popper-class="atooltip"
+ v-show="isSuperUser"
+ >
+ <i
+ class="iconfont iconshanchu4"
+ style="font-size: 30px; color:red; left:12px;"
+ @click="clickDelSdk(row, item)"
+ ></i>
+ </el-tooltip>
+ </div>
+ <div class style="height:100%;padding: 20px 10px 10px 10px;">
+ <div class="flex-center" style>
+ <span
+ :class="`iconfont ${item.icon}`"
+ style="font-size:3rem;margin-left:5px;"
+ ></span>
+ </div>
+ <div
+ :class="item.isSelect?'select-color text-css':'task-name text-css'"
+ style
+ >{{ item.sdk_name }}</div>
+ </div>
+ </div>
+ <div style class="tc drag-info flex-center" v-show="isSuperUser">
+ <div class="drag-info-text">
+ <span>鎷栧姩绠楁硶鍥炬爣鍒拌繖閲�</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class v-if="row.isShowSetAlgo">
+ <div class="b-top">
+ <div class="flex-box mt10">
+ <span class="alg-t ml10 mr10 fb">绠楁硶閰嶇疆</span>
+ </div>
+ <div style="border: 1px solid #EBEBEB;"></div>
+ <div>
+ <div class="p5">
+ <div
+ v-for="(temp, index) in TaskMange.argsList"
+ :key="index"
+ class="p5 ml50"
+ >
+ <el-row :gutter="2">
+ <el-col :span="4">
+ <el-select
+ v-model="temp.value1"
+ placeholder="璇烽�夋嫨"
+ width="200px"
+ disabled
+ @change="selectChange($event, 'options1', temp)"
+ >
+ <el-option
+ v-for="item in temp.options1"
+ :key="item.id"
+ :label="item.name"
+ :value="item.value"
+ ></el-option>
+ </el-select>
+ </el-col>
+ <el-col :span="4">
+ <el-select
+ v-model="temp.value2"
+ placeholder="璇烽�夋嫨"
+ disabled
+ @change="selectChange($event, 'options2', temp)"
+ >
+ <el-option
+ v-for="item in temp.options2"
+ :key="item.id"
+ :label="item.name"
+ :value="item.value"
+ ></el-option>
+ </el-select>
+ </el-col>
+ <el-col :span="12">
+ <div v-if="temp.value2 === 'is'">
+ <el-select
+ v-model="temp.value3"
+ placeholder="璇烽�夋嫨"
+ @change="selectChange($event, 'options3', temp)"
+ >
+ <el-option
+ v-for="item in temp.options3"
+ :key="item.id"
+ :label="item.name"
+ :value="item.value"
+ ></el-option>
+ </el-select>
+ </div>
+ <div v-else class="flex-row-left">
+ <div>
+ <el-input
+ v-model="temp.value3"
+ placeholder="璇疯緭鍏�"
+ :disabled="temp.value1 !== 'score'"
+ @blur="valiNum(temp.value3)"
+ ></el-input>
+ </div>
+ <div v-if="temp.unit" class="unit-class">
+ <span>(鍗曚綅锛歿{ temp.unit }})</span>
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+ </div>
+ </div>
+ </div>
+ <div class="flex-row-right" style="margin: 0px 25px 5px 0px;">
+ <a
+ style="font-family: PingFangSC-Medium;line-height: 32px;
+ font-size: 13px;text-decoration:underline;
+ color: #3D68E1;margin-right: 28px;"
+ @click="getDefault"
+ v-show="isSuperUser"
+ >鎭㈠榛樿鍊�</a>
+ <el-button type="info" size="small" class="mb10" @click="cancle(row)">鍙栨秷</el-button>
+ <el-button type="primary" size="small" class="mr50 mb10" @click="save">淇濆瓨</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div> -->
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+<script>
+
+import {
+ findAllSdk,
+ findAll,
+ addTaskSdk,
+ delTaskSdk,
+ deleteTask,
+ updateTaskStatus,
+ updateTaskName,
+ getSdkArgs,
+ saveTaskSdkRule,
+ addTask,
+ getRulesByTaskSdk,
+ deleteTaskSdkRule,
+ findByType,
+ getTagList,
+ downloadSdk,
+ installSdk
+} from "./api";
+import FileUploader from "@/components/subComponents/FileUpload/index";
+
+export default {
+ name: "algorithmManage",
+ props: {},
+ components: {
+ FileUploader
+ },
+
+ data() {
+ return {
+ activeName: "myAlgorithm",
+ patchUpdateStatus: "",
+ dragging: false,
+ list1: [
+ {
+ sdk_name: "浜鸿劯鎻愬彇"
+ }
+ ],
+ list2: [
+ {
+ id: "001",
+ name: "浠诲姟1",
+ child: [
+ {
+ id: "1",
+ sdk_name: "浜鸿劯妫�娴�",
+ isSelect: false
+ },
+ {
+ id: "2",
+ sdk_name: "浜鸿劯瀵规瘮",
+ isSelect: false
+ }
+ ],
+ isSetting: false,
+ isShowSetAlgo: false
+ }
+ ],
+ argsList: [],
+ baseObject: {
+ id: "",
+ algoId: "",
+ options1: [],
+ options2: [],
+ options3: [],
+ value1: "",
+ value2: "",
+ value3: "",
+ unit: ""
+ },
+ currentAlgoId: "",
+ currentTaskId: "",
+ isSuperUser: false,
+ downloadItem: "",
+ downloading: false,
+ sceneDialogVisible: false,
+ dialogTitle: '',
+ direction: "rtl",
+ actDrawerShow: false,
+ actStep: 0,
+ activeCode: "",
+ sceneTemplates: [],
+ appSceneForm: {
+ id: "",
+ name: "",
+ desc: "",
+ rules: "",
+ txt: ""
+ },
+ sceneSdks: [],
+ sceneRuleList: "",
+ isInstall: false,
+ installPercentage: 0
+ }
+ },
+ methods: {},
+ mounted() {}
+};
+</script>
+<style lang="scss">
+.s-task-manage {
+ width: 100% !important;
+ height: 100%;
+
+ box-sizing: border-box;
+ background-color: rgb(233, 235, 242);
+ padding: 10px;
+ text-align: left;
+ // background-color: #f2f6fc;
+ .s-video-manage-breadcrumb {
+ height: 5%;
+ -webkit-box-sizing: border-box;
+ border: 1px solid #e4e7ed;
+ background-color: rgb(255, 255, 255);
+ -webkit-box-shadow: #e4e7ed 0px 0px 9px inset;
+ box-shadow: #e4e7ed 0px 0px 9px inset;
+ border-radius: 5px;
+ }
+ .el-tabs {
+ height: calc(100% - 50px);
+ // margin-top: 5px !important;
+ }
+ .el-tabs--border-card > .el-tabs__header {
+ border: none;
+ }
+ .el-tabs__item.is-top {
+ height: 50px;
+ padding: 5px 50px !important;
+ font-size: 15px;
+ border: none !important;
+ }
+ .el-tabs__item.is-top.is-active {
+ font-weight: bold;
+ }
+ .el-tabs__content {
+ width: 100%;
+ height: calc(100% - 34px);
+ box-sizing: border-box;
+ }
+ .el-tab-pane {
+ width: 100%;
+ height: 100%;
+ }
+}
+.el-breadcrumb__inner {
+ font-weight: bold;
+ color: #606266;
+ cursor: pointer;
+}
+</style>
diff --git a/src/pages/algorithmManage/index/api.ts b/src/pages/algorithmManage/index/api.ts
new file mode 100644
index 0000000..64ecdad
--- /dev/null
+++ b/src/pages/algorithmManage/index/api.ts
@@ -0,0 +1,145 @@
+import request from '@/scripts/httpRequest'
+import qs from "qs";
+
+// 鏌ヨ鎵�鏈夌畻娉�
+export const findAllSdk = (query: any) => {
+ return request({
+ url: "/data/api-v/sdk/findAllSdk",
+ method: "get",
+ params: query
+ });
+};
+
+// 鏌ユ壘鎵�鏈変换鍔★紝鍖呭惈浠诲姟淇℃伅鍜屽搴旂殑绠楁硶淇℃伅
+export const findAll = (query: any) => {
+ return request({
+ url: "/data/api-v/task/findAll",
+ method: "get",
+ params: query
+ });
+};
+
+// 缁欎换鍔℃坊鍔犵畻娉�
+export const addTaskSdk = (query: any) => {
+ return request({
+ url: "/data/api-v/task/addTaskSdk",
+ method: "post",
+ data: query
+ })
+}
+
+// 缁欎换鍔″垹闄ょ畻娉�
+export const delTaskSdk = (query: any) => {
+ return request({
+ url: "/data/api-v/task/delTaskSdk",
+ method: 'get',
+ params: query
+ })
+}
+
+// 鍒犻櫎浠诲姟
+export const deleteTask = (query: any) => {
+ return request({
+ url: '/data/api-v/task/delete',
+ method: 'get',
+ params: query
+ })
+}
+
+// 鏇存柊浠诲姟鐘舵��
+export const updateTaskStatus = (query: any) => {
+ return request({
+ url: '/data/api-v/task/updateTaskStatus',
+ method: 'post',
+ data: query
+ })
+}
+
+// 鏇存柊浠诲姟鍚嶇О
+export const updateTaskName = (query: any) => {
+ return request({
+ url: '/data/api-v/task/updateTaskName',
+ method: 'post',
+ data: qs.stringify(query)
+ })
+}
+
+// 鑾峰彇绠楁硶鍙傛暟
+export const getSdkArgs = (query: any) => {
+ return request({
+ url: '/data/api-v/sdkArg/getSdkArgs',
+ method: 'get',
+ params: query
+ })
+}
+
+// 绠楁硶鍙傛暟淇濆瓨
+export const saveTaskSdkRule = (query: any) => {
+ return request({
+ url: '/data/api-v/task/saveTaskSdkRule',
+ method: 'post',
+ data: query
+ })
+}
+
+// 娣诲姞浠诲姟
+export const addTask = (query: any) => {
+ return request({
+ url: '/data/api-v/task/addTask',
+ method: 'post',
+ data: query
+ })
+}
+
+// 鏌ヨ绠楁硶瑙勫垯
+export const getRulesByTaskSdk = (query: any) => {
+ return request({
+ url: '/data/api-v/task/getRulesByTaskSdk',
+ method: 'get',
+ params: query
+ })
+}
+
+// 鎭㈠榛樿
+export const deleteTaskSdkRule = (query: any) => {
+ return request({
+ url: '/data/api-v/task/deleteTaskSdkRule',
+ method: 'post',
+ data: qs.stringify(query)
+ })
+}
+
+// 鏍规嵁绫诲瀷鏌ユ壘瀛楀吀
+export const findByType = (query: any) => {
+ return request({
+ url: '/data/api-v/dictionary/findByType',
+ method: "get",
+ params: query
+ })
+}
+
+// 鏌ヨ妫�绱㈡爣绛�
+export const getTagList = (query: any) => {
+ return request({
+ url: '/data/api-v/es/tagList',
+ method: 'post',
+ data: query
+ })
+}
+
+export const downloadSdk = (query: any) => {
+ return request({
+ url: '/data/api-v/sdk/sdkDownload',
+ method: 'get',
+ params: query
+ })
+}
+
+//瀹夎宸蹭笂浼犵殑绠楁硶鎺ュ彛
+export const installSdk = (file: any) => {
+ return request({
+ url: '/data/api-v/sdk/install',
+ method: 'post',
+ params: file
+ })
+}
\ No newline at end of file
diff --git a/src/pages/algorithmManage/index/main.ts b/src/pages/algorithmManage/index/main.ts
new file mode 100644
index 0000000..264f7e4
--- /dev/null
+++ b/src/pages/algorithmManage/index/main.ts
@@ -0,0 +1,11 @@
+import Vue from 'vue'
+import ElementUI from 'element-ui'
+import 'element-ui/lib/theme-chalk/index.css'
+import App from './App.vue'
+
+Vue.use(ElementUI)
+
+new Vue({
+ el: '#app',
+ render: h => h(App)
+})
diff --git a/src/pages/desktop/index/App.vue b/src/pages/desktop/index/App.vue
index b58209a..aaa21d5 100644
--- a/src/pages/desktop/index/App.vue
+++ b/src/pages/desktop/index/App.vue
@@ -3,6 +3,7 @@
<tools></tools>
<preference></preference>
<desktop></desktop>
+ <tools-entry></tools-entry>
<dock ref="dock_model"></dock>
<notice-tip ref="notice_tip_model"></notice-tip>
<notification-center></notification-center>
@@ -16,12 +17,13 @@
import NotificationCenter from './components/NotificationCenter';
import NoticeTip from './components/NoticeTip';
import Tools from './components/Tools';
+import ToolsEntry from './components/ToolsEntry';
import axios from 'axios'
export default {
name: 'app',
components: {
- Desktop, Dock, Preference, NotificationCenter, NoticeTip, Tools
+ Desktop, Dock, Preference, NotificationCenter, NoticeTip, Tools, ToolsEntry
},
mounted() {
document.getElementById('app').style.backgroundImage = process.env.VUE_APP_MAIN_URL;
@@ -113,6 +115,14 @@
width: 100%;
height: 100%;
background-size: 100% 100%;
- background-image: url("../../../assets/img/desktop/main.jpg");
+ background-image: url("../../../assets/img/desktop/desktop.png");
+ background-attachment: fixed;
+}
+
+.clearFix:after{
+ content: '';
+ display: block;
+ height: 0;
+ clear: both;
}
</style>
diff --git a/src/pages/desktop/index/components/Dock.vue b/src/pages/desktop/index/components/Dock.vue
index 4a6bcd3..68e3d4a 100644
--- a/src/pages/desktop/index/components/Dock.vue
+++ b/src/pages/desktop/index/components/Dock.vue
@@ -10,10 +10,10 @@
<span>{{dock.alt}}</span>
<img class="dock-item" :src="dock.src" :alt="dock.alt" />
</a>
- <img v-show="dock.isOpen" class="dock-item-dot" src="images/circle.png" />
+ <img v-show="dock.isOpen" class="dock-item-dot" :src="`${publicPath}images/circle.png`" />
</div>
<a class="dock-item-split">
- <img src="images/split.jpg" alt="split" />
+ <img :src="`${publicPath}images/split.jpg`" alt="split" />
</a>
<div v-for="dock in this.$store.state.desktop.minDocks" :key="dock.id" class="dock-item-wrap">
<a @click="dockClick(dock)">
@@ -24,7 +24,7 @@
<div class="dock-item-wrap">
<a>
<span>trash</span>
- <img class="dock-item" src="images/trash.png" alt="trash" />
+ <img class="dock-item" :src="`${publicPath}images/trash.png`" alt="trash" />
</a>
</div>
</div>
@@ -35,6 +35,14 @@
export default {
name: "Dock",
+ data(){
+ return {
+ publicPath: process.env.BASE_URL
+ }
+ },
+ mounted(){
+ console.log(this.publicPath)
+ },
methods: {
getOffsetTop: function (el) {
if (el.offsetParent == null) {
diff --git a/src/pages/desktop/index/components/Tools.vue b/src/pages/desktop/index/components/Tools.vue
index ea2a2b0..385e1d2 100644
--- a/src/pages/desktop/index/components/Tools.vue
+++ b/src/pages/desktop/index/components/Tools.vue
@@ -1,36 +1,53 @@
<template>
<div class="tools">
- <div class="tools-left">
- <div
- :class="['tools-icon', {clicked:this.$store.state.desktop.preferenceVisiable}]"
- @click="togglePreference()"
- >
- <span class="fa fa-apple"></span>
+ <div class="center">
+ <div class="tools-left">
+ <div
+ :class="['tools-icon', {clicked:this.$store.state.desktop.preferenceVisiable}]"
+ @click="togglePreference()"
+ >
+ <img class="system" :src="`${publicPath}images/header-icon/system.png`" />
+ <!-- <span class="fa fa-apple"></span> -->
+ </div>
+ <div class="tools-icon" @click="openSafari()">
+ <!-- <span class="fa fa-safari"></span> -->
+ <img class="smart-ai" :src="`${publicPath}images/header-icon/SmartAI.png`" alt="">
+ </div>
</div>
- <div class="tools-icon" @click="openSafari()">
- <span class="fa fa-safari"></span>
- </div>
- </div>
- <div class="tools-middle"></div>
- <div class="tools-right">
- <div class="tools-icon">
- <span class="fa fa-battery-full"></span>
- </div>
- <timer></timer>
- <div class="tools-icon tools-notification-center" @click="notificationCenterClick()">
- <span
- :class="['fa', {'fa-list-ul':notificationCenterNoMessage()}, {'fa-comment-o on-new-msg':!notificationCenterNoMessage()},{'fa-commenting-o':notificationCenterMessageFlicker()}]"
- ></span>
- </div>
- <div class="tools-icon tools-show-desktop">
- <span> </span>
+ <div class="tools-middle"></div>
+ <div class="tools-right">
+ <div class="tools-icon">
+ <!-- <span class="fa fa-battery-full"></span> -->
+ <img :src="`${publicPath}images/header-icon/search.png`" alt="">
+ </div>
+ <div class="tools-icon">
+ <!-- <span class="fa fa-battery-full"></span> -->
+ <img :src="`${publicPath}images/header-icon/help.png`" alt="">
+ </div>
+ <div class="tools-icon">
+ <!-- <span class="fa fa-battery-full"></span> -->
+ <img :src="`${publicPath}images/header-icon/notice.png`" alt="">
+ </div>
+ <div class="tools-icon">
+ <!-- <span class="fa fa-battery-full"></span> -->
+ <img :src="`${publicPath}images/header-icon/user.png`" alt="">
+ </div>
+ <!-- <timer></timer> -->
+ <div class="tools-icon tools-notification-center" @click="notificationCenterClick()">
+ <span
+ :class="['fa', {'fa-list-ul':notificationCenterNoMessage()}, {'fa-comment-o on-new-msg':!notificationCenterNoMessage()},{'fa-commenting-o':notificationCenterMessageFlicker()}]"
+ ></span>
+ </div>
+ <div class="tools-icon tools-show-desktop">
+ <span> </span>
+ </div>
</div>
</div>
</div>
</template>
<script>
-import Timer from './Timer';
+import Timer from "./Timer";
export default {
name: "Tools",
@@ -39,40 +56,47 @@
},
data() {
return {
+ publicPath: process.env.BASE_URL,
notificationCenterVisible: false,
- notificationCenterMessageCount: 0,
- }
+ notificationCenterMessageCount: 0
+ };
},
created() {
let _that = this;
if (window.toolIntervalArr) {
window.toolIntervalArr.forEach(item => clearInterval(item));
}
- window.toolIntervalArr = [setInterval(function () {
- _that.notificationCenterMessageCount += 1;
- }, 600)];
+ window.toolIntervalArr = [
+ setInterval(function() {
+ _that.notificationCenterMessageCount += 1;
+ }, 600)
+ ];
},
methods: {
- notificationCenterClick: function () {
+ notificationCenterClick: function() {
this.notificationCenterVisible = !this.notificationCenterVisible;
- this.$store.commit('desktop/changeNotificationCenterVisible',
- this.notificationCenterVisible);
+ this.$store.commit(
+ "desktop/changeNotificationCenterVisible",
+ this.notificationCenterVisible
+ );
},
- notificationCenterNoMessage: function () {
+ notificationCenterNoMessage: function() {
return this.$store.state.desktop.messageNotices.length === 0;
},
- notificationCenterMessageFlicker: function () {
- return ((this.notificationCenterMessageCount % 2) === 0)
- && !this.notificationCenterNoMessage();
+ notificationCenterMessageFlicker: function() {
+ return (
+ this.notificationCenterMessageCount % 2 === 0 &&
+ !this.notificationCenterNoMessage()
+ );
},
- openSafari: function () {
+ openSafari: function() {
this.$store.commit("desktop/openSafari");
},
- togglePreference: function () {
+ togglePreference: function() {
this.$store.commit("desktop/togglePreference");
}
}
-}
+};
</script>
<style scoped>
@@ -80,31 +104,39 @@
width: 100%;
position: fixed;
top: 0;
- height: 30px;
- line-height: 30px;
- background-color: rgba(15, 15, 0, 0.4);
+ height: 40px;
+ line-height: 40px;
+ background-color: #d9e5f1;
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
z-index: 120;
- color: #fff;
+ color: #000;
}
-
+.tools .center {
+ width: 1300px;
+ height: 40px;
+ margin: auto;
+}
.tools .tools-left {
width: 200px;
height: 100%;
float: left;
margin-left: 8px;
+
}
.tools-icon {
text-align: center;
- width: 30px;
height: 100%;
display: inline-block;
+ vertical-align: top;
+ line-height: 56px;
+ margin-right: 28px;
}
.tools .tools-icon:hover,
.tools .tools-icon.clicked {
color: white;
- background-color: rgba(49, 156, 241, 0.71);
+ background-color: #98aabe;
cursor: pointer;
}
diff --git a/src/pages/desktop/index/components/ToolsEntry.vue b/src/pages/desktop/index/components/ToolsEntry.vue
new file mode 100644
index 0000000..adbba7c
--- /dev/null
+++ b/src/pages/desktop/index/components/ToolsEntry.vue
@@ -0,0 +1,95 @@
+<template>
+ <div class="tools-entry">
+ <div class="entry-wrap">
+ <div class="app-list clearFix">
+ <div class="app" v-for="(item,index) in applist" :key="index">
+ <div class="wrap">
+ <div class="app-icon">
+ <img :src="item.src" alt="">
+ </div>
+ <div class="app-name">{{item.name}}</div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script>
+export default {
+ name:'toolsEntry',
+ data(){
+ return {
+ publicPath: process.env.BASE_URL,
+ applist:[
+ {src: `/images/app-mid/camera-access.png`, name:'鎽勫儚鏈烘帴鍏�'},
+ {src: `/images/app-mid/datastack-config.png`, name:'鏁版嵁鏍堥厤缃�'},
+ {src: `/images/app-mid/DVR-access.png`, name:'纭洏褰曞儚鏈烘帴鍏�'},
+ {src: `/images/app-mid/data-push.png`, name:'鏁版嵁鎺ㄩ��'},
+ {src: `/images/app-mid/GB-config.png`, name:'GB28281閰嶇疆'},
+ {src: `/images/app-mid/scene-config.png`, name:'鍦烘櫙閰嶇疆'},
+ {src: `/images/app-mid/library.png`, name:'姣斿搴撶鐞�'},
+ {src: `/images/app-mid/poll.png`, name:'杞绠$悊'},
+ {src: `/images/app-mid/algorithm-manage.png`, name:'绠楁硶绠$悊'},
+ {src: `/images/app-mid/algorithm-store.png`, name:'绠楁硶鍟嗗煄'},
+ {src: `/images/app-mid/hashrate-manage.png`, name:'绠楀姏绠$悊'},
+ {src: `/images/app-mid/monitor.png`, name:'瀹炴椂鐩戞帶-鍦ㄧ嚎鎾斁'},
+ {src: `/images/app-mid/search.png`, name:'妫�绱�-缁熻鏌ヨ'},
+ {src: `/images/app-mid/360.png`, name:'鍏ㄦ櫙瑙嗛'},
+ {src: `/images/app-mid/log-manage.png`, name:'鏃ュ織绠$悊'},
+ {src: `/images/app-mid/device.png`, name:'璁惧绠$悊'},
+ {src: `/images/app-mid/settings.png`, name:'绯荤粺璁剧疆'},
+ {src: `/images/app-mid/vindicate.png`, name:'绯荤粺缁存姢'}
+ ]
+ }
+ }
+};
+</script>
+
+<style lang="scss">
+ .tools-entry{
+ //margin-top: 130px;
+ position: absolute;
+ top: 142px;
+ left: 50%;
+ transform: translateX(-50%);
+ .entry-wrap{
+ width: 1180px;
+ padding: 0 60px;
+ margin: 0 auto;
+ .app-list{
+ .app{
+ width: 16.6%;
+ margin-bottom: 54px;
+ float: left;
+ .wrap{
+ .app-icon{
+ text-align: center;
+ line-height: 110px;
+ width: 110px;
+ height: 110px;
+ margin: auto;
+ img{
+ vertical-align: middle;
+ margin-right: -3px;
+ }
+ }
+ .app-name{
+ padding-top: 10px;
+ text-align: center;
+ font: Bold 16px/16px Microsoft JhengHei;
+ color: #fff;
+ }
+ }
+
+ &:hover{
+ .app-icon{
+ background: rgba(0,0,0,.4);
+ }
+ }
+
+ }
+ }
+ }
+ }
+</style>
\ No newline at end of file
diff --git a/src/pages/desktop/index/mock/userData.json b/src/pages/desktop/index/mock/userData.json
index 1260c13..c5040fd 100644
--- a/src/pages/desktop/index/mock/userData.json
+++ b/src/pages/desktop/index/mock/userData.json
@@ -56,6 +56,13 @@
"alt": "鍒嗗竷寮忚皟搴�",
"type": "2",
"url": "http://www.justlive.vip/center/"
+ },
+ {
+ "id": "9",
+ "src": "../../images/gitee.png",
+ "alt": "绠楁硶绠$悊",
+ "type": "2",
+ "url": "/view/algorithmManage"
}
]
}
diff --git a/src/pages/index/app.vue b/src/pages/index/app.vue
index 26f9550..320b1ab 100644
--- a/src/pages/index/app.vue
+++ b/src/pages/index/app.vue
@@ -138,8 +138,9 @@
type: 'success',
message: '鐧诲綍鎴愬姛锛�'
})
- await this.getMenuList()
- this.$router.push('/Layout/Video')
+ // await this.getMenuList()
+ // this.$router.push('/Layout/Video')
+ location.assign("/view/desktop")
return json
} else {
this.$notify({
--
Gitblit v1.8.0