此篇代码在原插件基础进行了bug修改与滑动功能的新增
原插件地址
- HM-dragSorts.vue
- 组件使用
HM-dragSorts.vue
<template><view class=""><view class="HM-drag-sort" :style="{'height': ListHeight+'rpx','background-color': listBackgroundColor}"><!-- 拖拽中显示的行 --><view class="rowBox-shadow" id="shadowRowBox"><view class="hm-row-shadow move" id="shadowRow"><view class="modules"><!-- 内容 --><view class="row-content"><view class="row" :style="{'height': rowHeight+'rpx'}"><slot :hobby="shadowRow"></slot></view></view><!-- 拖拽图标 --><view class="drag-content"><view class="drag-icon" :style="{'height': rowHeight+'rpx'}"></view></view></view></view></view><!-- 拖拽列表 --><scroll-view class="color scroll-view" :id="'scrollView_'+guid" :scroll-y="true":style="{'height': ListHeight+'px'}" :scroll-top="scrollViewTop" @scroll="drag.scroll":scroll-with-animation="scrollAnimation"><view class="list"><view v-for="(row,index) in dragList" :key="row.HMDrag_id" class="rowBox ani" @click="goDetails(row)"><uni-swipe-action><!-- 注意,这里的style只有在行首次渲染出来才有效,后面拖动列表,style会被wxs修改,这里的style就不会再生效了 --><view class="hm-row":style="{'transform': 'translate3d(0,' + (row.HMDrag_sort-index)*100 + '%,-1px)'}":data-sort="row.HMDrag_sort" :data-id="row.HMDrag_id" :id="row.HMDrag_id"><uni-swipe-action-item><view class="modules"><!-- 内容 --><view class="row-content" ><view class="row" @tap="triggerClick(row.HMDrag_sort, row)":style="{'height': rowHeight+'rpx'}"><slot :hobby="row"></slot></view></view><view class="drag-content" :data-id="row.HMDrag_id"@touchstart="drag.touchstart" @touchmove="drag.touchmove"@touchend="drag.touchend"><view class="drag-icon" :style="{'height': rowHeight+'rpx'}"><!-- <text class="iconfont icon-drag"></text> --></view></view></view><template v-slot:right class="rgBox"><view class="rightBtn" ><view class="" @click.stop="editBtn(row)"><image src="@/static/index/edit.png" mode=""></image></view><view class="" @click.stop="delBtn(row)"><image src="@/static/index/delete.png" mode=""></image></view></view></template></uni-swipe-action-item></view></uni-swipe-action></view></view></scroll-view><!-- 数据跳板 --><view id="dataView" style="display: none !important;" :data-guid="guid" :prop="wxsDataStr":change:prop="drag.receiveData">触发wxs跳板,请勿删除</view><!-- #ifdef APP-VUE || H5 --><view style="display: none !important;" :prop="scrollCommand" :change:prop="renderjs.runCommand">触发renderjs跳板,请勿删除</view><!-- #endif --></view></view>
</template>
<script src="./drag.wxs" module="drag" lang="wxs"></script>
<script module="renderjs" lang="renderjs">// APP or H5端 renderjs 实现拖拽中的自动滚动列表export default {data() {return {e: null,ScrollView: null,}},methods: {runCommand(e) {if (e == null) {return}this.e = e;this.getScrollView(document.getElementById('scrollView_' + this.e.guid))window.cancelAnimationFrame(this.AnimationFrameID);this.AnimationFrameID = window.requestAnimationFrame(this.Animation);if (e.command == "stop") {window.cancelAnimationFrame(this.AnimationFrameID);return;}},Animation() {if (this.e.command == "stop") {window.cancelAnimationFrame(this.AnimationFrameID);return;}// 计算最大滚动高度let maxScrollTop = this.e.rowLength * this.e.rowHeight - this.e.ListHeight;if (this.e.command == "up") {this.ScrollView.scrollTop -= 3} else if (this.e.command == "down") {this.ScrollView.scrollTop += 3;}if (this.ScrollView.scrollTop < 0) {this.ScrollView.scrollTop = 0;window.cancelAnimationFrame(this.AnimationFrameID);}if (this.ScrollView.scrollTop > maxScrollTop) {this.ScrollView.scrollTop = maxScrollTop;window.cancelAnimationFrame(this.AnimationFrameID);}this.AnimationFrameID = window.requestAnimationFrame(this.Animation);},getScrollView(DOM) {if (this.ScrollView != null) {return this.ScrollView;}let styleStr = DOM.getAttribute('style');if (DOM.className == 'uni-scroll-view' && styleStr != null && styleStr.indexOf('overflow') > -1 && styleStr.indexOf('auto') > -1) {this.ScrollView = DOM;return DOM;} else {this.getScrollView(DOM.firstChild);}}}}
</script>
<script>/** * 拖拽排序组件 HM-dragSort* @description 拖拽排序组件 HM-dragSort* @property {ObjectArray} list = [] 列表数据,数据格式[{"name": "花呗","icon": "/static/img/1.png",}]* @property {Boolean} feedbackGenerator = [true|false] 是否拖动触感反馈 * @property {Boolean} longTouch = [true|false] 是否长按拖动 * @property {Boolean} autoScroll = [true|false] 是否拖拽至边缘自动滚动列表 * @property {Number} longTouchTime = [] 选填,触发长按时长,单位:ms,默认350ms,不支持微信小程序 * @property {Number} listHeight = 0 选填,可拖动列表整体的高度,单位:px,默认等于窗口高度 * @property {Number} rowHeight = 44 选填,行高,单位:px,默认44px* @property {String} listBackgroundColor 选填,列表底色,注意是列表的底色,不是行的底色,默认#FFFFFF* @event {Function} change 行位置发生改变时触发事件 返回值:{index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据'} * @event {Function} confirm 拖拽结束且行位置发生了改变触发事件 返回值:{index:'原始下标',moveTo:'被拖动到的下标',moveRow:'拖动行数据',list:'整个列表拖动后的数据'} */export default {name: 'HM-dragSort',data() {return {guid: "",isAppH5: true, //是否APPH5 无需手动配置shadowRow: {}, // 存放被拖拽行数据// 列表数据dragList: [],ListHeight: this.listHeight, // scroll-view列表高度// 控制滑动scrollViewTop: 0, // 滚动条位置scrollCommand: null, //传递renderjs数据isHoldTouch: false, //是否正在拖拽isScrolling: false, //是否正在滚动视图scrollAnimation: false, //滚动动画 在微信端开启scrollTimer: null, //定时器-控制滚动 微信小程序端使用 实现类似requestAnimationFrame效果wxsDataObj: [],wxsDataStr: "[]"}},// #ifdef VUE3emits: ['change', 'confirm'],// #endifprops: {//是否开启拖动震动反馈feedbackGenerator: {value: Boolean,default: true},// 是否开启长按拖动longTouch: {value: Boolean,default: false},autoScroll: {value: Boolean,default: true},longTouchTime: {value: Number,default: 300},// 列表数据list: {value: Array,default: []},// 行高度 默认44行高rowHeight: {value: Number,default: 44},// 组件高度 默认windowHeight满屏listHeight: {value: Number,default: 0},listBackgroundColor: {value: String,default: "#fff"}},watch: {longTouch(val) {// #ifdef VUE3if (!val) {console.error('vue3目前仅支持长按拖拽!');}// #endifthis.pushWxsData('longTouch', val);},longTouchTime(val) {this.pushWxsData('longTouchTime', val);},feedbackGenerator(val) {this.pushWxsData('feedbackGenerator', val);},autoScroll(val) {this.pushWxsData('autoScroll', val);},list: {handler(val) {this.initList(val); //数据变化重新初始化list},immediate: true,deep: true},listHeight: {handler(val) {this.ListHeight = val;this.pushWxsData('ListHeight', this.ListHeight);},immediate: true}},mounted() {this.guid = this.getGuid();const res = uni.getSystemInfoSync();// #ifdef MP-WEIXINlet state = this.compareVersion(res.hostVersion, '2.14.2');if (state < 0) {console.error('当前微信基础库:' + res.hostVersion + ',HM-dragSorts组件仅支持微信基础库2.14.2+,请切换基础库!');}this.scrollAnimation = true;this.isAppH5 = false;// #endifif (this.listHeight == 0) {this.ListHeight = res.windowHeight;// #ifdef VUE3// vue3 要减去导航栏和状态栏高度if (res.windowHeight == res.screenHeight) {this.ListHeight = res.windowHeight - 45 - res.statusBarHeight;}// #endif}this.pushWxsData('isAppH5', this.isAppH5);this.pushWxsData('ListHeight', this.ListHeight);this.pushWxsData('longTouch', this.longTouch);},methods: {getGuid() {function S4() {return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);}return (S4() + S4() + "_" + S4() + "_" + S4() + "_" + S4() + "_" + S4() + S4() + S4());},initList() {let tmpList = JSON.parse(JSON.stringify(this.list));for (let i = 0, len = tmpList.length; i < len; i++) {// 组件内赋予临时id和sortif (!tmpList[i].hasOwnProperty('HMDrag_id')) {tmpList[i].HMDrag_id = 'HMDragId_' + this.getGuid();}tmpList[i].HMDrag_sort = i;}if (this.dragList.length > 0) {setTimeout(() => {this.dragList.splice(0, this.dragList.length, ...tmpList);}, 50)} else {this.dragList = JSON.parse(JSON.stringify(tmpList));}this.pushWxsData('lastInitTime', (new Date()).valueOf());},loadShadowRow(e) {this.shadowRow = this.getMoveRow(e.rowSort);},//兼容微信小程序震动vibrate() {uni.vibrateShort()},// 控制自动滚动视图pageScroll(e) {// 滚动 up-上滚动 down-下滚动if (e.command == "up" || e.command == "down") {if (!this.isHoldTouch) {this.isHoldTouch = true;this.scrollViewTop = e.scrollTop;}if (this.isScrolling) {return;};this.isScrolling = true;if (this.isAppH5) {// APP端和H5端 执行renderjs的滚动e.ListHeight = this.ListHeight;e.rowHeight = this.rowHeight;e.rowLength = this.dragList.length;this.scrollCommand = e;return;}// 微信小程序执行以下逻辑this.scrollTimer != null && clearInterval(this.scrollTimer);let maxHeight = this.rowHeight * this.dragList.length + 1 - this.ListHeight;let runTick = true;// 逻辑层传递到视图层需要时间,可能会出现滚动不流畅现象this.scrollTimer = setInterval(() => {if (!runTick) {return;}this.runScroll(e.command, maxHeight);runTick = false;this.$nextTick(function() {runTick = true;})}, 16.6)}// 停止滚动if (e.command == "stop") {// #ifdef APP-PLUS || H5// 停止指定传递到renderjsthis.scrollCommand = e;// #endifthis.isScrolling && this.stopScroll();}},// 微信端的滚动runScroll(command, maxHeight) {if (command == "up") {this.scrollViewTop -= 5}if (command == "down") {this.scrollViewTop += 5;}if (this.scrollViewTop < 0) {this.scrollViewTop = 0;clearInterval(this.scrollTimer);}if (this.scrollViewTop > maxHeight) {this.scrollViewTop = maxHeight;clearInterval(this.scrollTimer);}},//停止滚动stopScroll() {this.scrollTimer != null && clearInterval(this.scrollTimer);this.isScrolling = false;this.scrollingtop = 0;},// getMoveRow(HMDrag_sort) {for (let i = 0, len = this.dragList.length; i < len; i++) {if (this.dragList[i].HMDrag_sort == HMDrag_sort) {return JSON.parse(JSON.stringify(this.dragList[i]));}}},// triggerClick(index, row) {let tmpRow = JSON.parse(JSON.stringify(row));// 清除临时id和sortdelete tmpRow.HMDrag_id;delete tmpRow.HMDrag_sort;this.$emit('onclick', {index: index,row: JSON.parse(JSON.stringify(tmpRow))});},change(e) {e.moveRow = this.getMoveRow(e.index);// 清除组件临时赋予的iddelete e.moveRow.HMDrag_id;delete e.moveRow.HMDrag_sort;this.$emit('change', e);},sort(e) {this.stopScroll();this.isHoldTouch = false;let moveRow = this.getMoveRow(e.index);// 检测清除临时id和sortdelete moveRow.HMDrag_id;delete moveRow.HMDrag_sort;let list = JSON.parse(JSON.stringify(this.dragList));let tmpList = [];for (let i = 0, len = list.length; i < len; i++) {// 检测清除临时id和sortdelete list[i].HMDrag_id;delete list[i].HMDrag_sort;let index = e.sortArray[i];this.dragList[i].HMDrag_sort = index;tmpList[index] = list[i];}// 触发组件confirm 并传递数据this.$emit('confirm', {list: tmpList,index: e.index,moveTo: e.offset,moveRow: moveRow});},getNowList() {let list = JSON.parse(JSON.stringify(this.dragList));let tmpList = [];for (let i = 0, len = list.length; i < len; i++) {let tmpSotr = list[i].HMDrag_sort;tmpList[tmpSotr] = list[i];// 检测清除临时id和sortdelete tmpList[tmpSotr].HMDrag_id;delete tmpList[tmpSotr].HMDrag_sort;}return tmpList;},splice() {let deleteIndex = arguments[0];let deleteLength = arguments[1];let len = arguments.length;let waitPushList = [];for (let i = 2; i < len; i++) {let newRow = arguments[i]newRow.HMDrag_id = 'HMDragId_' + this.getGuid();newRow.HMDrag_sort = deleteIndex + i - 2;waitPushList.push(newRow);}let minDeleteSort = deleteIndex;let maxDeleteSort = deleteLength > 0 ? deleteIndex + deleteLength - 1 : deleteIndex;let offsetSort = waitPushList.length - deleteLength;let deleteIndexArray = [];for (let i = this.dragList.length - 1; i >= 0; i--) {let row = this.dragList[i];let rowSort = row.HMDrag_sort;// 跳过if (rowSort < minDeleteSort) {continue;}// 删除if (deleteLength > 0 && rowSort >= minDeleteSort && rowSort <= maxDeleteSort) {this.dragList.splice(i, 1);continue;}if (offsetSort != 0 && rowSort >= maxDeleteSort) {let newSort = rowSort + offsetSort;this.dragList[i].HMDrag_sort = newSort;}}this.dragList.push(...waitPushList);this.pushNewSort();let list = JSON.parse(JSON.stringify(this.dragList));let tmpList = this.getNowList();return tmpList;},push() {let len = arguments.length;let waitPushList = [];let startSotr = this.dragList.length;for (let i = 0; i < len; i++) {let newRow = arguments[i]newRow.HMDrag_id = 'HMDragId_' + this.getGuid();newRow.HMDrag_sort = startSotr + i;waitPushList.push(newRow);}this.dragList.push(...waitPushList);this.pushNewSort();let tmpList = this.getNowList();return tmpList;},unshift() {let len = arguments.length;let waitPushList = [];for (let i = 0; i < len; i++) {let newRow = arguments[i]newRow.HMDrag_id = 'HMDragId_' + this.getGuid();newRow.HMDrag_sort = i;waitPushList.push(newRow);}for (let i = this.dragList.length - 1; i >= 0; i--) {let row = this.dragList[i];let rowSort = row.HMDrag_sort;let newSort = rowSort + len;this.dragList[i].HMDrag_sort = newSort;}this.dragList.push(...waitPushList);this.pushNewSort();let tmpList = this.getNowList();return tmpList;},pushNewSort() {let sortArray = [];for (let i = 0, len = this.dragList.length; i < len; i++) {sortArray.push(this.dragList[i].HMDrag_sort);}this.pushWxsData('sortArray', sortArray);this.pushWxsData('lastInitTime', (new Date()).valueOf());},pushWxsData(key = null, val = null) {this.wxsDataObj.splice(0, 8, ['guid', this.guid],['listLength', this.dragList.length],['ListHeight', this.ListHeight],['isAppH5', this.isAppH5],['longTouch', this.longTouch],['longTouchTime', this.longTouchTime],['feedbackGenerator', this.feedbackGenerator],['autoScroll', this.autoScroll]);let index = -1;let sotrArrayIndex = -1;for (let i = 0; i < this.wxsDataObj.length; i++) {if (this.wxsDataObj[i][0] == key) {index = i;break;}}if (index > -1) {this.wxsDataObj[index][1] = val;if (key == 'sortArray') {sotrArrayIndex = index;}} else {this.wxsDataObj.push([key, val]);if (key == 'sortArray') {sotrArrayIndex = this.wxsDataObj.length - 1;}}if (this.guid == "") {return;}this.wxsDataStr = JSON.stringify(this.wxsDataObj);},compareVersion(v1, v2) {v1 = v1.split('.')v2 = v2.split('.')const len = Math.max(v1.length, v2.length)while (v1.length < len) {v1.push('0')}while (v2.length < len) {v2.push('0')}for (let i = 0; i < len; i++) {const num1 = parseInt(v1[i])const num2 = parseInt(v2[i])if (num1 > num2) {return 1} else if (num1 < num2) {return -1}}return 0},//编辑按钮editBtn(row) {this.$emit('editBtn', row)},//删除按钮delBtn(row) {this.$emit('delBtn', row)},//获取详情goDetails(row){console.log(row);this.$emit('goDetails',row)}}}
</script><style lang="scss" scoped>//默认$row-background-color: #fff;$border-color :#c8c7cb;$shadow-color-moveing :rgba(0, 0, 0, 0.5);$drag-icon-color: #c7c7cb;$drag-icon-color-disabled: #e7e7eb;//Dark模式$Dark-row-background-color: #000;$Dark-border-color :#3d3d40;$Dark-shadow-color-moveing :rgba(0, 0, 0, 0.5);$Dark-drag-icon-color: #c7c7cb;$Dark-drag-icon-color-disabled: #e7e7eb;//字体图标 拖拽图标@font-face {font-family: "HM-DS-font";src: url('data:font/truetype;charset=utf-8;base64,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') format('truetype');}.iconfont {font-family: "HM-DS-font" !important;font-style: normal;&.icon-drag {&:before {content: "\e6e4";}}}// 定义颜色 start//默认颜色.color,.rowBox-shadow {.hm-row-shadow,.hm-row {.modules {.row-content {.row {border-bottom: solid 1rpx $border-color;background-color: $row-background-color;}}.drag-content {.drag-icon {border-bottom: solid 1rpx $border-color;background-color: $row-background-color;.iconfont {color: $drag-icon-color;}.disabled {color: $drag-icon-color-disabled;}}}}&.move {box-shadow: 0 1px 5px $shadow-color-moveing;}}}// 暗黑模式@media (prefers-color-scheme: dark) {//Dark模式.color .rowBox-shadow {&.scroll-view {border-bottom: 1rpx $Dark-border-color solid;border-top: 1rpx $Dark-border-color solid;}.hm-row-shadow,.hm-row {.modules {.row-content {.row {border-bottom: solid 1rpx $Dark-border-color;background-color: $Dark-row-background-color;}}.drag-content {.drag-icon {border-bottom: solid 1rpx $Dark-border-color;background-color: $Dark-row-background-color;.iconfont {color: $Dark-drag-icon-color;}.disabled {color: $Dark-drag-icon-color-disabled;}}}}&.move {box-shadow: 0 1px 5px $Dark-shadow-color-moveing;}}}}// 定义颜色 end .HM-drag-sort {display: flex;flex-direction: column;position: relative;overflow: hidden;.scroll-view {box-sizing: border-box;}.rowBox,.rowBox-shadow {width: 100%;.hm-row-shadow,.hm-row {// display: flex;// flex-direction: row;width: 100%;.modules {position: relative;width: 100%;display: flex;flex-direction: row;justify-content: space-between;box-sizing: border-box;.row-content {width: 100%;flex-shrink: 1;position: relative;.row {display: flex;align-items: center;padding-left: 0px;box-sizing: border-box;.icon {width: 30px;height: 30px;border-radius: 6px;margin-right: 13px;}.text {font-size: 13px;}}}.drag-content {flex-shrink: 0;position: absolute;width: 100%;.drag-icon {width: 0px;display: flex;justify-content: center;align-items: center;box-sizing: border-box;.iconfont {font-size: 22px;color: #c7c7cb;}}}}}.hm-row-shadow {&.move {opacity: 0.8;view {border-bottom-width: 0;}}}.hm-row {opacity: 1;&.hide {opacity: 0;}&.ani {transition: transform 0.2s;-webkit-transition: transform 0.2s;}}&:last-child {.hm-row {view {border-bottom-width: 0;}}}}.rowBox-shadow {position: absolute;z-index: 100;display: none;&.show {display: flex !important;}&.hide {display: none !important;}}.list {display: flex;flex-direction: column;// transform-style:preserve-3d;}}/deep/ .uni-swipe {overflow: visible;}.rightBtn {width: 280rpx;padding: 0 32rpx 0 24rpx;display: flex;justify-content: space-between;align-items: center;background-color: #F2F7FA;view {width: 100rpx;height: 100rpx;background: #DDE6F2;border-radius: 50%;display: flex;justify-content: center;align-items: center;}image {width: 40rpx;height: 40rpx;}}/deep/ .uni-scroll-view{overflow: visible!important;}
</style>
组件使用
<template><view class="view"><u-navbar leftText="录入最小维修单元" :fixed="true" :placeholder="true" @leftClick="backClick"></u-navbar><view class="head-border"></view><view class="content-box"><view class="item"><text class="left">设备名称</text><text class="right">{{info.name}}</text></view><view class="item"><text class="left">专业</text><text class="right" v-if="info.major">{{info.major.name}}</text></view><view class="item"><text class="left">站点</text><text class="right" v-if="info.station">{{info.station.name}}</text></view><view class="item"><text class="left">安装位置</text><text class="right">{{info.location}}</text></view><view class="item"><text class="left">地图点位</text><view class="marker" @click="getLocation"><image src="../../static/index/map-marker.png" mode=""></image><view class="jwd" v-if="info.map_point">{{info.map_point.point.x | capitalize}},{{info.map_point.point.y | capitalize}}</view><view v-else>获取位置</view></view></view><view class="item"><text class="left">二维码</text><image class="right" :src="info.qrcode" mode="" @click="openImg"></image></view></view><view class="miniunit"><view class="mini-title"><text>最小维修单元列表</text><view class="allBtn"><view class="title-btn" v-if="list.length>0" @click="jxAdd">继续添加</view><view class="title-btn" v-if="list.length>0" @click="imports">导入相似</view></view></view><view class="enter" v-if="list.length==0"><text>这里空空如也</text><view class="btns"><view class="lf" @click="imports">导入相似</view><view class="rg" @click="jxAdd">立即录入</view></view></view><view class="mini-list" v-else><HM-dragSorts :key="keyNumber" ref="dragSorts" :list="list" :autoScroll="true" :feedbackGenerator="true":listHeight="380*(list.length)" :longTouch="true" :rowHeight="380" @confirm="confirm"@editBtn="edit" @delBtn="deleteItem"><template slot-scope="hobby"><view class="card" @click="goDetails(hobby.hobby)"><view class="card-item nmBox"><text><text>编码:</text><text>{{hobby.hobby.unit_code}}</text></text><text class="number">× {{hobby.hobby.quantity}}</text></view><view class="card-item"><text>名称:</text><text v-if="hobby.hobby.repair_unit">{{hobby.hobby.repair_unit.name}}</text></view><view class="card-item"><text>产品规格:</text><textv-if="hobby.hobby.repair_unit">{{hobby.hobby.repair_unit.specification_model}}</text></view><view class="card-item"><text>品牌:</text><text v-if="hobby.hobby.repair_unit">{{hobby.hobby.repair_unit.reference_brand}}</text></view></view></template></HM-dragSorts></view></view><!-- 确认删除 --><uni-popup ref="popup" type="center"><view class="dialogBox"><image src="../../static/index/close.png" class="close" @click="off()" mode=""></image><view class="title"><text>确认删除</text></view><view class="contents"><text>确认删除吗?</text></view><view class="btnBox"><view class="off" @click="off">取消</view><view class="bd"></view><view class="queren" @click="confirmBtn">确定</view></view></view></uni-popup><PrintCode ref="PrintCode" :imgUrl="info.qrcode" :info="info" codeType="qr"></PrintCode></view>
</template><script>import {equipmentInfo,deviceQrcode,qrcodeInfo,unitList,unitDelete,orderUnit} from "@/api/material.js"export default {data() {return {id: '',info: {},list: [], //列表minId: "", //点击的最小维修单元idisShow:false,keyNumber:0};},filters: {capitalize(value) {if (!value) return '';value = Number(value).toFixed(2);return value}},onLoad(options) {if (options.code) {console.log(options.code);this.getDeviceQrcode(options.code)};if (options.id) {this.id = options.idthis.getDeviceInfo()}uni.$on('update', (data) => {console.log(data.id);this.getList(data.id)if (data.obj) {console.log(data.obj);this.$set(this.info, 'map_point', {point: {}});this.$set(this.info.map_point.point, 'x', data.obj.x);this.$set(this.info.map_point.point, 'y', data.obj.y);this.$set(this.info.map_point, 'fl_id', data.obj.flId);}})},methods: {confirm(e) {//排序后的序列console.log('=== confirm end ===', e.list);},openImg() {this.$refs.PrintCode.open()},//导入相似imports() {//存入当前设备uni.setStorageSync('current_equipment_id', this.info.id);uni.navigateTo({url: `/pages/importList/importList?major=${encodeURIComponent(JSON.stringify(this.info.major))}`})},off() {this.$refs.popup.close()},//确认confirmBtn() {unitDelete({id: this.minId}).then(res => {plus.nativeUI.toast("删除成功", {verticalAlign: 'top',});this.off()this.getList(this.info.id)})},getLocation() {let x = this.info.map_point?.point ? this.info.map_point.point.x : '';let y = this.info.map_point?.point ? this.info.map_point.point.y : '';let fl_id = this.info.map_point?.fl_id ? this.info.map_point.fl_id : ''; //楼层名称 uni.navigateTo({url: `/pages/map/map?x=${x}&y=${y}&fl_id=${fl_id}`})},async getDeviceInfo() {let res = await equipmentInfo({id: this.id});this.info = res.data;uni.setStorageSync('equipment_id', res.data.id)let res2 = await qrcodeInfo({id: res.data.id});this.$set(this.info, 'qrcode', res2.data.qrcode)this.getList(res.data.id)},//扫码过来async getDeviceQrcode(code) {let res = await deviceQrcode({encrypt: code});console.log(res.data);this.info = res.data;uni.setStorageSync('equipment_id', res.data.id)let res2 = await qrcodeInfo({id: res.data.id});this.$set(this.info, 'qrcode', res2.data.qrcode)this.getList(res.data.id)// let res3=await unitList({equipment_id:res.data.id})// console.log(res3);// this.list=res3.data;},//获取设备二维码getQrcodeInfo() {qrcodeInfo().then(res => {console.log(res);})},//获取列表 getList(id) {unitList({equipment_id: id}).then(res => {console.log(res);// this.isShow=false;setTimeout(()=>{this.keyNumber++;this.list = res.data;},100)})},//继续添加jxAdd() {// uni.setStorageSync('infoId',this.info.id);uni.navigateTo({url: `/pages/enteringMin/enteringMin?id=${this.info.id}`})},//跳转最小维修单元详情goDetails(item) {console.log(item);uni.navigateTo({url: `/pages/unitDetails/unitDetails?item=${encodeURIComponent(JSON.stringify(item))}&id=${this.info.id}`})},backClick() {uni.navigateBack(1)},//修改edit(item) {uni.navigateTo({url: `/pages/editUnitDetails/editUnitDetails?item=${encodeURIComponent(JSON.stringify(item))}&delta=${1}`})},//删除deleteItem(item) {console.log(item);this.minId = item.id;this.$refs.popup.open('center')}}}
</script><style lang="scss" scoped>.view {width: 100%;background: #fff;}.head-border {width: 100%;height: 24rpx;background: #F2F7FA;}.content-box {padding: 0 32rpx;}.item {display: flex;justify-content: space-between;padding: 40rpx 0;.left {font-family: PingFang SC, PingFang SC;font-weight: 400;font-size: 30rpx;color: #000000;}.right {font-family: PingFang SC, PingFang SC;font-weight: 400;font-size: 30rpx;color: #000000;}image {width: 222rpx;height: 222rpx;}}.mini-title {padding: 40rpx 32rpx;background: #F2F7FA;display: flex;justify-content: space-between;text {font-family: PingFang SC, PingFang SC;font-weight: 500;font-size: 30rpx;color: #000000;}.title-btn {width: 168rpx;height: 58rpx;line-height: 58rpx;text-align: center;border-radius: 58rpx 58rpx 58rpx 58rpx;border: 2rpx solid #224BAE;font-family: PingFang SC, PingFang SC;font-weight: 400;font-size: 28rpx;color: #224BAE;}}.enter {padding-top: 122rpx;padding-bottom: 60px;text-align: center;}// .enter-btn {// width: 300rpx;// margin-top: 56rpx;// }.btns {padding: 84rpx 70rpx 0;box-sizing: border-box;display: flex;justify-content: space-between;view {width: 288rpx;height: 88rpx;line-height: 88rpx;text-align: center;border-radius: 10rpx 10rpx 10rpx 10rpx;font-family: PingFang SC, PingFang SC;font-weight: 500;font-size: 30rpx;}.lf {background: #5D96F5;color: #FFFFFF;}.rg {border: 2rpx solid #224BAE;color: #224BAE;}}.marker {max-width: 350rpx;display: flex;align-items: center;word-wrap: break-word;image {width: 32rpx;height: 32rpx;margin-right: 16rpx;}.jwd {width: 228rpx;}view {font-family: PingFang SC, PingFang SC;font-weight: 400;font-size: 30rpx;color: #3263D9;}}.card {width: 100%;border-bottom: 20rpx solid #F2F7FA;padding: 0 32rpx 40rpx 32rpx;.card-item {margin-top: 40rpx;text {font-family: PingFang SC, PingFang SC;font-weight: 400;font-size: 30rpx;color: #000000;}}.nmBox {display: flex;justify-content: space-between;.number {color: #3263D9;}}}.mini-list {// padding-bottom: 154rpx;// .bottomBox {// position: fixed;// bottom: 0;// width: 100%;// background: #fff;// }.rightBtn {width: 280rpx;padding: 0 32rpx 0 24rpx;display: flex;justify-content: space-between;align-items: center;background-color: #F2F7FA;view {width: 100rpx;height: 100rpx;background: #DDE6F2;border-radius: 50%;display: flex;justify-content: center;align-items: center;}image {width: 40rpx;height: 40rpx;}}// .saveBtn {// width: 686rpx;// height: 88rpx;// line-height: 88rpx;// text-align: center;// background: linear-gradient(180deg, #649DF6 0%, #3068EE 100%);// border-radius: 10rpx 10rpx 10rpx 10rpx;// font-family: PingFang HK, PingFang HK;// font-weight: 500;// font-size: 30rpx;// color: #FFFFFF;// margin: 0 auto;// }.bord {width: 270rpx;height: 10rpx;background: #000000;border-radius: 20rpx 20rpx 20rpx 20rpx;margin: 0 auto;margin-top: 16rpx;margin-bottom: 16rpx;}}// 弹窗样式.dialogBox {width: 630rpx;height: 374rpx;background: #FFFFFF;border-radius: 16rpx 16rpx 16rpx 16rpx;position: relative;.close {width: 32rpx;height: 32rpx;position: absolute;right: 32rpx;top: 32rpx;}.title {padding-top: 44rpx;box-sizing: border-box;font-family: PingFang SC, PingFang SC;font-weight: 500;font-size: 30rpx;color: #000000;text-align: center;}.contents {font-weight: 400;font-size: 28rpx;color: #666666;margin-top: 60rpx;text-align: center;letter-spacing: 2rpx;}.btnBox {width: 100%;height: 100rpx;position: absolute;bottom: 0px;display: flex;border-top: 2rpx solid #F2F2F2;.bd {width: 2rpx;height: 98rpx;background-color: #F2F2F2;}.off,.queren {flex: 1;text-align: center;line-height: 98rpx;font-family: PingFang SC, PingFang SC;font-weight: 500;font-size: 30rpx;}.off {color: #000000;}.queren {color: #0F3389;}}}.allBtn {display: flex;view:first-child {margin-right: 20rpx;}}
</style>