联调app
This commit is contained in:
@@ -212,10 +212,30 @@ export const lineTree = (params) => {
|
||||
url: '/cs-device-boot/csLedger/lineTree',
|
||||
method: 'POST',
|
||||
data: {
|
||||
type:'engineering'
|
||||
type: 'engineering',
|
||||
},
|
||||
// header: {
|
||||
// 'Content-Type': 'application/json',
|
||||
// },
|
||||
})
|
||||
}
|
||||
// 查询工程
|
||||
export const queryEngineeringPage = (params) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/engineering/queryEngineeringPage',
|
||||
method: 'POST',
|
||||
data: params,
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
// 通过ndid查询出厂设备
|
||||
export const queryEquipmentByndid = (params) => {
|
||||
return request({
|
||||
url: '/cs-device-boot/EquipmentDelivery/queryEquipmentByndid',
|
||||
method: 'POST',
|
||||
data: params,
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function getModuleState(params) {
|
||||
}
|
||||
export function getBaseRealData(id) {
|
||||
return request({
|
||||
url: 'cs-harmonic-boot/realData/getBaseRealData?lineId='+id,
|
||||
url: '/cs-harmonic-boot/realData/getBaseRealData?lineId='+id,
|
||||
method: 'post',
|
||||
})
|
||||
}
|
||||
40
common/api/report.js
Normal file
40
common/api/report.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import request from '../js/request'
|
||||
|
||||
// 下载稳态报告
|
||||
export function downloadHarmonicReport(data) {
|
||||
return request({
|
||||
url: '/cs-report-boot/csAppReport/downloadHarmonicReport',
|
||||
method: 'post',
|
||||
data,
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
// 申请暂态报告
|
||||
export function applicationReport(data) {
|
||||
return request({
|
||||
url: '/cs-report-boot/csAppReport/applicationReport',
|
||||
method: 'post',
|
||||
data,
|
||||
header: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
// 生成暂态报告
|
||||
export function createEventReport(params) {
|
||||
return request({
|
||||
url: '/cs-report-boot/csAppReport/createEventReport',
|
||||
method: 'post',
|
||||
params,
|
||||
})
|
||||
}
|
||||
// 下载暂态报告
|
||||
export function downloadEventReport(params) {
|
||||
return request({
|
||||
url: '/cs-report-boot/csAppReport/downloadEventReport',
|
||||
method: 'post',
|
||||
params,
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
const debug = true // true 是连地服务端本地,false 是连接线上
|
||||
|
||||
const development = {
|
||||
domain: 'http://192.168.2.126:10215',
|
||||
domain: 'http://192.168.1.103:10215',
|
||||
}
|
||||
|
||||
const production = {
|
||||
|
||||
@@ -12,13 +12,20 @@
|
||||
<view class="uni-card__header" @click="jump(device)">
|
||||
<view class="uni-card__header-box">
|
||||
<view class="uni-card__header-avatar">
|
||||
<view class="event-icon">
|
||||
<view
|
||||
class="event-icon"
|
||||
:style="{ backgroundColor: getColor(device.runStatus, device.devType) }"
|
||||
>
|
||||
<!-- 动态图标:根据类型切换 -->
|
||||
<uni-icons
|
||||
custom-prefix="iconfont"
|
||||
:type="device.devType == 'Direct_Connected_Device' ? 'icon-shebei2' : 'icon-shebei1'"
|
||||
:color="device.runStatus == 1 ? '#ff3b30' : '#67c23a'"
|
||||
size="45"
|
||||
:type="
|
||||
device.devType == 'Direct_Connected_Device'
|
||||
? 'icon-zaixianjianceshebei'
|
||||
: 'icon-shebei1'
|
||||
"
|
||||
:color="device.runStatus == 1 ? '#ff3b30' : '#10B981'"
|
||||
:size="device.devType == 'Direct_Connected_Device' ? '35' : '40'"
|
||||
></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
@@ -66,6 +73,7 @@
|
||||
<text>{{ device.process == 2 ? '功能调试' : '出厂调试' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pinToTop" v-if="device.isTop == 1"> 置顶 </view>
|
||||
</uni-card>
|
||||
</template>
|
||||
<script>
|
||||
@@ -133,16 +141,26 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
getColor(status, type) {
|
||||
if (status == 1) {
|
||||
return '#ff3b3020'
|
||||
} else {
|
||||
return '#10b98120' //type == 'Direct_Connected_Device' ? '#10b98120' : ''
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.device-body {
|
||||
padding: 20rpx;
|
||||
padding: 10rpx 20rpx 20rpx;
|
||||
|
||||
.device-body-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
line-height: 1.2;
|
||||
}
|
||||
}
|
||||
.uni-card {
|
||||
@@ -158,18 +176,19 @@ export default {
|
||||
border-bottom: 2rpx #ebeef5 solid;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
padding: 20rpx 20rpx 10rpx 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
.uni-card .uni-card__header .uni-card__header-content .uni-card__header-content-title {
|
||||
font-size: 15px;
|
||||
font-size: 28rpx;
|
||||
color: #3a3a3a;
|
||||
font-weight: 700;
|
||||
}
|
||||
.uni-card .uni-card__header .uni-card__header-content .uni-card__header-content-subtitle {
|
||||
font-size: 12px;
|
||||
// margin-top: 5px;
|
||||
color: #909399;
|
||||
color: #666666;
|
||||
}
|
||||
.uni-card .uni-card__header .uni-card__header-avatar .uni-card__header-avatar-image {
|
||||
width: 40px;
|
||||
@@ -191,8 +210,8 @@ export default {
|
||||
}
|
||||
.event-icon {
|
||||
position: relative;
|
||||
// width: 120rpx;
|
||||
height: 120rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 12rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
@@ -232,4 +251,23 @@ export default {
|
||||
background-color: #36cfc920;
|
||||
color: #36cfc9;
|
||||
}
|
||||
.pinToTop {
|
||||
background-color: $uni-theme-color;
|
||||
width: 100rpx;
|
||||
height: 60rpx;
|
||||
line-height: 90rpx;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
position: absolute;
|
||||
top: 0rpx;
|
||||
right: 0rpx;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
/* 核心:旋转成斜三角效果 */
|
||||
transform: rotate(45deg) translate(50rpx, -10rpx);
|
||||
transform-origin: top right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="nav choose">
|
||||
<view class="nav-menu" :class="{ 'nav-menu-active': select.engineeringName }" @click="selectEngineering"
|
||||
<view class="nav-menu" @click="selectEngineering" v-if="showQianTree"
|
||||
>{{
|
||||
// select.engineeringName + '>' + select.projectName + '>' + select.deviceName + '>' + select.lineName ||
|
||||
// '全部工程'
|
||||
@@ -10,7 +10,7 @@
|
||||
.join('>')
|
||||
: '全部工程'
|
||||
}}
|
||||
<uni-icons type="bottom" size="14" :color="select.engineeringName ? '#376cf3' : '#666'"></uni-icons>
|
||||
<uni-icons type="bottom" size="14"></uni-icons>
|
||||
</view>
|
||||
<!-- 弹框组件 -->
|
||||
<Cn-qianTree
|
||||
@@ -19,6 +19,7 @@
|
||||
:multiple="false"
|
||||
:range="list"
|
||||
:foldAll="true"
|
||||
:singleChoice="singleChoice"
|
||||
@confirm="treeConfirm"
|
||||
@cancel="treeCancel"
|
||||
></Cn-qianTree>
|
||||
@@ -42,6 +43,12 @@
|
||||
<uni-icons type="bottom" size="14"></uni-icons>
|
||||
</view>
|
||||
</uni-datetime-picker>
|
||||
<picker @change="bindReport" v-if="report" :value="select.report" :range="reportList">
|
||||
<view class="nav-menu"
|
||||
>{{ reportList[select.report] }}
|
||||
<uni-icons type="bottom" size="14"></uni-icons>
|
||||
</view>
|
||||
</picker>
|
||||
<slot />
|
||||
</view>
|
||||
</template>
|
||||
@@ -52,6 +59,9 @@ export default {
|
||||
props: {
|
||||
level: { type: Number, default: 3 },
|
||||
showDatetime: { type: Boolean, default: true },
|
||||
report: { type: Boolean, default: false },
|
||||
singleChoice: { type: Boolean, default: false },
|
||||
showQianTree: { type: Boolean, default: true },
|
||||
},
|
||||
data() {
|
||||
const currentDate = this.getDate({
|
||||
@@ -69,8 +79,10 @@ export default {
|
||||
lineId: '', //测点ID
|
||||
date: currentDate,
|
||||
range: ['', ''],
|
||||
report: 0,
|
||||
},
|
||||
list: [],
|
||||
reportList: ['日报', '月报'],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@@ -86,7 +98,20 @@ export default {
|
||||
getTree() {
|
||||
this.clear()
|
||||
lineTree().then((res) => {
|
||||
let list = {
|
||||
let list = {}
|
||||
if (this.singleChoice) {
|
||||
let result = this.findFirstLevel(res.data)
|
||||
console.log('🚀 ~ result:', result)
|
||||
this.select.engineeringName = result.parents[0].name
|
||||
this.select.engineeringId = result.parents[0].id //工程ID
|
||||
this.select.projectName = result.parents[1].name
|
||||
this.select.projectId = result.parents[1].id //項目ID
|
||||
this.select.deviceName = result.parents[2].name
|
||||
this.select.deviceId = result.parents[2].id //设备ID
|
||||
this.select.lineName = result.node.name
|
||||
this.select.lineId = result.node.id //测点ID
|
||||
} else {
|
||||
list = {
|
||||
id: '',
|
||||
pid: '0',
|
||||
pids: '0',
|
||||
@@ -107,8 +132,10 @@ export default {
|
||||
children: [],
|
||||
ndid: null,
|
||||
}
|
||||
}
|
||||
|
||||
this.list = this.filterTreeByLevel([list, ...res.data])
|
||||
this.list = this.filterTreeByLevel(this.singleChoice ? res.data : [list, ...res.data])
|
||||
// this.findFirstLevel( this.list)
|
||||
})
|
||||
},
|
||||
// 递归过滤函数:去除level > 2的节点
|
||||
@@ -147,11 +174,13 @@ export default {
|
||||
bindDateChange(e) {
|
||||
this.select.date = e.detail.value
|
||||
},
|
||||
bindReport(e) {
|
||||
this.select.report = e.detail.value
|
||||
},
|
||||
selectEngineering() {
|
||||
this.$refs.qiantree._show()
|
||||
},
|
||||
|
||||
getProjectList() {},
|
||||
// 确定回调事件
|
||||
treeConfirm(e) {
|
||||
this.clear()
|
||||
@@ -192,10 +221,33 @@ export default {
|
||||
break
|
||||
}
|
||||
},
|
||||
external(name, id) {
|
||||
this.getTree()
|
||||
this.select.engineeringId = id
|
||||
this.select.engineeringName = name
|
||||
},
|
||||
// 取消回调事件
|
||||
treeCancel(e) {
|
||||
console.log(e)
|
||||
},
|
||||
findFirstLevel(list, parents = []) {
|
||||
for (const item of list) {
|
||||
// 当前就是 level=3
|
||||
if (item.level === 3) {
|
||||
return {
|
||||
node: item, // 第一个 level=3
|
||||
parents: parents, // 它的所有上级
|
||||
}
|
||||
}
|
||||
|
||||
// 递归子节点
|
||||
if (item.children && item.children.length) {
|
||||
const res = this.findFirstLevel(item.children, [...parents, item])
|
||||
if (res) return res // 找到直接返回,不再循环
|
||||
}
|
||||
}
|
||||
return null
|
||||
},
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
||||
@@ -20,10 +20,17 @@
|
||||
class="uni-input"
|
||||
radius="5"
|
||||
placeholder="请输入关键字搜索"
|
||||
clearButton="auto"
|
||||
cancelButton="none"
|
||||
clearButton="none"
|
||||
@input="input"
|
||||
/>
|
||||
|
||||
<!-- <uni-search-bar
|
||||
v-model="searchValue"
|
||||
clearButton="none"
|
||||
bgColor="#fff"
|
||||
placeholder="请输入关键词"
|
||||
@input="input"
|
||||
></uni-search-bar> -->
|
||||
</view>
|
||||
|
||||
<view class="tki-tree-view">
|
||||
@@ -59,7 +66,7 @@
|
||||
>
|
||||
<view
|
||||
class="tki-tree-check-yes"
|
||||
v-if="item.checked"
|
||||
v-if="item.checked && (singleChoice ? item.rank == 3 : true)"
|
||||
:class="{ radio: !multiple }"
|
||||
:style="{ 'border-color': confirmColor }"
|
||||
>
|
||||
@@ -70,7 +77,7 @@
|
||||
</view>
|
||||
<view
|
||||
class="tki-tree-check-no"
|
||||
v-else
|
||||
v-if="!item.checked && (singleChoice ? item.rank == 3 : true)"
|
||||
:class="{ radio: !multiple }"
|
||||
:style="{ 'border-color': confirmColor }"
|
||||
></view>
|
||||
@@ -101,6 +108,7 @@ export default {
|
||||
type: String,
|
||||
default: 'id',
|
||||
},
|
||||
singleChoice: { type: Boolean, default: false },
|
||||
rangeKey: {
|
||||
type: String,
|
||||
default: 'name',
|
||||
@@ -416,6 +424,10 @@ export default {
|
||||
})
|
||||
},
|
||||
_treeItemSelect(item, index) {
|
||||
if (item.rank != 3) {
|
||||
if (this.singleChoice) return
|
||||
}
|
||||
// if(this.singleChoice)
|
||||
this.treeList[index].checked = !this.treeList[index].checked
|
||||
// 选父级, 子级自动全选
|
||||
this.syncChecked(this.treeList, item.id, this.treeList[index].checked)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
bottom: 0rpx;
|
||||
left: 0rpx;
|
||||
z-index: 9999;
|
||||
top: 160rpx;
|
||||
top: 40%;
|
||||
transition: all 0.3s ease;
|
||||
transform: translateY(100%);
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
"/api" : {
|
||||
"https" : true,
|
||||
// "target" : "https://pqmcn.com:8092/api",
|
||||
"target" : "http://192.168.2.126:10215",
|
||||
"target" : "http://192.168.1.103:10215",
|
||||
"changOrigin" : true,
|
||||
"pathRewrite" : {
|
||||
"/api" : ""
|
||||
|
||||
@@ -17,7 +17,12 @@
|
||||
"path": "pages/index/message1",
|
||||
"style": {
|
||||
"navigationBarTitleText": "消息",
|
||||
|
||||
"enablePullDownRefresh": true, // 开启下拉刷新
|
||||
"pullToRefresh": {
|
||||
"support":true,
|
||||
"style": "circle",
|
||||
"color":"#007aff"
|
||||
},
|
||||
"app-plus": {
|
||||
"bounce": "none",
|
||||
//关闭窗口回弹效果
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<!-- <view class="content-item-header-right-des">暂态类型:{{ item.showName }}</view> -->
|
||||
<!-- <view class="content-item-header-right-des">{{ item.subTitle }}</view> -->
|
||||
</view>
|
||||
<view class="ml10" v-if="type === '0' || item.status != '1'">🔍</view>
|
||||
<view class="ml10" v-if="type === '0' || item.status != '1'"> <uni-icons type="search" size="25"></uni-icons></view>
|
||||
</view>
|
||||
<view class="content-item-footer">{{ item.subTitle }}</view>
|
||||
</view>
|
||||
|
||||
@@ -3,16 +3,9 @@
|
||||
<template slot="body">
|
||||
<view class="device">
|
||||
<view class="nav" :style="{ top: navTabHeight + 'px' }">
|
||||
<view
|
||||
class="nav-menu"
|
||||
:class="{ 'nav-menu-active': select.engineeringName }"
|
||||
@click="selectEngineering"
|
||||
<view class="nav-menu" @click="selectEngineering"
|
||||
>{{ select.engineeringName || '全部工程' }}
|
||||
<uni-icons
|
||||
type="bottom"
|
||||
size="14"
|
||||
:color="select.engineeringName ? '#376cf3' : '#666'"
|
||||
></uni-icons>
|
||||
<uni-icons type="bottom" size="14"></uni-icons>
|
||||
</view>
|
||||
<picker
|
||||
@change="projectNameChange"
|
||||
@@ -22,30 +15,16 @@
|
||||
range-key="text"
|
||||
v-if="select.engineeringId"
|
||||
>
|
||||
<view
|
||||
class="nav-menu"
|
||||
:class="{ 'nav-menu-active': select.projectName }"
|
||||
@click="select.selectProject = true"
|
||||
>
|
||||
<view class="nav-menu" @click="select.selectProject = true">
|
||||
{{
|
||||
select.projectName
|
||||
? select.projectName.length > 6
|
||||
? select.projectName.substring(0, 6) + '...'
|
||||
? select.projectName.substring(0, 12) + '...'
|
||||
: select.projectName
|
||||
: '全部项目'
|
||||
}}
|
||||
<uni-icons
|
||||
type="top"
|
||||
size="14"
|
||||
:color="select.projectName ? '#376cf3' : '#666'"
|
||||
v-if="select.selectProject"
|
||||
></uni-icons>
|
||||
<uni-icons
|
||||
type="bottom"
|
||||
size="14"
|
||||
:color="select.projectName ? '#376cf3' : '#666'"
|
||||
v-else
|
||||
></uni-icons>
|
||||
<uni-icons type="top" size="14" v-if="select.selectProject"></uni-icons>
|
||||
<uni-icons type="bottom" size="14" v-else></uni-icons>
|
||||
</view>
|
||||
</picker>
|
||||
<picker
|
||||
@@ -55,30 +34,16 @@
|
||||
:range="projectType"
|
||||
range-key="text"
|
||||
>
|
||||
<view
|
||||
class="nav-menu"
|
||||
:class="{ 'nav-menu-active': select.runStatusName }"
|
||||
@click="select.runStatusSelect = true"
|
||||
>
|
||||
<view class="nav-menu" @click="select.runStatusSelect = true">
|
||||
{{
|
||||
select.runStatusName
|
||||
? select.runStatusName.length > 4
|
||||
? select.runStatusName.substring(0, 4) + '...'
|
||||
? select.runStatusName.length > 12
|
||||
? select.runStatusName.substring(0, 12) + '...'
|
||||
: select.runStatusName
|
||||
: '全部状态'
|
||||
}}
|
||||
<uni-icons
|
||||
type="top"
|
||||
size="14"
|
||||
:color="select.runStatusName ? '#376cf3' : '#666'"
|
||||
v-if="select.runStatusSelect"
|
||||
></uni-icons>
|
||||
<uni-icons
|
||||
type="bottom"
|
||||
size="14"
|
||||
:color="select.runStatusName ? '#376cf3' : '#666'"
|
||||
v-else
|
||||
></uni-icons>
|
||||
<uni-icons type="top" size="14" v-if="select.runStatusSelect"></uni-icons>
|
||||
<uni-icons type="bottom" size="14" v-else></uni-icons>
|
||||
</view>
|
||||
</picker>
|
||||
</view>
|
||||
@@ -108,7 +73,14 @@
|
||||
</view>
|
||||
|
||||
<view class="content device" :style="{ minHeight: minHeight }">
|
||||
<Cn-device-card v-for="(item, index) in store.data" :device="item" :key="index">
|
||||
<uni-swipe-action>
|
||||
<uni-swipe-action-item
|
||||
v-for="(item, index) in store.data"
|
||||
:threshold="0"
|
||||
:right-options="item.isTop == 0 ? options1 : options12"
|
||||
@click="bindClick($event, item)"
|
||||
>
|
||||
<Cn-device-card :device="item" :key="index">
|
||||
<template v-slot:title>
|
||||
<!-- 卡片标题 -->
|
||||
|
||||
@@ -118,16 +90,13 @@
|
||||
style="transform: scale(0.8); position: relative; left: 20rpx"
|
||||
@change="switchChange(item)"
|
||||
/>
|
||||
<view class="star-icon" v-else @click="toggleStar(item)">
|
||||
<uni-icons
|
||||
custom-prefix="custom-icon"
|
||||
:type="item.isTop == 1 ? 'star-filled' : 'star'"
|
||||
:color="item.isTop == 1 ? '#ffcc00' : ''"
|
||||
size="25"
|
||||
></uni-icons>
|
||||
<view class="star-icon" v-else>
|
||||
<uni-icons type="search" size="25"></uni-icons>
|
||||
</view>
|
||||
</template>
|
||||
</Cn-device-card>
|
||||
</uni-swipe-action-item>
|
||||
</uni-swipe-action>
|
||||
<uni-load-more
|
||||
v-if="store.status == 'loading' || (store.data && store.data.length > 0)"
|
||||
:status="store.status"
|
||||
@@ -181,6 +150,22 @@ export default {
|
||||
},
|
||||
],
|
||||
pageOptions: {},
|
||||
options1: [
|
||||
{
|
||||
text: '置顶',
|
||||
style: {
|
||||
backgroundColor: '#376cf3',
|
||||
},
|
||||
},
|
||||
],
|
||||
options12: [
|
||||
{
|
||||
text: '取消',
|
||||
style: {
|
||||
backgroundColor: '#ccc',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -250,10 +235,26 @@ export default {
|
||||
this.select.engineeringId = engineering.id
|
||||
this.select.engineeringName = engineering.name
|
||||
this.select.projectNameIndex = 0
|
||||
this.select.projectName = ''
|
||||
this.getProjectList()
|
||||
}
|
||||
this.store && this.store.reload()
|
||||
},
|
||||
methods: {
|
||||
bindClick(e, item) {
|
||||
engineeringPinToTop({
|
||||
targetId: item.equipmentId,
|
||||
targetType: 1,
|
||||
userId: uni.getStorageSync(this.$cacheKey.userInfo).userIndex,
|
||||
}).then((res) => {
|
||||
if (res.code == 'A0000') {
|
||||
this.$util.toast('操作成功!')
|
||||
this.store.search()
|
||||
} else {
|
||||
this.$util.toast(res.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
selectEngineering() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/selectEngineering?from=once',
|
||||
@@ -459,22 +460,11 @@ export default {
|
||||
this.checkList.push(e.equipmentId)
|
||||
}
|
||||
},
|
||||
toggleStar(item) {
|
||||
engineeringPinToTop({
|
||||
targetId: item.equipmentId,
|
||||
targetType: 1,
|
||||
userId: uni.getStorageSync(this.$cacheKey.userInfo).userIndex,
|
||||
}).then((res) => {
|
||||
if (res.code == 'A0000') {
|
||||
this.$util.toast('操作成功!')
|
||||
this.store.search()
|
||||
}else{
|
||||
this.$util.toast(res.message)
|
||||
}
|
||||
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss"></style>
|
||||
<style lang="scss">
|
||||
/deep/ .button-group--right {
|
||||
padding: 0 0 20rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,9 +23,26 @@
|
||||
</button>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else >
|
||||
<template v-else>
|
||||
<view class="content">
|
||||
<uni-forms>
|
||||
<uni-forms-item label="工程">
|
||||
<view style="display: flex; align-items: center">
|
||||
<uni-data-select
|
||||
v-model="formData.engineeringId"
|
||||
:localdata="engineeringList"
|
||||
@change="engineeringChang($event, true)"
|
||||
:clear="false"
|
||||
></uni-data-select>
|
||||
<uni-icons
|
||||
type="plusempty"
|
||||
color="#007aff"
|
||||
size="26"
|
||||
class="ml20"
|
||||
@click="createEngineering"
|
||||
></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="项目">
|
||||
<view style="display: flex; align-items: center">
|
||||
<uni-data-select
|
||||
@@ -43,28 +60,7 @@
|
||||
></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<!-- <uni-forms-item label="型号">
|
||||
<uni-data-select v-model="formData.type" :localdata="typeRange"
|
||||
@change="typeChange(item)"></uni-data-select>
|
||||
</uni-forms-item> -->
|
||||
<!-- <uni-forms-item label="位置">-->
|
||||
<!-- <view style="display: flex;">-->
|
||||
<!-- <uni-easyinput-->
|
||||
<!-- :clearable="false"-->
|
||||
<!-- type="textarea"-->
|
||||
<!-- autoHeight-->
|
||||
<!-- v-model="formData.area"-->
|
||||
<!-- placeholder="请输入位置信息"-->
|
||||
<!-- />-->
|
||||
<!-- <uni-icons-->
|
||||
<!-- type="location"-->
|
||||
<!-- color="#007aff"-->
|
||||
<!-- size="26"-->
|
||||
<!-- class="ml20"-->
|
||||
<!-- @click="chooseLocation"-->
|
||||
<!-- ></uni-icons>-->
|
||||
<!-- </view>-->
|
||||
<!-- </uni-forms-item>-->
|
||||
|
||||
<uni-forms-item label="拓扑图" v-if="formData.projectId">
|
||||
<view style="display: flex">
|
||||
<view style="flex: 1">
|
||||
@@ -82,7 +78,10 @@
|
||||
></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="监测点" v-if="pointList.length && formData.topologyDiagramUrl">
|
||||
<uni-forms-item
|
||||
label="监测点"
|
||||
v-if="pointList.length && formData.topologyDiagramUrl && formData.projectId"
|
||||
>
|
||||
<view
|
||||
class="point-item"
|
||||
v-for="(item2, index2) in pointList"
|
||||
@@ -97,7 +96,7 @@
|
||||
</uni-forms>
|
||||
</view>
|
||||
<image class="gplot-image" ref="gplot-image" :src="formData.topologyDiagramUrl" mode="widthFix" />
|
||||
<view class="btn-wrap" >
|
||||
<view class="btn-wrap">
|
||||
<!-- <view class="btn-wrap-item" @click="add"> 添加监测点 </view> -->
|
||||
<!-- <view class="btn-wrap-item" @click="submit" > 提交</view> -->
|
||||
<button class="btn-wrap-item" :loading="isLoading1" :disabled="isLoading1" @click="submit">
|
||||
@@ -172,7 +171,14 @@
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { registerDevice, getModel, addDevice, queryByTopoId } from '@/common/api/device.js'
|
||||
import {
|
||||
registerDevice,
|
||||
getModel,
|
||||
addDevice,
|
||||
queryByTopoId,
|
||||
queryEngineeringPage,
|
||||
queryEquipmentByndid,
|
||||
} from '@/common/api/device.js'
|
||||
import { getProjectList, queryTopologyDiagramPage } from '@/common/api/project.js'
|
||||
import ykAuthpup from '@/components/yk-authpup/yk-authpup'
|
||||
export default {
|
||||
@@ -184,6 +190,7 @@ export default {
|
||||
loading: false,
|
||||
type: 1,
|
||||
formData: {
|
||||
engineeringId: '',
|
||||
nDid: '',
|
||||
projectId: '',
|
||||
topologyDiagramUrl: '',
|
||||
@@ -200,6 +207,7 @@ export default {
|
||||
isAdaptive: false, // 是否适应当前项目
|
||||
dialogOpen: false,
|
||||
options: {},
|
||||
engineeringList: [],
|
||||
}
|
||||
},
|
||||
onBackPress() {
|
||||
@@ -231,13 +239,60 @@ export default {
|
||||
})
|
||||
},
|
||||
onShow() {
|
||||
let engineering = uni.getStorageSync(this.$cacheKey.engineering)
|
||||
this.getEngineering()
|
||||
if (this.formData.engineeringId) {
|
||||
this.engineeringChang(this.formData.engineeringId, false)
|
||||
// this.queryTopologyDiagramPage()
|
||||
}
|
||||
// let engineering = uni.getStorageSync(this.$cacheKey.engineering)
|
||||
// getProjectList({
|
||||
// pageNum: 1,
|
||||
// pageSize: 9999,
|
||||
// engineeringId: engineering.id,
|
||||
// }).then((res) => {
|
||||
// console.log(res)
|
||||
// let arr = [
|
||||
// ...res.data.records.map((item) => {
|
||||
// return {
|
||||
// ...item,
|
||||
// text: item.name,
|
||||
// value: item.id,
|
||||
// }
|
||||
// }),
|
||||
// ]
|
||||
// this.projectRange = arr
|
||||
// })
|
||||
},
|
||||
methods: {
|
||||
getEngineering() {
|
||||
queryEngineeringPage({ pageNum: 1, pageSize: 9999 }).then((res) => {
|
||||
let arr = [
|
||||
...res.data.records.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
text: item.name,
|
||||
value: item.id,
|
||||
}
|
||||
}),
|
||||
]
|
||||
this.engineeringList = arr
|
||||
})
|
||||
},
|
||||
|
||||
engineeringChang(e, key) {
|
||||
if (e == '') {
|
||||
return (this.projectRange = [])
|
||||
}
|
||||
if (key) {
|
||||
this.formData.projectId = ''
|
||||
}
|
||||
uni.setStorageSync('engineering', this.engineeringList.filter((item) => item.id == e)[0])
|
||||
|
||||
getProjectList({
|
||||
pageNum: 1,
|
||||
pageSize: 9999,
|
||||
engineeringId: engineering.id,
|
||||
engineeringId: e,
|
||||
}).then((res) => {
|
||||
console.log(res)
|
||||
let arr = [
|
||||
...res.data.records.map((item) => {
|
||||
return {
|
||||
@@ -250,12 +305,23 @@ export default {
|
||||
this.projectRange = arr
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
|
||||
createProject() {
|
||||
if (this.formData.engineeringId == '') {
|
||||
return uni.showToast({
|
||||
title: '请选择工程',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
uni.navigateTo({
|
||||
url: '/pages/project/new?from=newDevice',
|
||||
})
|
||||
},
|
||||
createEngineering() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/engineering/new',
|
||||
})
|
||||
},
|
||||
resize() {
|
||||
console.log(this.$refs['gplot-image'])
|
||||
},
|
||||
@@ -265,7 +331,7 @@ export default {
|
||||
this.pointList.forEach((item) => {
|
||||
console.log(item.position)
|
||||
this.imageList[this.activeGplot].csLineTopologyTemplateVOList.forEach((item3) => {
|
||||
console.log(item3.linePostion)
|
||||
// console.log(item3.linePostion)
|
||||
if (item3.linePostion === item.position) {
|
||||
item.lat = item3.lat
|
||||
item.lng = item3.lng
|
||||
@@ -320,9 +386,8 @@ export default {
|
||||
}
|
||||
},
|
||||
changeAuth() {
|
||||
|
||||
uni.scanCode({
|
||||
onlyFromCamera:true,
|
||||
onlyFromCamera: true,
|
||||
success: (res) => {
|
||||
console.log('条码类型:' + res.scanType)
|
||||
console.log('条码内容:' + res.result)
|
||||
@@ -353,7 +418,7 @@ export default {
|
||||
}
|
||||
})
|
||||
this.type = 2
|
||||
|
||||
this.getNdin()
|
||||
this.isLoading = false
|
||||
})
|
||||
.catch(() => {
|
||||
@@ -364,6 +429,25 @@ export default {
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
// 默认回显工程项目
|
||||
getNdin() {
|
||||
queryEquipmentByndid({ ndid: this.formData.nDid }).then((res) => {
|
||||
this.formData.engineeringId = res.data.associatedEngineering || ''
|
||||
this.formData.projectId = res.data.associatedProject || ''
|
||||
if (this.formData.engineeringId) {
|
||||
this.engineeringChang(this.formData.engineeringId, false)
|
||||
this.queryTopologyDiagramPage()
|
||||
let flag = this.engineeringList.some((item) => item.id === this.formData.engineeringId)
|
||||
if (!flag) {
|
||||
this.engineeringList.unshift({
|
||||
text: res.data.associatedEngineeringName,
|
||||
value: res.data.associatedEngineering,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// chooseLocation() {
|
||||
// uni.chooseLocation({
|
||||
// success: function (res) {
|
||||
@@ -461,7 +545,8 @@ export default {
|
||||
list: this.pointList,
|
||||
ndid: this.formData.nDid,
|
||||
process: Number(this.options.type),
|
||||
}).then((res) => {
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res)
|
||||
this.$util.toast('提交成功')
|
||||
this.isLoading1 = false
|
||||
@@ -469,7 +554,8 @@ export default {
|
||||
this.type = 3
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1500)
|
||||
}).catch(()=>{
|
||||
})
|
||||
.catch(() => {
|
||||
this.isLoading1 = false
|
||||
})
|
||||
},
|
||||
|
||||
@@ -201,6 +201,7 @@ export default {
|
||||
this.echartsDataA1 = this.initEcharts('#DAA520', 1, 'A相(A)')
|
||||
this.echartsDataA2 = this.initEcharts('#2E8B57', 1, 'B相(A)')
|
||||
this.echartsDataA3 = this.initEcharts('#A52a2a', 1, 'C相(A)')
|
||||
this.loading = false
|
||||
this.$nextTick(() => {
|
||||
this.setMqtt(0)
|
||||
this.initMqtt()
|
||||
@@ -224,7 +225,7 @@ export default {
|
||||
}
|
||||
})
|
||||
clearInterval(this.timer)
|
||||
this.client.end()
|
||||
this.client && this.client.end()
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -590,7 +591,7 @@ export default {
|
||||
// 刷新
|
||||
handleRefresh() {
|
||||
this.disabled = true
|
||||
this.client.end()
|
||||
this.client && this.client.end()
|
||||
this.setMqtt(1)
|
||||
this.initMqtt()
|
||||
if (this.numTimer) {
|
||||
@@ -611,7 +612,12 @@ export default {
|
||||
}, 1000)
|
||||
},
|
||||
async setMqtt(e) {
|
||||
uni.showLoading({
|
||||
title: '连接中,请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
this.clear()
|
||||
|
||||
await getBaseRealData(this.lineId)
|
||||
.then((res) => {
|
||||
if (res.code == 'A0000') {
|
||||
@@ -620,7 +626,7 @@ export default {
|
||||
clearInterval(this.timer)
|
||||
this.timer = null
|
||||
}
|
||||
this.loading = false
|
||||
|
||||
this.timer = setInterval(() => {
|
||||
getBaseRealData(this.lineId).then((res) => {
|
||||
console.log(res, '获取基础实时数据')
|
||||
@@ -629,12 +635,9 @@ export default {
|
||||
} else {
|
||||
this.countdown = 60 // 重置倒计时
|
||||
this.disabled = false
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
.catch(() => {})
|
||||
},
|
||||
|
||||
initMqtt() {
|
||||
@@ -852,13 +855,13 @@ export default {
|
||||
})
|
||||
},
|
||||
// 监测点变化
|
||||
lineChange(e) {
|
||||
this.clear()
|
||||
async lineChange(e) {
|
||||
await this.clear()
|
||||
this.lineKey = e.detail.value
|
||||
this.lineId = this.lineList[e.detail.value].lineId
|
||||
this.client.end()
|
||||
this.setMqtt(0)
|
||||
this.initMqtt()
|
||||
await (this.client && this.client.end())
|
||||
await this.setMqtt(0)
|
||||
await this.initMqtt()
|
||||
},
|
||||
},
|
||||
|
||||
@@ -957,6 +960,7 @@ export default {
|
||||
display: flex;
|
||||
position: relative;
|
||||
height: 600rpx;
|
||||
margin: 0 10rpx;
|
||||
flex: 1;
|
||||
.echart1 {
|
||||
position: absolute;
|
||||
@@ -967,6 +971,7 @@ export default {
|
||||
.chart {
|
||||
width: 170rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 5rpx;
|
||||
}
|
||||
.text {
|
||||
text-align: center;
|
||||
|
||||
@@ -34,7 +34,7 @@ export default {
|
||||
this.engineeringList.forEach((item) => {
|
||||
let arr = pinyin(item.name[0], { toneType: 'none', type: 'array' })
|
||||
let letter = arr[0][0].toUpperCase()
|
||||
console.log(letter)
|
||||
// console.log(letter)
|
||||
let index = result.findIndex((item) => item.letter === letter)
|
||||
if (index === -1) {
|
||||
result.push({
|
||||
@@ -67,7 +67,16 @@ export default {
|
||||
onShow() {
|
||||
queryEngineering().then((res) => {
|
||||
this.engineeringList = res.data.sort((a, b) => {
|
||||
return a.name.localeCompare(b.name, 'zh', { sensitivity: 'accent' })
|
||||
const nameA = a.name
|
||||
const nameB = b.name
|
||||
|
||||
const isANumber = /^\d/.test(nameA)
|
||||
const isBNumber = /^\d/.test(nameB)
|
||||
|
||||
if (isANumber !== isBNumber) {
|
||||
return isANumber ? 1 : -1
|
||||
}
|
||||
return nameA.localeCompare(nameB, 'zh', { sensitivity: 'accent' })
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
<view>
|
||||
<view class="filterCriteria">
|
||||
<!-- 筛选条件 -->
|
||||
<Cn-filterCriteria @select="select" :showDatetime="false"> </Cn-filterCriteria>
|
||||
<Cn-filterCriteria @select="select" :singleChoice="true" :showDatetime="true"> </Cn-filterCriteria>
|
||||
<view class="choose1">
|
||||
<view>
|
||||
<checkbox-group @change="changeBox"
|
||||
><checkbox value="true" :checked="checkedAll" />全选
|
||||
</checkbox-group></view
|
||||
>
|
||||
<view class="nav-menu nav-menu-btn" @click="selectDevice('transfer')">申请报表 </view>
|
||||
<view class="nav-menu nav-menu-btn" @click="selectDevice">申请报告 </view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="smallLabel mt20">
|
||||
@@ -24,11 +24,15 @@
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 -->
|
||||
<view class="event-list" :style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }">
|
||||
<scroll-view
|
||||
scroll-y="true"
|
||||
class="event-list"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }"
|
||||
>
|
||||
<!-- 循环渲染事件项 -->
|
||||
<uni-card
|
||||
class="event-item"
|
||||
:class="judgment(item.showName)"
|
||||
:class="judgment(item.showName).type"
|
||||
v-for="(item, index) in store.data"
|
||||
:key="index"
|
||||
@click="clackCard(item)"
|
||||
@@ -39,27 +43,17 @@
|
||||
<!-- 动态图标:根据类型切换 -->
|
||||
<uni-icons
|
||||
:custom-prefix="judgment(item.showName) == 'interrupt' ? 'custom-icon' : 'iconfont'"
|
||||
:type="
|
||||
judgment(item.showName) == 'sag'
|
||||
? 'icon-xiajiang'
|
||||
: judgment(item.showName) == 'swell'
|
||||
? 'icon-shangsheng'
|
||||
: 'minus'
|
||||
"
|
||||
:color="
|
||||
judgment(item.showName) == 'sag'
|
||||
? '#2563eb '
|
||||
: judgment(item.showName) == 'swell'
|
||||
? '#e6a23c'
|
||||
: '#909399'
|
||||
"
|
||||
:size="judgment(item.showName) == 'interrupt' ? '50' : '25'"
|
||||
:type="judgment(item.showName).icon"
|
||||
:color="judgment(item.showName).color"
|
||||
:size="judgment(item.showName).size"
|
||||
></uni-icons>
|
||||
</view>
|
||||
<view class="event-info">
|
||||
<view class="event-title">
|
||||
<text class="event-id">{{ item.equipmentName }}</text>
|
||||
<text class="event-tag" :class="`${judgment(item.showName)}-tag`">{{ item.showName }}</text>
|
||||
<text class="event-tag" :class="`${judgment(item.showName).type}-tag`">{{
|
||||
item.showName
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="event-desc">
|
||||
<text>工程名称:{{ item.engineeringName }}</text>
|
||||
@@ -88,11 +82,12 @@
|
||||
:status="store.status"
|
||||
></uni-load-more>
|
||||
<Cn-empty v-else style="top: 20%"></Cn-empty>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import list from '@/common/js/list'
|
||||
import { applicationReport } from '@/common/api/report.js'
|
||||
export default {
|
||||
components: {},
|
||||
props: {
|
||||
@@ -112,20 +107,21 @@ export default {
|
||||
array: ['发生时间', '暂降深度', '持续时间'],
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
mounted() {
|
||||
this.setHeight()
|
||||
},
|
||||
|
||||
methods: {
|
||||
setHeight() {
|
||||
uni.createSelectorQuery()
|
||||
.select('.filterCriteria')
|
||||
.boundingClientRect((rect) => {
|
||||
console.log('🚀 ~ rect:', rect)
|
||||
//
|
||||
// #ifdef H5
|
||||
this.height = rect?.height + 100 || 0
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
this.height = rect?.height + 100 || 0
|
||||
this.height = rect?.height + 90 || 0
|
||||
// #endif
|
||||
})
|
||||
.exec()
|
||||
@@ -144,8 +140,11 @@ export default {
|
||||
this.store.params.projectId = this.selectValue.projectId
|
||||
this.store.params.deviceId = this.selectValue.deviceId
|
||||
this.store.params.lineId = this.selectValue.lineId
|
||||
this.store.params.startTime = this.selectValue.range[0]
|
||||
this.store.params.endTime = this.selectValue.range[1]
|
||||
this.store.params.target = ['Evt_Sys_DipStr']
|
||||
this.store.params.startTime = this.$util.getMonthFirstAndLastDay(this.selectValue.date).firstDay
|
||||
this.store.params.endTime = this.$util.getMonthFirstAndLastDay(this.selectValue.date).lastDay
|
||||
// this.store.params.startTime = this.selectValue.range[0]
|
||||
// this.store.params.endTime = this.selectValue.range[1]
|
||||
this.store.loadedCallback = () => {
|
||||
this.checkedTotal = 0
|
||||
this.store.data = this.store.data.map((item) => {
|
||||
@@ -184,15 +183,88 @@ export default {
|
||||
this.sort = e.detail.value
|
||||
this.init()
|
||||
},
|
||||
judgment(val) {
|
||||
judgment(val, key) {
|
||||
switch (val) {
|
||||
case '电压暂降':
|
||||
return 'sag'
|
||||
case '电压暂升':
|
||||
return 'swell'
|
||||
case '电压中断':
|
||||
return 'interrupt'
|
||||
return {
|
||||
type: 'sag',
|
||||
icon: 'icon-a-svg4',
|
||||
color: '#2563eb',
|
||||
size: '25',
|
||||
}
|
||||
case '电压暂升':
|
||||
return {
|
||||
type: 'swell',
|
||||
icon: 'icon-a-svg5',
|
||||
color: '#e6a23c',
|
||||
size: '25',
|
||||
}
|
||||
case '电压中断':
|
||||
return {
|
||||
type: 'interrupt',
|
||||
icon: 'icon-zhongduan2',
|
||||
color: '#6b7280',
|
||||
size: '35',
|
||||
}
|
||||
case '瞬态':
|
||||
return {
|
||||
type: 'transient',
|
||||
icon: 'icon-shuntaishijian',
|
||||
color: '#8b5cf6',
|
||||
size: '40',
|
||||
}
|
||||
case '未知':
|
||||
return {
|
||||
type: 'unknown',
|
||||
icon: 'icon-wenhao',
|
||||
color: '#6b7280',
|
||||
size: '45',
|
||||
}
|
||||
}
|
||||
},
|
||||
// 申请
|
||||
selectDevice() {
|
||||
if (this.checkedTotal == 0) {
|
||||
return uni.showToast({
|
||||
title: '请选择事件!',
|
||||
icon: 'none',
|
||||
})
|
||||
} else {
|
||||
uni.showLoading({
|
||||
title: '申请中,请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
|
||||
let list = this.store.data.filter((item) => item.checked === true)
|
||||
applicationReport({
|
||||
list: list.map((item) => item.id),
|
||||
lineId: list[0].lineId,
|
||||
startTime: this.$util.getMonthFirstAndLastDay(this.selectValue.date).firstDay,
|
||||
endTime: this.$util.getMonthFirstAndLastDay(this.selectValue.date).lastDay,
|
||||
}).then((res) => {
|
||||
this.store.reload()
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
title: '申请暂态报告,成功!',
|
||||
duration: 1000,
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
isAllLineIdSame(data) {
|
||||
// 获取第一个元素的lineId作为基准
|
||||
const baseLineId = data[0].lineId
|
||||
|
||||
// 遍历数组,检查每个元素的lineId是否和基准一致
|
||||
for (let item of data) {
|
||||
// 兼容元素可能没有lineId的情况
|
||||
if (!item || item.lineId !== baseLineId) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
},
|
||||
|
||||
@@ -220,9 +292,11 @@ export default {
|
||||
}
|
||||
}
|
||||
.nav-menu {
|
||||
height: 40rpx;
|
||||
padding: 6rpx 20rpx;
|
||||
margin-left: 20rpx;
|
||||
margin-bottom: 20rpx;
|
||||
line-height: 40rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 8rpx;
|
||||
background: #ebeaec;
|
||||
|
||||
@@ -60,7 +60,14 @@
|
||||
</picker> -->
|
||||
</view>
|
||||
<view class="content device" :style="{ minHeight: minHeight }">
|
||||
<Cn-device-card v-for="(item, index) in deviceListFilter" :device="item" :key="index">
|
||||
<uni-swipe-action>
|
||||
<uni-swipe-action-item
|
||||
v-for="(item, index) in deviceListFilter"
|
||||
:threshold="0"
|
||||
:right-options="item.isTop == 0 ? options1 : options12"
|
||||
@click="bindClick($event, item)"
|
||||
>
|
||||
<Cn-device-card :device="item" :key="index">
|
||||
<template v-slot:title>
|
||||
<!-- 卡片标题 -->
|
||||
|
||||
@@ -70,16 +77,11 @@
|
||||
style="transform: scale(0.8); position: relative; left: 20rpx"
|
||||
@change="switchChange(item)"
|
||||
/>
|
||||
<view class="star-icon" v-else @click="toggleStar(item)">
|
||||
<uni-icons
|
||||
custom-prefix="custom-icon"
|
||||
:type="item.isTop == 1 ? 'star-filled' : 'star'"
|
||||
:color="item.isTop == 1 ? '#ffcc00' : ''"
|
||||
size="25"
|
||||
></uni-icons>
|
||||
</view>
|
||||
<view class="star-icon" v-else> <uni-icons type="search" size="25"></uni-icons> </view>
|
||||
</template>
|
||||
</Cn-device-card>
|
||||
</uni-swipe-action-item>
|
||||
</uni-swipe-action>
|
||||
<uni-load-more
|
||||
v-if="store.status == 'loading' || deviceListFilter.length > 0"
|
||||
:status="store.status"
|
||||
@@ -118,6 +120,22 @@ export default {
|
||||
projectType: [],
|
||||
userInfo: {},
|
||||
selectProject: false,
|
||||
options1: [
|
||||
{
|
||||
text: '置顶',
|
||||
style: {
|
||||
backgroundColor: '#376cf3',
|
||||
},
|
||||
},
|
||||
],
|
||||
options12: [
|
||||
{
|
||||
text: '取消',
|
||||
style: {
|
||||
backgroundColor: '#ccc',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -148,7 +166,7 @@ export default {
|
||||
},
|
||||
mounted() {},
|
||||
methods: {
|
||||
toggleStar(item) {
|
||||
bindClick(e, item) {
|
||||
engineeringPinToTop({
|
||||
targetId: item.equipmentId,
|
||||
targetType: 1,
|
||||
@@ -162,6 +180,7 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
selectDevice(type) {
|
||||
if (this.deviceListFilter.findIndex((item) => item.isPrimaryUser === '1') === -1) {
|
||||
this.$util.toast('没有可操作的设备')
|
||||
@@ -351,4 +370,9 @@ export default {
|
||||
.nav-menu {
|
||||
}
|
||||
}
|
||||
/deep/ .button-group--right {
|
||||
padding: 0 0 20rpx;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
@@ -2,10 +2,22 @@
|
||||
<view class="index-device">
|
||||
<view class="nav" :style="{ top: navTabHeight + 'px' }"> </view>
|
||||
<view class="content device project-list" :style="{ minHeight: minHeight }">
|
||||
<uni-card v-for="(item, index) in store.data" :key="index">
|
||||
<uni-swipe-action>
|
||||
<uni-swipe-action-item
|
||||
v-for="(item, index) in store.data"
|
||||
:threshold="0"
|
||||
:right-options="item.isTop == 0 ? options1 : options12"
|
||||
@click="bindClick($event, item)"
|
||||
>
|
||||
<uni-card :key="index">
|
||||
<view class="card-header">
|
||||
<view class="project-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-gongcheng" color="#2563eb" size="45"></uni-icons>
|
||||
<uni-icons
|
||||
custom-prefix="iconfont"
|
||||
type="icon-gongcheng"
|
||||
color="#2563eb"
|
||||
size="45"
|
||||
></uni-icons>
|
||||
</view>
|
||||
<view class="project-info">
|
||||
<view class="project-name">{{ item.engineeringName }}</view>
|
||||
@@ -28,16 +40,11 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="star-icon" @click="toggleStar(item)">
|
||||
<uni-icons
|
||||
custom-prefix="custom-icon"
|
||||
:type="item.isTop == 1 ? 'star-filled' : 'star'"
|
||||
:color="item.isTop == 1 ? '#ffcc00' : ''"
|
||||
size="25"
|
||||
></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<view class="pinToTop" v-if="item.isTop == 1"> 置顶 </view>
|
||||
</uni-card>
|
||||
</uni-swipe-action-item>
|
||||
</uni-swipe-action>
|
||||
<uni-load-more
|
||||
v-if="store.status == 'loading' || deviceListFilter.length > 0"
|
||||
:status="store.status"
|
||||
@@ -61,6 +68,22 @@ export default {
|
||||
minHeight: 0,
|
||||
navTabHeight: 0,
|
||||
userInfo: {},
|
||||
options1: [
|
||||
{
|
||||
text: '置顶',
|
||||
style: {
|
||||
backgroundColor: '#376cf3',
|
||||
},
|
||||
},
|
||||
],
|
||||
options12: [
|
||||
{
|
||||
text: '取消',
|
||||
style: {
|
||||
backgroundColor: '#ccc',
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -77,7 +100,7 @@ export default {
|
||||
console.log(12333, this.store)
|
||||
},
|
||||
methods: {
|
||||
toggleStar(item) {
|
||||
bindClick(e, item) {
|
||||
engineeringPinToTop({
|
||||
targetId: item.engineeringId,
|
||||
targetType: 2,
|
||||
@@ -85,12 +108,13 @@ export default {
|
||||
}).then((res) => {
|
||||
if (res.code == 'A0000') {
|
||||
this.$util.toast('操作成功!')
|
||||
this.$emit('refresh')
|
||||
this.store.search()
|
||||
} else {
|
||||
this.$util.toast(res.message)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getDeviceList() {
|
||||
this.store.params.pageSize = 50
|
||||
this.store.firstCallBack = (res) => {
|
||||
@@ -124,6 +148,11 @@ export default {
|
||||
|
||||
jump(type, item) {
|
||||
if (type == 'event') {
|
||||
// 存储参数
|
||||
uni.setStorageSync('messageParams', {
|
||||
name: item.engineeringName,
|
||||
id: item.engineeringId,
|
||||
})
|
||||
uni.switchTab({
|
||||
url: '/pages/index/message1',
|
||||
})
|
||||
@@ -171,8 +200,9 @@ export default {
|
||||
}
|
||||
|
||||
.project-name {
|
||||
font-size: 15px;
|
||||
color: #3a3a3a;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
margin-bottom: 10rpx;
|
||||
}
|
||||
|
||||
@@ -193,13 +223,13 @@ export default {
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 30rpx;
|
||||
font-size: 32rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 24rpx;
|
||||
color: #6a6a6a;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.blue {
|
||||
@@ -221,4 +251,26 @@ export default {
|
||||
/deep/ .uni-card {
|
||||
padding: 0 !important;
|
||||
}
|
||||
/deep/ .button-group--right {
|
||||
padding: 0 0 20rpx;
|
||||
}
|
||||
.pinToTop {
|
||||
background-color: $uni-theme-color;
|
||||
width: 100rpx;
|
||||
height: 60rpx;
|
||||
line-height: 90rpx;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 20rpx;
|
||||
position: absolute;
|
||||
top: 0rpx;
|
||||
right: 0rpx;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
/* 核心:旋转成斜三角效果 */
|
||||
transform: rotate(45deg) translate(50rpx, -10rpx);
|
||||
transform-origin: top right;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="index-zhuyonghu">
|
||||
<template v-if="devCount.engineeringListLength > 1">
|
||||
<template v-if="devCount.engineeringListLength > 0">
|
||||
<view class="canneng-index-title mb20">所有工程设备统计</view>
|
||||
<view class="header">
|
||||
<view class="header-item" @click="jump('allEngineering')">
|
||||
@@ -53,7 +53,7 @@
|
||||
<view style="padding: 20rpx 20rpx 0">
|
||||
<Cn-grid title="" :auto-fill="false">
|
||||
<Cn-grid-item src="/static/device2.png" text="设备注册" @click="registerDevice(4)"></Cn-grid-item>
|
||||
<!-- <Cn-grid-item
|
||||
<Cn-grid-item
|
||||
src="/static/device2.png"
|
||||
text="功能调试"
|
||||
@click="registerDevice(2)"
|
||||
@@ -64,12 +64,12 @@
|
||||
text="出厂调试"
|
||||
@click="registerDevice(3)"
|
||||
v-if="config.factory"
|
||||
></Cn-grid-item> -->
|
||||
<!-- <Cn-grid-item background="#fff" v-if="!config.feature"></Cn-grid-item>
|
||||
<Cn-grid-item background="#fff" v-if="!config.factory"></Cn-grid-item> -->
|
||||
<Cn-grid-item background="#fff"></Cn-grid-item>
|
||||
<Cn-grid-item background="#fff"></Cn-grid-item>
|
||||
></Cn-grid-item>
|
||||
<Cn-grid-item background="#fff" v-if="!config.feature"></Cn-grid-item>
|
||||
<Cn-grid-item background="#fff" v-if="!config.factory"></Cn-grid-item>
|
||||
<Cn-grid-item background="#fff"></Cn-grid-item>
|
||||
<!-- <Cn-grid-item background="#fff"></Cn-grid-item>
|
||||
<Cn-grid-item background="#fff"></Cn-grid-item> -->
|
||||
<!-- <Cn-grid-item src="/static/gateway2.png" text="网关注册" @click="registerGateway"></Cn-grid-item> -->
|
||||
<!-- <Cn-grid-item src="/static/feedback2.png" text="问题反馈" @click="submitFeedBack"></Cn-grid-item>-->
|
||||
</Cn-grid>
|
||||
@@ -156,15 +156,15 @@ export default {
|
||||
this.$refs.popup.close()
|
||||
},
|
||||
confirm(value) {
|
||||
if (this.devCount.engineeringListLength > 0) {
|
||||
// if (this.devCount.engineeringListLength > 0) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/device/new?type=' + this.type,
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/pages/engineering/new?from=index&type=' + this.type,
|
||||
})
|
||||
}
|
||||
// } else {
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/engineering/new?from=index&type=' + this.type,
|
||||
// })
|
||||
// }
|
||||
|
||||
this.$refs.popup.close()
|
||||
},
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
<Cn-grid-item src="/static/feedback2.png" text="问题反馈" @click="submitFeedBack"></Cn-grid-item>
|
||||
</Cn-grid>
|
||||
</view>
|
||||
<uni-popup ref="popup" type="dialog" @maskClick='maskClick'>
|
||||
<uni-popup ref="popup" type="dialog" @maskClick="maskClick">
|
||||
<uni-popup-dialog
|
||||
mode="base"
|
||||
type="info"
|
||||
@@ -51,11 +51,10 @@
|
||||
:duration="0"
|
||||
confirmText="直连设备"
|
||||
cancelText="网关接入"
|
||||
cancelColor= '#007aff'
|
||||
cancelColor="#007aff"
|
||||
@close="close"
|
||||
@confirm="confirm"
|
||||
></uni-popup-dialog>
|
||||
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
@@ -105,7 +104,7 @@ export default {
|
||||
// },
|
||||
// })
|
||||
},
|
||||
maskClick(){
|
||||
maskClick() {
|
||||
this.$refs.popup.close()
|
||||
},
|
||||
close() {
|
||||
@@ -113,17 +112,15 @@ export default {
|
||||
this.$refs.popup.close()
|
||||
},
|
||||
confirm(value) {
|
||||
|
||||
if (this.devCount.engineeringListLength > 0) {
|
||||
// if (this.devCount.engineeringListLength > 0) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/device/new?type=4',
|
||||
})
|
||||
} else {
|
||||
uni.navigateTo({
|
||||
url: '/pages/engineering/new?from=index'
|
||||
})
|
||||
}
|
||||
|
||||
// } else {
|
||||
// uni.navigateTo({
|
||||
// url: '/pages/engineering/new?from=index',
|
||||
// })
|
||||
// }
|
||||
|
||||
this.$refs.popup.close()
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<view class="dateReport">
|
||||
<view class="pd20">
|
||||
<!-- <view class="pd20">
|
||||
<uni-segmented-control
|
||||
:current="curSub"
|
||||
class="subsection"
|
||||
@@ -8,42 +8,58 @@
|
||||
:values="subsectionList"
|
||||
@clickItem="sectionChange"
|
||||
/>
|
||||
</view> -->
|
||||
<view class="filterCriteria">
|
||||
<!-- 筛选条件 -->
|
||||
<Cn-filterCriteria @select="select" :singleChoice="true" :report="true"> </Cn-filterCriteria>
|
||||
</view>
|
||||
|
||||
<!-- 卡片 -->
|
||||
<view
|
||||
class="event-list"
|
||||
<scroll-view
|
||||
scroll-y="true"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
:refresher-triggered="triggered"
|
||||
refresher-enabled="true"
|
||||
class="event-list mt20"
|
||||
v-if="eventList.length != 0"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + 56) + 'px)', overflow: 'auto' }"
|
||||
:style="{ height: 'calc(100vh - ' + height + 'px)', overflow: 'auto' }"
|
||||
>
|
||||
<!-- 循环渲染事件项 -->
|
||||
<uni-card class="event-item" :class="item.type" v-for="(item, index) in eventList" :key="index">
|
||||
<uni-card class="event-item" :class="item.type" v-for="(item, index) in store.data" :key="index">
|
||||
<!-- 头部:图标 + 信息 + 操作 -->
|
||||
<view class="event-header">
|
||||
<view class="event-info">
|
||||
<view class="event-title">
|
||||
<text class="event-id" >{{ item.id }}</text>
|
||||
<text class="event-tags">{{ item.tag }}</text>
|
||||
<text class="event-id">{{ item.lineName }}</text>
|
||||
<view class="event-tags"
|
||||
>{{ selectValue.report == 0 ? item.startTime : item.startTime + '至' + item.endTime }}
|
||||
<view class="iconText ml10" @click="download(item)"
|
||||
><uni-icons type="arrow-down" color="#fff" size="16"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
<text>频率偏差越限111次</text>
|
||||
<text>不平衡度越限3次</text>
|
||||
<text>电压畸变率越限5次</text>
|
||||
<text>偶次电压越限5次</text>
|
||||
<text>{{ item.overLimitDesc == '' ? '该监测点暂无指标越限' : item.overLimitDesc }}</text>
|
||||
</view>
|
||||
<view class="downloadReport">
|
||||
<!-- <view class="downloadReport" @click="download">
|
||||
<uni-icons type="download" size="16" color="#376cf3"></uni-icons>下载报告
|
||||
</view>
|
||||
</view> -->
|
||||
</uni-card>
|
||||
<uni-load-more :status="status"></uni-load-more>
|
||||
</view>
|
||||
<Cn-empty v-else></Cn-empty>
|
||||
<uni-load-more
|
||||
v-if="store.status == 'loading' || (store.data && store.data.length > 0)"
|
||||
:status="store.status"
|
||||
></uni-load-more>
|
||||
<Cn-empty v-else style="top: 20%"></Cn-empty>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import list from '@/common/js/list'
|
||||
import { downloadHarmonicReport } from '@/common/api/report.js'
|
||||
|
||||
export default {
|
||||
components: {},
|
||||
props: {
|
||||
@@ -60,6 +76,7 @@ export default {
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
mixins: [list],
|
||||
data() {
|
||||
return {
|
||||
status: 'noMore',
|
||||
@@ -73,21 +90,134 @@ export default {
|
||||
status: '1',
|
||||
},
|
||||
],
|
||||
thisSelectValue: {},
|
||||
triggered: true,
|
||||
height: 0,
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
|
||||
mounted() {
|
||||
this.setHeight()
|
||||
},
|
||||
methods: {
|
||||
setHeight() {
|
||||
uni.createSelectorQuery()
|
||||
.select('.filterCriteria')
|
||||
.boundingClientRect((rect) => {
|
||||
//
|
||||
// #ifdef H5
|
||||
this.height = rect?.height + 130 || 0
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
this.height = rect?.height + 75 || 0
|
||||
// #endif
|
||||
})
|
||||
.exec()
|
||||
},
|
||||
sectionChange(index) {
|
||||
this.curSub = index.currentIndex
|
||||
},
|
||||
scrolltolower() {
|
||||
if (this.total != this.indexList.length) {
|
||||
this.$emit('scrolltolower')
|
||||
init() {
|
||||
if (this.selectValue.lineId == '') return
|
||||
|
||||
this.store = this.DataSource('/cs-report-boot/csAppReport/reportList')
|
||||
this.store.params.pageSize = 10000
|
||||
this.store.params.timeType = this.selectValue.report
|
||||
this.store.params.engineerId = this.selectValue.engineeringId
|
||||
this.store.params.projectId = this.selectValue.projectId
|
||||
this.store.params.devId = this.selectValue.deviceId
|
||||
this.store.params.lineId = this.selectValue.lineId
|
||||
this.store.params.time = this.selectValue.date
|
||||
// this.store.params.startTime = this.selectValue.range[0]
|
||||
// this.store.params.endTime = this.selectValue.range[1]
|
||||
this.store.loadedCallback = () => {}
|
||||
this.store.reload()
|
||||
},
|
||||
|
||||
select(value) {
|
||||
this.selectValue = value
|
||||
this.init()
|
||||
setTimeout(() => {
|
||||
this.setHeight()
|
||||
}, 100)
|
||||
},
|
||||
// 下载
|
||||
download(item) {
|
||||
uni.showLoading({
|
||||
title: '下载中,请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
downloadHarmonicReport({
|
||||
devId: this.selectValue.deviceId,
|
||||
endTime: item.endTime,
|
||||
engineerId: this.selectValue.engineeringId,
|
||||
lineId: this.selectValue.lineId,
|
||||
list: [],
|
||||
projectId: this.selectValue.projectId,
|
||||
startTime: item.startTime,
|
||||
time: '',
|
||||
timeType: this.selectValue.report,
|
||||
}).then((res) => {
|
||||
// 下载文件资源到本地
|
||||
uni.downloadFile({
|
||||
url: res.data, // 后端返回的线上文件路径
|
||||
success: function (res) {
|
||||
if (res.statusCode === 200) {
|
||||
// 文件到本地
|
||||
uni.saveFile({
|
||||
tempFilePath: res.tempFilePath, //临时路径
|
||||
success: function (data) {
|
||||
var savedFilePath = data.savedFilePath
|
||||
// 在app端执行
|
||||
// #ifdef APP-PLUS
|
||||
let osname = plus.os.name
|
||||
// 如果是安卓的话弹出提示
|
||||
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
title: '下载成功!',
|
||||
duration: 1000,
|
||||
})
|
||||
|
||||
// #endif
|
||||
//ios手机直接打开文件,手动存储文件到手机,Android手机从根目录创建文件夹,保存文件并改名
|
||||
setTimeout(() => {
|
||||
//打开文档查看
|
||||
uni.openDocument({
|
||||
filePath: data.savedFilePath,
|
||||
success: function (ress) {
|
||||
console.log('成功打开文件')
|
||||
},
|
||||
fail() {
|
||||
console.log('打开文件失败')
|
||||
},
|
||||
})
|
||||
}, 500)
|
||||
},
|
||||
})
|
||||
console.log('下载成功')
|
||||
} else {
|
||||
// this.status = 'noMore'
|
||||
uni.showToast({
|
||||
icon: 'error',
|
||||
mask: true,
|
||||
title: '下载失败!',
|
||||
duration: 1000,
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: function (res) {},
|
||||
})
|
||||
})
|
||||
},
|
||||
// 下拉
|
||||
refresherrefresh() {
|
||||
this.triggered = true
|
||||
uni.startPullDownRefresh()
|
||||
setTimeout(() => {
|
||||
this.triggered = false
|
||||
}, 500)
|
||||
},
|
||||
},
|
||||
|
||||
computed: {},
|
||||
@@ -101,12 +231,15 @@ export default {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.event-tags {
|
||||
font-size: 24rpx;
|
||||
display: flex;
|
||||
font-size: 27rpx !important ;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
|
||||
.event-detail {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
font-size: 25rpx !important;
|
||||
// display: grid;
|
||||
// grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.downloadReport {
|
||||
width: 100%;
|
||||
@@ -120,5 +253,31 @@ export default {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.filterCriteria {
|
||||
.nav {
|
||||
background-color: #fff;
|
||||
}
|
||||
.choose1 {
|
||||
background-color: #fff;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
/deep/ .uni-checkbox-input {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
/deep/ .uni-scroll-view-refresher {
|
||||
display: none;
|
||||
}
|
||||
.iconText {
|
||||
width: 45rpx;
|
||||
height: 45rpx;
|
||||
border-radius: 50%;
|
||||
background-color: $uni-theme-color;
|
||||
text-align: center;
|
||||
line-height: 45rpx;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,57 +10,106 @@
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 申请报表 -->
|
||||
<view v-if="curSub == 0">
|
||||
<!-- 申请报告 -->
|
||||
<view v-show="curSub == 0">
|
||||
<!-- apply -->
|
||||
<Apply :navHeight="navHeight"/>
|
||||
<Apply :navHeight="navHeight" />
|
||||
</view>
|
||||
|
||||
<!-- 申请记录 -->
|
||||
<view v-if="curSub == 1">
|
||||
<view
|
||||
class="record event-list"
|
||||
v-if="eventList.length != 0"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + 56) + 'px)', overflow: 'auto' }"
|
||||
>
|
||||
<!-- 循环渲染事件项 -->
|
||||
<uni-card class="event-item" :class="item.type" v-for="(item, index) in eventList" :key="index">
|
||||
<view class="title" :class="item.status == 1 ? 'completed' : 'incomplete'">
|
||||
<view> {{ item.status == 1 ? '已完成' : '未完成' }} </view>
|
||||
<view class="filterCriteria">
|
||||
<!-- 筛选条件 -->
|
||||
<Cn-filterCriteria @select="select" :showQianTree="false"> </Cn-filterCriteria>
|
||||
</view>
|
||||
<view
|
||||
class="record event-list mt20"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }"
|
||||
>
|
||||
<uni-card class="event-item" :class="item.type" v-for="(item, index) in store.data" :key="index">
|
||||
<!-- 头部:图标 + 信息 + 操作 -->
|
||||
<view class="event-header">
|
||||
<view
|
||||
class="event-icon"
|
||||
:style="{ backgroundColor: item.isComplete == 1 ? '#10b98120' : '#FF000020' }"
|
||||
>
|
||||
<!-- 动态图标:根据类型切换 -->
|
||||
<uni-icons
|
||||
custom-prefix="iconfont"
|
||||
type="icon-baogaoguanli"
|
||||
size="40"
|
||||
:color="item.isComplete == 1 ? '#10b981' : '#FF0000'"
|
||||
></uni-icons>
|
||||
</view>
|
||||
<view class="event-info">
|
||||
<view class="event-title">
|
||||
<text class="event-id">{{ item.id }}</text>
|
||||
<text class="event-tags">{{ item.tag }}</text>
|
||||
<text class="event-id">{{ item.lineName }}</text>
|
||||
</view>
|
||||
<view class="event-desc">
|
||||
<text>工程名称:{{ item.engineeringName }}</text>
|
||||
<text>项目名称:{{ item.projectName }}</text>
|
||||
<text>设备名称:{{ item.deviceName }}</text>
|
||||
<!-- <text>申请时间:{{ item.time }}</text>
|
||||
<text>事件数:{{ item.eventNums }}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="event-action">
|
||||
<view class="iconText" v-if="item.isComplete == 1" @click="download(item)"
|
||||
><uni-icons type="arrow-down" color="#fff" size="16"></uni-icons>
|
||||
</view>
|
||||
<view
|
||||
class="nav-menu nav-menu-btn"
|
||||
v-else-if="userInfo.authorities === 'operation_manager'"
|
||||
@click="generate(item)"
|
||||
>生成报告
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
<text>申请人:xxx</text>
|
||||
<text>电话号码:18888888888</text>
|
||||
<!-- <view class="device-body"> -->
|
||||
<view class="device-body-item">
|
||||
<text>申请人:</text>
|
||||
<text>{{ item.applyUser }}</text>
|
||||
</view>
|
||||
<view class="device-body-item">
|
||||
<text>申请时间:</text>
|
||||
<text>{{ item.time }}</text>
|
||||
</view>
|
||||
<view class="device-body-item">
|
||||
<text>暂降事件:</text>
|
||||
<text>{{ item.eventNums }}次</text>
|
||||
</view>
|
||||
<view class="device-body-item">
|
||||
<text>申请状态:</text>
|
||||
<text
|
||||
:style="{ color: item.isComplete == 1 ? '#10b981' : '#FF0000' }"
|
||||
style="font-weight: 700"
|
||||
>{{ item.isComplete == 1 ? '已完成' : '未完成' }}</text
|
||||
>
|
||||
</view>
|
||||
<view class="downloadReport">
|
||||
<!-- <u-icon :name="item.status == 1 ? 'download' : 'upload'" color="#376cf3" size="40"></u-icon> -->
|
||||
<uni-icons
|
||||
:type="item.status == 1 ? 'download' : 'upload'"
|
||||
size="16"
|
||||
color="#376cf3"
|
||||
></uni-icons>
|
||||
|
||||
{{ item.status == 1 ? '下载报告' : '生成报告' }}
|
||||
<!-- <view class="device-body-item">
|
||||
<text>申请时间:</text>
|
||||
<text>{{ item.time }}</text>
|
||||
</view> -->
|
||||
</view>
|
||||
|
||||
<!-- </view> -->
|
||||
</uni-card>
|
||||
<uni-load-more :status="status"></uni-load-more>
|
||||
<uni-load-more
|
||||
v-if="store.status == 'loading' || (store.data && store.data.length > 0)"
|
||||
:status="store.status"
|
||||
></uni-load-more>
|
||||
<Cn-empty v-else style="top: 30%"></Cn-empty>
|
||||
</view>
|
||||
<Cn-empty v-else></Cn-empty>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import Apply from './apply.vue'
|
||||
import list from '@/common/js/list'
|
||||
import { createEventReport, downloadEventReport } from '@/common/api/report.js'
|
||||
export default {
|
||||
components: { Apply },
|
||||
props: {
|
||||
@@ -81,99 +130,205 @@ export default {
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
mixins: [list],
|
||||
data() {
|
||||
return {
|
||||
value: ['0'],
|
||||
content: 123,
|
||||
curSub: 0,
|
||||
subsectionList: ['申请报表', '申请记录'],
|
||||
subsectionList: ['申请报告', '申请记录'],
|
||||
form: {
|
||||
type: 0,
|
||||
lindId: '',
|
||||
},
|
||||
status: 'noMore',
|
||||
eventList: [
|
||||
{
|
||||
id: '测试监测点',
|
||||
tag: '2026-01-23至2026-01-23',
|
||||
status: '1',
|
||||
},
|
||||
{
|
||||
id: '测试监测点',
|
||||
tag: '2026-01-23至2026-01-23',
|
||||
status: '0',
|
||||
},
|
||||
],
|
||||
userInfo: {},
|
||||
height: 0,
|
||||
selectValue: {},
|
||||
}
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
mounted() {
|
||||
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
|
||||
},
|
||||
computed: {},
|
||||
methods: {
|
||||
scrolltolower() {
|
||||
this.$emit('scrolltolower')
|
||||
setHeight() {
|
||||
uni.createSelectorQuery()
|
||||
.select('.filterCriteria')
|
||||
.boundingClientRect((rect) => {
|
||||
//
|
||||
// #ifdef H5
|
||||
this.height = rect?.height + 115 || 0
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
this.height = rect?.height + 10 || 0
|
||||
// #endif
|
||||
})
|
||||
.exec()
|
||||
},
|
||||
init() {
|
||||
this.store = this.DataSource('/cs-report-boot/csAppReport/getApplicationReport')
|
||||
this.store.params.startTime = this.$util.getMonthFirstAndLastDay(this.selectValue.date).firstDay
|
||||
this.store.params.endTime = this.$util.getMonthFirstAndLastDay(this.selectValue.date).lastDay
|
||||
this.store.loadedCallback = () => {}
|
||||
this.store.reload()
|
||||
},
|
||||
async select(val) {
|
||||
this.selectValue = val
|
||||
await this.init()
|
||||
this.setHeight()
|
||||
},
|
||||
getHeight() {},
|
||||
|
||||
sectionChange(index) {
|
||||
this.curSub = index.currentIndex
|
||||
},
|
||||
// 生成报告
|
||||
generate(item) {
|
||||
uni.showLoading({
|
||||
title: '生成中,请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
createEventReport({
|
||||
id: item.eventId,
|
||||
}).then((res) => {
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
title: '生成事件报告成功!',
|
||||
duration: 1000,
|
||||
})
|
||||
this.store.reload()
|
||||
})
|
||||
},
|
||||
// 下载报告
|
||||
download(item) {
|
||||
uni.showLoading({
|
||||
title: '下载中,请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
downloadEventReport({
|
||||
id: item.eventId,
|
||||
}).then((res) => {
|
||||
// 下载文件资源到本地
|
||||
uni.downloadFile({
|
||||
url: res.data, // 后端返回的线上文件路径
|
||||
success: function (res) {
|
||||
if (res.statusCode === 200) {
|
||||
// 文件到本地
|
||||
uni.saveFile({
|
||||
tempFilePath: res.tempFilePath, //临时路径
|
||||
success: function (data) {
|
||||
var savedFilePath = data.savedFilePath
|
||||
// 在app端执行
|
||||
// #ifdef APP-PLUS
|
||||
let osname = plus.os.name
|
||||
// 如果是安卓的话弹出提示
|
||||
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
title: '下载成功!',
|
||||
duration: 1000,
|
||||
})
|
||||
|
||||
// #endif
|
||||
//ios手机直接打开文件,手动存储文件到手机,Android手机从根目录创建文件夹,保存文件并改名
|
||||
setTimeout(() => {
|
||||
//打开文档查看
|
||||
uni.openDocument({
|
||||
filePath: data.savedFilePath,
|
||||
success: function (ress) {
|
||||
console.log('成功打开文件')
|
||||
},
|
||||
fail() {
|
||||
console.log('打开文件失败')
|
||||
},
|
||||
})
|
||||
}, 500)
|
||||
},
|
||||
})
|
||||
console.log('下载成功')
|
||||
} else {
|
||||
uni.showToast({
|
||||
icon: 'error',
|
||||
mask: true,
|
||||
title: '下载失败!',
|
||||
duration: 1000,
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: function (res) {},
|
||||
})
|
||||
})
|
||||
},
|
||||
},
|
||||
watch: {},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/pages/message1/index.scss';
|
||||
.event-title {
|
||||
justify-content: space-between;
|
||||
}
|
||||
.event-tags {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.event-detail {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
.downloadReport {
|
||||
width: 100%;
|
||||
background: #376cf320;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
color: #376cf3;
|
||||
font-weight: 600;
|
||||
border-radius: 15rpx;
|
||||
margin-top: 10rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
grid-template-columns: 1fr 1.2fr;
|
||||
}
|
||||
|
||||
.title {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
width: calc(100% - 36rpx);
|
||||
// margin: 0 10px;
|
||||
top: 0;
|
||||
border-radius: 4px 4px 0 0;
|
||||
padding: 2px 10px;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600px;
|
||||
// /deep/ .record {
|
||||
// .uni-card__content {
|
||||
// padding: 55rpx 20rpx 20rpx !important;
|
||||
// }
|
||||
// }
|
||||
.filterCriteria {
|
||||
.nav {
|
||||
background-color: #fff;
|
||||
}
|
||||
.choose1 {
|
||||
background-color: #fff;
|
||||
padding: 0 20rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-weight: 700;
|
||||
}
|
||||
.completed {
|
||||
background: #e1f3d8;
|
||||
color: #67c23a;
|
||||
}
|
||||
.incomplete {
|
||||
background: #fde2e2;
|
||||
color: #f56c6c;
|
||||
/deep/ .uni-checkbox-input {
|
||||
width: 30rpx;
|
||||
height: 30rpx;
|
||||
}
|
||||
font-size: 26rpx;
|
||||
}
|
||||
}
|
||||
// .device-body {
|
||||
// padding: 10rpx 20rpx 20rpx;
|
||||
|
||||
/deep/ .record {
|
||||
.uni-card__content {
|
||||
padding: 55rpx 20rpx 20rpx !important;
|
||||
.device-body-item {
|
||||
display: flex;
|
||||
// justify-content: space-between;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
line-height: 1.5;
|
||||
}
|
||||
// }
|
||||
.iconText {
|
||||
display: flex;
|
||||
width: 45rpx;
|
||||
height: 45rpx;
|
||||
border-radius: 50%;
|
||||
background-color: $uni-theme-color;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.nav-menu {
|
||||
height: 40rpx;
|
||||
padding: 6rpx 20rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 8rpx;
|
||||
line-height: 40rpx;
|
||||
background: #ebeaec;
|
||||
color: #666;
|
||||
&-active {
|
||||
background: #dfe5f7;
|
||||
color: $uni-theme-color;
|
||||
}
|
||||
&-btn {
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -33,11 +33,11 @@
|
||||
<view class="index">
|
||||
<!-- 运维 -->
|
||||
<YunWei :devCount="devCount" v-if="userInfo.authorities === 'operation_manager'" />
|
||||
<!-- 专职 -->
|
||||
<!-- 营销 -->
|
||||
<ZhuanZhi :devCount="devCount" v-if="userInfo.authorities === 'market_user'" />
|
||||
<!-- 工程 -->
|
||||
<GongCheng ref="gongCheng" :devCount="devCount" v-if="userInfo.authorities === 'engineering_user'" />
|
||||
<!-- 主用户 -->
|
||||
<!-- 正式 -->
|
||||
<ZhuYongHu :devCount="devCount" v-if="userInfo.authorities === 'app_vip_user'" />
|
||||
<!-- 游客 -->
|
||||
<YouKe :devCount="devCount" v-if="userInfo.authorities === 'tourist'"></YouKe>
|
||||
|
||||
@@ -117,13 +117,24 @@ export default {
|
||||
},
|
||||
|
||||
onShow() {
|
||||
const params = uni.getStorageSync('messageParams')
|
||||
console.log('🚀 ~ params:', params)
|
||||
this.getDevCount()
|
||||
this.$nextTick(() => {
|
||||
this.refresh()
|
||||
this.$refs.cnFilterCriteria.getProjectList()
|
||||
if (params.name != '') {
|
||||
this.$refs.cnFilterCriteria && this.$refs.cnFilterCriteria.external(params.name, params.id)
|
||||
}
|
||||
// this.refresh()
|
||||
this.$refs.TransientRef && this.$refs.TransientRef.getConfig()
|
||||
})
|
||||
},
|
||||
// 页面销毁
|
||||
onHide() {
|
||||
uni.setStorageSync('messageParams', {
|
||||
name: '',
|
||||
id: '',
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
setHeight() {
|
||||
uni.createSelectorQuery()
|
||||
@@ -132,7 +143,7 @@ export default {
|
||||
this.width = rect.width
|
||||
//
|
||||
// #ifdef H5
|
||||
this.navHeight = rect.height + 70
|
||||
this.navHeight = rect.height + 75
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
this.navHeight = rect.height + 20
|
||||
@@ -144,10 +155,7 @@ export default {
|
||||
refresh() {
|
||||
switch (this.current) {
|
||||
case 0:
|
||||
// this.$refs.TransientRef.getConfig()
|
||||
// this.$refs.TransientRef.filterValue = ''
|
||||
this.$refs.TransientRef.store.reload()
|
||||
|
||||
break
|
||||
case 1:
|
||||
this.$refs.SteadyStateRef.store.reload()
|
||||
@@ -171,7 +179,7 @@ export default {
|
||||
this.setHeight()
|
||||
}, 100)
|
||||
},
|
||||
|
||||
// 设置角标
|
||||
getDevCount() {
|
||||
if (uni.getStorageSync('projectList')[1] != undefined) {
|
||||
getDevCount(uni.getStorageSync('projectList')[1].engineeringId).then((res) => {
|
||||
@@ -242,7 +250,7 @@ export default {
|
||||
}
|
||||
|
||||
.segmented-control__text {
|
||||
font-size: 27rpx !important;
|
||||
font-size: 30rpx !important;
|
||||
color: rgb(96, 98, 102);
|
||||
}
|
||||
.segmented-control__item--text {
|
||||
|
||||
@@ -47,7 +47,7 @@ export default {
|
||||
|
||||
total: 6,
|
||||
loading: false,
|
||||
items: ['稳态报表', '暂态报表'],
|
||||
items: ['稳态报表', '暂降报告'],
|
||||
status: 'more', //more加载前 loading加载中 noMore加载后
|
||||
|
||||
navHeight: 0,
|
||||
@@ -99,7 +99,7 @@ export default {
|
||||
.boundingClientRect((rect) => {
|
||||
//
|
||||
// #ifdef H5
|
||||
this.navHeight = rect.height + 60
|
||||
this.navHeight = rect.height + 65
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
this.navHeight = rect.height + 10
|
||||
@@ -160,7 +160,7 @@ export default {
|
||||
}
|
||||
|
||||
.segmented-control__text {
|
||||
font-size: 27rpx !important;
|
||||
font-size: 30rpx !important;
|
||||
color: rgb(96, 98, 102);
|
||||
}
|
||||
.segmented-control__item--text {
|
||||
|
||||
@@ -121,7 +121,7 @@ export default {
|
||||
font-size: 26rpx;
|
||||
|
||||
.detail-content-title {
|
||||
font-size: 32rpx;
|
||||
font-size: 28rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
display: flex;
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
>
|
||||
<!-- <view class="content-item-header-right-des">{{ item.subTitle }}</view> -->
|
||||
</view>
|
||||
<view class="ml10" v-if="type === '0' || item.status != '1'">🔍</view>
|
||||
<view class="ml10" v-if="type === '0' || item.status != '1'"> <uni-icons type="search" size="25"></uni-icons></view>
|
||||
</view>
|
||||
<view class="content-item-footer">{{ item.subTitle }}</view>
|
||||
</view>
|
||||
|
||||
@@ -82,7 +82,7 @@ export default {
|
||||
font-size: 26rpx;
|
||||
|
||||
.detail-content-title {
|
||||
font-size: 32rpx;
|
||||
font-size: 28rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,14 @@
|
||||
<!-- 运行告警 -->
|
||||
|
||||
<!-- 卡片 -->
|
||||
<view class="event-list" :style="{ height: 'calc(100vh - ' + (navHeight + 10) + 'px)', overflow: 'auto' }">
|
||||
<scroll-view
|
||||
scroll-y="true"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
:refresher-triggered="triggered"
|
||||
refresher-enabled="true"
|
||||
class="event-list"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + 10) + 'px)', overflow: 'auto' }"
|
||||
>
|
||||
<!-- 循环渲染事件项 -->
|
||||
<uni-card
|
||||
class="event-item"
|
||||
@@ -19,7 +26,7 @@
|
||||
<uni-icons
|
||||
custom-prefix="iconfont"
|
||||
type="icon-terminal-box-fill"
|
||||
size="22"
|
||||
size="30"
|
||||
color="#FF0000"
|
||||
></uni-icons>
|
||||
<view class="badge1" v-if="item.isRead == 0"> </view>
|
||||
@@ -29,7 +36,7 @@
|
||||
<text class="event-id">{{ item.date }}发生告警终端{{ item.warnNums }}台</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="event-action"> 🔍 </view>
|
||||
<view class="event-action"> <uni-icons type="search" size="25"></uni-icons> </view>
|
||||
</view>
|
||||
</uni-card>
|
||||
<uni-load-more
|
||||
@@ -37,7 +44,7 @@
|
||||
:status="store.status"
|
||||
></uni-load-more>
|
||||
<Cn-empty v-else style="top: 20%"></Cn-empty>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
@@ -57,6 +64,7 @@ export default {
|
||||
mixins: [list],
|
||||
data() {
|
||||
return {
|
||||
triggered: true,
|
||||
status: 'noMore', //more加载前 loading加载中 noMore加载后
|
||||
}
|
||||
},
|
||||
@@ -74,6 +82,7 @@ export default {
|
||||
this.store.loadedCallback = () => {
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
this.store.reload()
|
||||
},
|
||||
jump(item) {
|
||||
@@ -81,6 +90,14 @@ export default {
|
||||
item.status = '1'
|
||||
uni.navigateTo({ url: '/pages/message1/comp/alarmDetails?detail=' + encodeURIComponent(str) })
|
||||
},
|
||||
// 下拉
|
||||
refresherrefresh() {
|
||||
this.triggered = true
|
||||
uni.startPullDownRefresh()
|
||||
setTimeout(() => {
|
||||
this.triggered = false
|
||||
}, 500)
|
||||
},
|
||||
},
|
||||
|
||||
computed: {},
|
||||
@@ -123,4 +140,7 @@ export default {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
/deep/ .uni-scroll-view-refresher {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -13,6 +13,9 @@ export default {
|
||||
store: {
|
||||
type: [Object],
|
||||
},
|
||||
filterValue: {
|
||||
type: [String],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -52,9 +55,10 @@ export default {
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
splitNumber: 10,
|
||||
minInterval: 3,
|
||||
minInterval: 20,
|
||||
position: 'top',
|
||||
rotate: 90,
|
||||
max: 140,
|
||||
axisLabel: {
|
||||
rotate: -90,
|
||||
},
|
||||
@@ -103,6 +107,7 @@ export default {
|
||||
pointF: [],
|
||||
pointFun: [],
|
||||
data: [],
|
||||
maxXAxis: 140,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@@ -129,6 +134,7 @@ export default {
|
||||
this.pointF = []
|
||||
this.pointFun = []
|
||||
var total = 0
|
||||
let dataList = [0]
|
||||
total = this.data.length
|
||||
if (total == 0) {
|
||||
} else {
|
||||
@@ -137,7 +143,7 @@ export default {
|
||||
var xx = this.data[i].evtParamTm.replace(/s/g, '')
|
||||
var yy = this.data[i].evtParamVVaDepth.replace(/%/g, '')
|
||||
var time = this.data[i].startTime.replace('T', ' ')
|
||||
|
||||
dataList.push(yy)
|
||||
point = [yy, xx, time, this.data[i]]
|
||||
|
||||
if (xx < 0.05) {
|
||||
@@ -191,6 +197,20 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.option.xAxis.max = Math.max(
|
||||
140,
|
||||
Math.ceil(
|
||||
Math.max(
|
||||
...dataList
|
||||
.filter((item) => {
|
||||
return item !== '-' && !isNaN(Number(item))
|
||||
})
|
||||
.map((item) => Number(item)),
|
||||
) / 10,
|
||||
) * 10,
|
||||
) //this.maxXAxis
|
||||
|
||||
this.option.series[1].data = this.pointF
|
||||
this.option.series[2].data = this.pointFun
|
||||
|
||||
@@ -204,7 +224,6 @@ export default {
|
||||
bindChartClickEvent() {
|
||||
if (!this.echartRef) return
|
||||
this.echartRef.on('click', (params) => {
|
||||
console.log('🚀 ~ params:', params.value[3])
|
||||
// 点击查看详情
|
||||
let item = params.value[3]
|
||||
let str = JSON.stringify(item).replace(/%/g, '百分比')
|
||||
@@ -219,12 +238,20 @@ export default {
|
||||
store: {
|
||||
handler(val, oldVal) {
|
||||
this.status = val.status
|
||||
this.data = val.data
|
||||
this.data = (val.data || []).filter((k) =>
|
||||
this.filterValue == '' ? k : k.showName == this.filterValue,
|
||||
)
|
||||
this.gongfunction()
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
filterValue: {
|
||||
handler(val, oldVal) {
|
||||
this.data = (this.store.data || []).filter((k) => (val == '' ? k : k.showName == val))
|
||||
this.gongfunction()
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -13,6 +13,9 @@ export default {
|
||||
store: {
|
||||
type: [Object],
|
||||
},
|
||||
filterValue: {
|
||||
type: [String],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -35,7 +38,7 @@ export default {
|
||||
itemWidth: 10,
|
||||
itemHeight: 10,
|
||||
itemGap: 8,
|
||||
padding: [5, 5 ,5 ,10],
|
||||
padding: [5, 5, 5, 10],
|
||||
},
|
||||
|
||||
color: ['#FF8C00', '#00BFFF', 'green', 'red'],
|
||||
@@ -141,108 +144,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// gongfunction() {
|
||||
// var standI = 0
|
||||
// var unstandI = 0
|
||||
// this.pointI = []
|
||||
// this.pointIun = []
|
||||
// var total = 0
|
||||
// total = this.data.length
|
||||
// if (total == 0) {
|
||||
// } else {
|
||||
// for (var i = 0; i < this.data.length; i++) {
|
||||
// var point = []
|
||||
// var xx = this.data[i].evtParamTm.replace(/s/g, '')
|
||||
// var yy = this.data[i].evtParamVVaDepth.replace(/%/g, '')
|
||||
// var time = this.data[i].startTime.replace('T', ' ')
|
||||
|
||||
// point = [yy, xx, time, this.data[i]]
|
||||
|
||||
// if (xx <= 0.003) {
|
||||
// var line = 0
|
||||
// line = 230 - 30000 * xx
|
||||
// if (yy > line) {
|
||||
// unstandI++
|
||||
// this.pointIun.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'red' } },
|
||||
// })
|
||||
// } else {
|
||||
// standI++
|
||||
// this.pointI.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'green' } },
|
||||
// })
|
||||
// }
|
||||
// } else if (xx <= 0.02) {
|
||||
// if (yy > 120) {
|
||||
// unstandI++
|
||||
// this.pointIun.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'red' } },
|
||||
// })
|
||||
// } else {
|
||||
// standI++
|
||||
// this.pointI.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'green' } },
|
||||
// })
|
||||
// }
|
||||
// } else if (xx <= 0.5) {
|
||||
// if (yy > 120 || yy < 70) {
|
||||
// unstandI++
|
||||
// this.pointIun.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'red' } },
|
||||
// })
|
||||
// } else {
|
||||
// standI++
|
||||
// this.pointI.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'green' } },
|
||||
// })
|
||||
// }
|
||||
// } else if (xx <= 10) {
|
||||
// if (yy > 110 || yy < 80) {
|
||||
// unstandI++
|
||||
// this.pointIun.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'red' } },
|
||||
// })
|
||||
// } else {
|
||||
// standI++
|
||||
// this.pointI.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'green' } },
|
||||
// })
|
||||
// }
|
||||
// } else {
|
||||
// if (yy > 110 || yy < 90) {
|
||||
// unstandI++
|
||||
// this.pointIun.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'red' } },
|
||||
// })
|
||||
// } else {
|
||||
// standI++
|
||||
// this.pointI.push({
|
||||
// value: point,
|
||||
// itemStyle: { normal: { color: 'green' } },
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// this.option.series[2].data = this.pointI
|
||||
// this.option.series[3].data = this.pointIun
|
||||
|
||||
// if (this.echartRef) {
|
||||
// this.echartRef.setOption(this.option, true)
|
||||
// } else {
|
||||
// this.initChart()
|
||||
// }
|
||||
// },
|
||||
|
||||
gongfunction() {
|
||||
// 初始化计数与数据数组
|
||||
let normalCount = 0
|
||||
@@ -329,12 +230,20 @@ export default {
|
||||
store: {
|
||||
handler(val, oldVal) {
|
||||
this.status = val.status
|
||||
this.data = val.data
|
||||
this.data = (val.data || []).filter((k) =>
|
||||
this.filterValue == '' ? k : k.showName == this.filterValue,
|
||||
)
|
||||
this.gongfunction()
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
filterValue: {
|
||||
handler(val, oldVal) {
|
||||
this.data = (this.store.data || []).filter((k) => (val == '' ? k : k.showName == val))
|
||||
this.gongfunction()
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
<!-- <view class="detail-content-title mb20">发生时间</view> -->
|
||||
<view>{{ detail.date }}</view>
|
||||
</view>
|
||||
<view class="detail-content">
|
||||
<view class="detail-content-title mb20">终端告警列表</view>
|
||||
<view class="detail-content" style="padding: 0px">
|
||||
<view class="detail-content-title mb20 pt20 pl20">终端告警列表</view>
|
||||
|
||||
<uni-collapse accordion>
|
||||
<!-- <uni-collapse accordion v-model="collapseValue">
|
||||
<uni-collapse-item :title="item.devName" v-for="item in list">
|
||||
<template v-slot:title>
|
||||
<view class="collapseTop">
|
||||
@@ -27,7 +27,6 @@
|
||||
<view class="mb10 ml12 frequency">
|
||||
<view>工程名称:{{ item.engineeringName }}</view></view
|
||||
>
|
||||
|
||||
<view class="mb10 ml12 frequency">
|
||||
<view>通讯信息:</view>
|
||||
<view style="flex: 1">
|
||||
@@ -50,8 +49,62 @@
|
||||
>
|
||||
</view>
|
||||
</uni-collapse-item>
|
||||
</uni-collapse> -->
|
||||
<view class="event-list">
|
||||
<uni-card
|
||||
class="event-item"
|
||||
:class="item.type"
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
@click="jump(item)"
|
||||
>
|
||||
<!-- 头部:图标 + 信息 + 操作 -->
|
||||
<view class="event-header">
|
||||
<view class="event-icon">
|
||||
<!-- 动态图标:根据类型切换 -->
|
||||
<uni-icons
|
||||
custom-prefix="iconfont"
|
||||
type="icon-terminal-box-fill"
|
||||
size="35"
|
||||
color="#FF0000"
|
||||
></uni-icons>
|
||||
<view class="badge1" v-if="item.status == 0"> </view>
|
||||
</view>
|
||||
<view class="event-info">
|
||||
<view class="event-title">
|
||||
<text class="event-id">{{ item.devName }}</text>
|
||||
</view>
|
||||
<view class="event-desc">
|
||||
<text>工程名称:{{ item.engineeringName }}</text>
|
||||
<text>项目名称:{{ item.projectName }}</text>
|
||||
<!-- <text>事件时间:{{ item.startTime }}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
<uni-collapse accordion>
|
||||
<uni-collapse-item
|
||||
:title="
|
||||
item.interruptCounts == 0 ? '通讯正常' : `通讯中断 ${item.interruptCounts} 次`
|
||||
"
|
||||
>
|
||||
<view v-for="date in item.interruptDetails" class="textBox mb10">{{ date }}</view>
|
||||
</uni-collapse-item>
|
||||
<uni-collapse-item
|
||||
:title="
|
||||
item.warnCounts == 0 ? '暂无终端告警信息' : `终端告警 ${item.warnCounts} 次`
|
||||
"
|
||||
>
|
||||
<view v-for="val in item.warnDetails" class="textBox mb10">
|
||||
{{ val.warnEventTime + '发生' + val.warnEventDesc }}
|
||||
</view>
|
||||
</uni-collapse-item>
|
||||
</uni-collapse>
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
@@ -64,13 +117,13 @@ export default {
|
||||
loading: true,
|
||||
detail: {},
|
||||
limit: '',
|
||||
accordionVal: '1',
|
||||
collapseValue: '0',
|
||||
|
||||
list: [],
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.loading = false
|
||||
this.loading = true
|
||||
this.detail = JSON.parse(decodeURIComponent(options.detail).replace(/百分比/g, '%'))
|
||||
this.init()
|
||||
if (this.detail.isRead != 1) {
|
||||
@@ -81,7 +134,6 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.loading = false
|
||||
queryAlarmDetail({
|
||||
devList: this.detail.devIds,
|
||||
time: this.detail.date,
|
||||
@@ -97,7 +149,8 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
@import '../index.scss';
|
||||
.detail {
|
||||
padding: 20rpx 0;
|
||||
|
||||
@@ -105,10 +158,10 @@ export default {
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
font-size: 26rpx;
|
||||
|
||||
.detail-content-title {
|
||||
font-size: 32rpx;
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -117,18 +170,38 @@ export default {
|
||||
padding: 10rpx 0;
|
||||
margin-left: 15px;
|
||||
.name {
|
||||
font-size: 26rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
.frequency {
|
||||
display: flex;
|
||||
font-size: 24rpx;
|
||||
font-size: 26rpx;
|
||||
// color: #666666;
|
||||
}
|
||||
}
|
||||
.textBox {
|
||||
border-bottom: 1px solid #eee;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
}
|
||||
.event-list {
|
||||
background: #fff;
|
||||
.event-icon {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
background-color: #ff000020;
|
||||
}
|
||||
}
|
||||
/deep/ .uni-collapse-item__title-box {
|
||||
padding: 0 15px 0 0;
|
||||
height: 56rpx;
|
||||
line-height: 56rpx;
|
||||
font-size: 26rpx !important;
|
||||
color: #666666;
|
||||
span {
|
||||
font-size: 26rpx !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
<template>
|
||||
<view class="preview-container">
|
||||
<!-- 右上角关闭按钮 -->
|
||||
<view class="close-btn" @click="close">
|
||||
<text class="close-icon">✕</text>
|
||||
</view>
|
||||
<!-- 右上角按钮组 -->
|
||||
<view class="btn-group">
|
||||
<!-- 缩小按钮 -->
|
||||
<!-- <view class="btn zoom-out-btn" @click="zoomOut">
|
||||
<text class="btn-icon">−</text>
|
||||
</view> -->
|
||||
|
||||
<!-- 放大按钮 -->
|
||||
<!-- <view class="btn zoom-in-btn" @click="zoomIn">
|
||||
<text class="btn-icon">+</text>
|
||||
</view> -->
|
||||
|
||||
<!-- 下载按钮 -->
|
||||
<view class="download-btn" @click="downloadImage">
|
||||
<text class="download-icon">⬇️</text>
|
||||
<view class="btn download-btn" @click="downloadImage">
|
||||
<text class="btn-icon">⬇</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 图片预览区域,使用movable-area和movable-view实现缩放移动 -->
|
||||
@@ -19,12 +27,16 @@
|
||||
:scale-min="0.5"
|
||||
:scale-max="3"
|
||||
:scale-value="scaleValue"
|
||||
@scale="onScale"
|
||||
|
||||
@touchstart="onTouchStart"
|
||||
@touchend="onTouchEnd"
|
||||
:x="x"
|
||||
:y="y"
|
||||
:animation="true"
|
||||
:animation-duration="300"
|
||||
:style="{
|
||||
width: rotatedWidth + 'px',
|
||||
height: rotatedHeight + 'px'
|
||||
height: rotatedHeight + 'px',
|
||||
}"
|
||||
>
|
||||
<view
|
||||
@@ -33,7 +45,7 @@
|
||||
width: imgWidth + 'px',
|
||||
height: imgHeight + 'px',
|
||||
transform: 'rotate(90deg)',
|
||||
transformOrigin: 'center center'
|
||||
transformOrigin: 'center center',
|
||||
}"
|
||||
>
|
||||
<image
|
||||
@@ -42,7 +54,7 @@
|
||||
mode="aspectFill"
|
||||
:style="{
|
||||
width: imgWidth + 'px',
|
||||
height: imgHeight + 'px'
|
||||
height: imgHeight + 'px',
|
||||
}"
|
||||
@load="onImageLoad"
|
||||
></image>
|
||||
@@ -50,10 +62,7 @@
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
|
||||
<!-- 图片信息提示 -->
|
||||
<view class="scale-tip" v-if="showScaleTip">
|
||||
当前缩放: {{ Math.round(scaleValue * 100) }}%
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -66,8 +75,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
imageUrl: '',
|
||||
// 缩放相关
|
||||
scaleValue: 1,
|
||||
// 缩放相关 - 默认0.5
|
||||
scaleValue: 0.6,
|
||||
x: 0,
|
||||
y: 0,
|
||||
// 图片原始尺寸
|
||||
@@ -81,69 +90,131 @@ export default {
|
||||
tipTimer: null,
|
||||
// 屏幕尺寸
|
||||
windowWidth: 0,
|
||||
windowHeight: 0
|
||||
windowHeight: 0,
|
||||
// 缩放步长
|
||||
zoomStep: 0.2,
|
||||
// 动画控制
|
||||
isTouching: false,
|
||||
animationTimer: null
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// 获取屏幕尺寸
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
this.windowWidth = systemInfo.windowWidth;
|
||||
this.windowHeight = systemInfo.windowHeight;
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
this.windowWidth = systemInfo.windowWidth
|
||||
this.windowHeight = systemInfo.windowHeight
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 图片加载完成后获取尺寸
|
||||
onImageLoad(e) {
|
||||
const { width, height } = e.detail;
|
||||
const { width, height } = e.detail
|
||||
|
||||
// 保存原始尺寸
|
||||
this.imgWidth = width;
|
||||
this.imgHeight = height;
|
||||
this.imgWidth = width
|
||||
this.imgHeight = height
|
||||
|
||||
// 旋转90度后,宽度和高度互换
|
||||
this.rotatedWidth = height; // 旋转后宽度 = 原高度
|
||||
this.rotatedHeight = width; // 旋转后高度 = 原宽度
|
||||
this.rotatedWidth = height // 旋转后宽度 = 原高度
|
||||
this.rotatedHeight = width // 旋转后高度 = 原宽度
|
||||
|
||||
// 计算初始位置居中
|
||||
this.resetPosition();
|
||||
|
||||
console.log('图片加载:', {width, height}, '旋转后:', {rotatedWidth: this.rotatedWidth, rotatedHeight: this.rotatedHeight});
|
||||
// 计算初始位置居中(考虑0.5缩放)
|
||||
this.resetPosition()
|
||||
},
|
||||
|
||||
// 重置位置到中心
|
||||
// 重置位置到中心(考虑当前缩放比例)
|
||||
resetPosition() {
|
||||
// 计算居中的偏移量
|
||||
this.x = (this.windowWidth - this.rotatedWidth) / 2;
|
||||
this.y = (this.windowHeight - this.rotatedHeight) / 2;
|
||||
// 计算居中的偏移量,考虑缩放比例
|
||||
const displayWidth = this.rotatedWidth * this.scaleValue
|
||||
const displayHeight = this.rotatedHeight * this.scaleValue
|
||||
|
||||
console.log('重置位置:', {x: this.x, y: this.y, windowWidth: this.windowWidth, windowHeight: this.windowHeight});
|
||||
this.x = (this.windowWidth - displayWidth) / 2
|
||||
this.y = (this.windowHeight - displayHeight) / 2
|
||||
},
|
||||
|
||||
// 触摸开始
|
||||
onTouchStart() {
|
||||
this.isTouching = true
|
||||
},
|
||||
|
||||
// 触摸结束
|
||||
onTouchEnd() {
|
||||
this.isTouching = false
|
||||
},
|
||||
|
||||
// 缩放事件处理
|
||||
onScale(e) {
|
||||
this.scaleValue = e.detail.scale;
|
||||
this.scaleValue = e.detail.scale
|
||||
|
||||
// 显示缩放提示
|
||||
this.showScaleTip = true;
|
||||
this.showScaleTip = true
|
||||
if (this.tipTimer) {
|
||||
clearTimeout(this.tipTimer);
|
||||
clearTimeout(this.tipTimer)
|
||||
}
|
||||
this.tipTimer = setTimeout(() => {
|
||||
this.showScaleTip = false;
|
||||
}, 1500);
|
||||
this.showScaleTip = false
|
||||
}, 1500)
|
||||
},
|
||||
|
||||
// 关闭预览
|
||||
close() {
|
||||
uni.navigateBack();
|
||||
// 放大
|
||||
zoomIn() {
|
||||
// 计算新的缩放值,不超过最大值
|
||||
const newScale = Math.min(this.scaleValue + this.zoomStep, 3)
|
||||
this.setScaleWithAnimation(newScale)
|
||||
},
|
||||
|
||||
// 缩小
|
||||
zoomOut() {
|
||||
// 计算新的缩放值,不低于最小值
|
||||
const newScale = Math.max(this.scaleValue - this.zoomStep, 0.5)
|
||||
this.setScaleWithAnimation(newScale)
|
||||
},
|
||||
|
||||
// 带动画的设置缩放值
|
||||
setScaleWithAnimation(newScale) {
|
||||
// 保存旧的缩放值用于动画
|
||||
const oldScale = this.scaleValue
|
||||
|
||||
// 计算缩放中心点(屏幕中心)
|
||||
const centerX = this.windowWidth / 2
|
||||
const centerY = this.windowHeight / 2
|
||||
|
||||
// 计算当前图片中心点
|
||||
const oldDisplayWidth = this.rotatedWidth * oldScale
|
||||
const oldDisplayHeight = this.rotatedHeight * oldScale
|
||||
const oldCenterX = this.x + oldDisplayWidth / 2
|
||||
const oldCenterY = this.y + oldDisplayHeight / 2
|
||||
|
||||
// 计算偏移量,使缩放后图片中心保持在屏幕中心
|
||||
const newDisplayWidth = this.rotatedWidth * newScale
|
||||
const newDisplayHeight = this.rotatedHeight * newScale
|
||||
const newX = centerX - newDisplayWidth / 2
|
||||
const newY = centerY - newDisplayHeight / 2
|
||||
|
||||
// 更新缩放值和位置
|
||||
this.scaleValue = newScale
|
||||
this.x = newX
|
||||
this.y = newY
|
||||
|
||||
// 显示缩放提示
|
||||
this.showScaleTip = true
|
||||
if (this.tipTimer) {
|
||||
clearTimeout(this.tipTimer)
|
||||
}
|
||||
this.tipTimer = setTimeout(() => {
|
||||
this.showScaleTip = false
|
||||
}, 1500)
|
||||
|
||||
console.log('缩放:', {oldScale, newScale, x: this.x, y: this.y})
|
||||
},
|
||||
|
||||
// 下载图片
|
||||
downloadImage() {
|
||||
uni.showLoading({
|
||||
title: '下载中...'
|
||||
});
|
||||
title: '下载中,请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
|
||||
// 先获取图片信息(如果是网络图片需要先下载)
|
||||
uni.downloadFile({
|
||||
@@ -154,15 +225,15 @@ export default {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
});
|
||||
icon: 'success',
|
||||
})
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.hideLoading();
|
||||
console.error('保存失败', err);
|
||||
uni.hideLoading()
|
||||
console.error('保存失败', err)
|
||||
|
||||
// 处理用户拒绝权限的情况
|
||||
if (err.errMsg.includes('auth deny')) {
|
||||
@@ -173,52 +244,49 @@ export default {
|
||||
if (res.confirm) {
|
||||
uni.openSetting({
|
||||
success: (settingRes) => {
|
||||
console.log('打开设置页面', settingRes);
|
||||
console.log('打开设置页面', settingRes)
|
||||
},
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
icon: 'none'
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
})
|
||||
} else {
|
||||
uni.hideLoading();
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
title: '下载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.hideLoading();
|
||||
console.error('下载失败', err);
|
||||
uni.hideLoading()
|
||||
console.error('下载失败', err)
|
||||
uni.showToast({
|
||||
title: '下载失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
// 双击重置缩放和位置(可选功能)
|
||||
onDoubleTap() {
|
||||
this.scaleValue = 1;
|
||||
this.resetPosition();
|
||||
}
|
||||
},
|
||||
|
||||
// 页面返回前清理定时器
|
||||
onUnload() {
|
||||
if (this.tipTimer) {
|
||||
clearTimeout(this.tipTimer);
|
||||
clearTimeout(this.tipTimer)
|
||||
}
|
||||
if (this.animationTimer) {
|
||||
cancelAnimationFrame(this.animationTimer)
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -241,62 +309,89 @@ export default {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// 添加硬件加速
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: transform 0.1s ease;
|
||||
// 添加硬件加速
|
||||
transform: translateZ(0) rotate(90deg);
|
||||
will-change: transform;
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
transition: transform 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
|
||||
}
|
||||
|
||||
.preview-img {
|
||||
display: block;
|
||||
// 添加硬件加速
|
||||
transform: translateZ(0);
|
||||
will-change: transform;
|
||||
backface-visibility: hidden;
|
||||
-webkit-backface-visibility: hidden;
|
||||
}
|
||||
|
||||
// 关闭按钮
|
||||
.close-btn {
|
||||
// 按钮组
|
||||
.btn-group {
|
||||
position: fixed;
|
||||
top: 30rpx;
|
||||
right: 30rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 20rpx;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
// 通用按钮样式
|
||||
.btn {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
// 按钮不参与动画
|
||||
transform: translateZ(0);
|
||||
transition: background-color 0.2s ease;
|
||||
|
||||
.close-icon {
|
||||
&:active {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
line-height: 1;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
// 缩小按钮
|
||||
.zoom-out-btn {
|
||||
.btn-icon {
|
||||
font-size: 50rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 放大按钮
|
||||
.zoom-in-btn {
|
||||
.btn-icon {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
// 下载按钮
|
||||
.download-btn {
|
||||
position: fixed;
|
||||
top: 30rpx;
|
||||
right: 110rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
|
||||
.download-icon {
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
line-height: 1;
|
||||
.btn-icon {
|
||||
font-size: 35rpx;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,7 +400,7 @@ export default {
|
||||
position: fixed;
|
||||
bottom: 100rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
transform: translateX(-50%) translateZ(0);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
padding: 10rpx 30rpx;
|
||||
@@ -315,12 +410,22 @@ export default {
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
animation: fadeInOut 1.5s ease;
|
||||
// 提示不参与动画
|
||||
will-change: opacity;
|
||||
}
|
||||
|
||||
@keyframes fadeInOut {
|
||||
0% { opacity: 0; }
|
||||
15% { opacity: 1; }
|
||||
85% { opacity: 1; }
|
||||
100% { opacity: 0; }
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
15% {
|
||||
opacity: 1;
|
||||
}
|
||||
85% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -21,7 +21,7 @@
|
||||
>指标越限详情<text class="prompt">(仅显示较为严重的10次)</text></view
|
||||
>
|
||||
|
||||
<uni-collapse accordion>
|
||||
<uni-collapse accordion v-model="collapseValue">
|
||||
<uni-collapse-item :title="item.targetName" v-for="item in list">
|
||||
<view class="data-table">
|
||||
<view class="table-header">
|
||||
@@ -57,6 +57,7 @@ export default {
|
||||
loading: true,
|
||||
detail: {},
|
||||
list: [],
|
||||
collapseValue: '0',
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
@@ -96,10 +97,10 @@ export default {
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
font-size: 26rpx;
|
||||
|
||||
.detail-content-title {
|
||||
font-size: 32rpx;
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
}
|
||||
@@ -130,7 +131,7 @@ export default {
|
||||
text {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
font-size: 26rpx;
|
||||
// color: #333;
|
||||
&:first-child {
|
||||
// text-align: left;
|
||||
@@ -140,9 +141,13 @@ export default {
|
||||
}
|
||||
.table-header {
|
||||
padding: 0rpx;
|
||||
padding-bottom: 10rpx;
|
||||
}
|
||||
}
|
||||
/deep/ .uni-collapse-item__title-text{
|
||||
/deep/ .uni-collapse-item__title-text {
|
||||
font-weight: 700;
|
||||
span {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -83,10 +83,10 @@ export default {
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
font-size: 26rpx;
|
||||
|
||||
.detail-content-title {
|
||||
font-size: 32rpx;
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
/* 第一个盒子的特殊样式(蓝色背景) */
|
||||
.box:first-child {
|
||||
flex: 1.7;
|
||||
}
|
||||
.boxClick {
|
||||
background-color: $uni-theme-color;
|
||||
color: #ffffff;
|
||||
}
|
||||
@@ -83,7 +85,13 @@
|
||||
background-color: #e6a23c20;
|
||||
}
|
||||
.interrupt .event-icon {
|
||||
background-color: #90939920;
|
||||
background-color: #00000020;
|
||||
}
|
||||
.transient .event-icon {
|
||||
background-color: #8b5cf620;
|
||||
}
|
||||
.unknown .event-icon {
|
||||
background-color: #6b728020;
|
||||
}
|
||||
.event-icon image {
|
||||
width: 48rpx;
|
||||
@@ -101,7 +109,7 @@
|
||||
flex-wrap: wrap; /* 适配小屏,防止文字溢出 */
|
||||
}
|
||||
.event-id {
|
||||
font-size: 15px;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
margin-right: 16rpx;
|
||||
@@ -115,16 +123,24 @@
|
||||
height: 38rpx;
|
||||
}
|
||||
.sag-tag {
|
||||
background-color: #ecf5ff;
|
||||
background-color: #2563eb20;
|
||||
color: #2563eb;
|
||||
}
|
||||
.swell-tag {
|
||||
background-color: #fdf6ec;
|
||||
background-color: #e6a23c20;
|
||||
color: #e6a23c;
|
||||
}
|
||||
.interrupt-tag {
|
||||
background-color: #f4f4f5;
|
||||
color: #909399;
|
||||
background-color: #6b728020;
|
||||
color: #6b7280;
|
||||
}
|
||||
.transient-tag {
|
||||
background-color: #8b5cf620;
|
||||
color: #8b5cf6;
|
||||
}
|
||||
.unknown-tag {
|
||||
background-color: #6b728020;
|
||||
color: #6b7280;
|
||||
}
|
||||
/* 描述文本 */
|
||||
.event-desc {
|
||||
@@ -155,7 +171,7 @@
|
||||
|
||||
/* 详情文本 */
|
||||
.event-detail {
|
||||
font-size: 24rpx;
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
line-height: 1.5;
|
||||
padding-top: 10rpx;
|
||||
@@ -174,7 +190,6 @@
|
||||
height: 58rpx;
|
||||
}
|
||||
.uni-input {
|
||||
|
||||
font-size: 24rpx;
|
||||
color: #2563eb;
|
||||
margin-right: 10rpx;
|
||||
|
||||
@@ -3,8 +3,14 @@
|
||||
<!-- 运行事件 -->
|
||||
|
||||
<!-- 卡片 -->
|
||||
<view
|
||||
class="event-list" :style="{ height: 'calc(100vh - ' + (navHeight + 10) + 'px)', overflow: 'auto' }">
|
||||
<scroll-view
|
||||
scroll-y="true"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
:refresher-triggered="triggered"
|
||||
refresher-enabled="true"
|
||||
class="event-list"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + 10) + 'px)', overflow: 'auto' }"
|
||||
>
|
||||
<!-- 循环渲染事件项 -->
|
||||
<uni-card
|
||||
class="event-item"
|
||||
@@ -17,7 +23,7 @@
|
||||
<view class="event-header">
|
||||
<view class="event-icon">
|
||||
<!-- 动态图标:根据类型切换 -->
|
||||
<uni-icons custom-prefix="iconfont" type="icon-shebei" size="30" color="#10B981"></uni-icons>
|
||||
<uni-icons custom-prefix="iconfont" type="icon-shebei" size="35" color="#10B981"></uni-icons>
|
||||
<view class="badge1" v-if="item.status == 0"> </view>
|
||||
</view>
|
||||
<view class="event-info">
|
||||
@@ -27,12 +33,13 @@
|
||||
<view class="event-desc">
|
||||
<text>工程名称:{{ item.engineeringName }}</text>
|
||||
<text>项目名称:{{ item.projectName }}</text>
|
||||
<text>事件时间:{{ item.startTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
<text> 于{{ item.startTime }}发生{{ item.showName }} </text>
|
||||
<text> {{ item.showName }} </text>
|
||||
</view>
|
||||
</uni-card>
|
||||
<uni-load-more
|
||||
@@ -40,7 +47,7 @@
|
||||
:status="store.status"
|
||||
></uni-load-more>
|
||||
<Cn-empty v-else style="top: 20%"></Cn-empty>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
@@ -60,7 +67,9 @@ export default {
|
||||
},
|
||||
mixins: [list],
|
||||
data() {
|
||||
return {}
|
||||
return {
|
||||
triggered: true,
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
|
||||
@@ -91,6 +100,14 @@ export default {
|
||||
this.$emit('getDevCount')
|
||||
}
|
||||
},
|
||||
// 下拉
|
||||
refresherrefresh() {
|
||||
this.triggered = true
|
||||
uni.startPullDownRefresh()
|
||||
setTimeout(() => {
|
||||
this.triggered = false
|
||||
}, 500)
|
||||
},
|
||||
},
|
||||
|
||||
computed: {},
|
||||
@@ -118,10 +135,13 @@ export default {
|
||||
|
||||
/* 图标区域(按类型区分背景色) */
|
||||
.event-icon {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
// width: 90rpx;
|
||||
// height: 90rpx;
|
||||
|
||||
background-color: #10b98120;
|
||||
}
|
||||
}
|
||||
/deep/ .uni-scroll-view-refresher {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,15 +3,21 @@
|
||||
<!-- 稳态 -->
|
||||
<view class="transientBox">
|
||||
<view class="statistics pd20">
|
||||
<view class="box" v-for="item in list">
|
||||
<view class="box" :class="{ boxClick: item.label == '稳态数量' }" v-for="item in list">
|
||||
<text class="num">{{ item.value }}</text>
|
||||
<text class="label">{{ item.label }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 -->
|
||||
<view
|
||||
class="event-list" :style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }">
|
||||
<scroll-view
|
||||
scroll-y="true"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
:refresher-triggered="triggered"
|
||||
refresher-enabled="true"
|
||||
class="event-list"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }"
|
||||
>
|
||||
<!-- 循环渲染事件项 -->
|
||||
<uni-card
|
||||
class="event-item"
|
||||
@@ -40,14 +46,16 @@
|
||||
<text>工程名称:{{ item.engineeringName }}</text>
|
||||
<text>项目名称:{{ item.projectName }}</text>
|
||||
<text>设备名称:{{ item.devName }}</text>
|
||||
<text>统计日期:{{ item.statisticsDate }}</text>
|
||||
<!-- <text>统计日期:{{ item.statisticsDate }}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
<view class="event-action"> 🔍 </view>
|
||||
<view class="event-action">
|
||||
<uni-icons type="search" size="25"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
<text> {{ item.overLimitDesc }} </text>
|
||||
<text>{{ item.statisticsDate }}发生 {{ item.overLimitDesc }} </text>
|
||||
</view>
|
||||
</uni-card>
|
||||
|
||||
@@ -56,7 +64,7 @@
|
||||
:status="store.status"
|
||||
></uni-load-more>
|
||||
<Cn-empty v-else style="top: 20%"></Cn-empty>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
@@ -82,6 +90,7 @@ export default {
|
||||
{ value: 0, label: '越限天数' },
|
||||
{ value: 0, label: '越限测点数' },
|
||||
],
|
||||
triggered: true,
|
||||
status: 'noMore', //more加载前 loading加载中 noMore加载后
|
||||
}
|
||||
},
|
||||
@@ -130,6 +139,14 @@ export default {
|
||||
|
||||
uni.navigateTo({ url: '/pages/message1/comp/steadyStateDetails?detail=' + encodeURIComponent(str) })
|
||||
},
|
||||
// 下拉
|
||||
refresherrefresh() {
|
||||
this.triggered = true
|
||||
uni.startPullDownRefresh()
|
||||
setTimeout(() => {
|
||||
this.triggered = false
|
||||
}, 500)
|
||||
},
|
||||
},
|
||||
|
||||
computed: {},
|
||||
@@ -171,4 +188,7 @@ export default {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
/deep/ .uni-scroll-view-refresher {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,7 +3,12 @@
|
||||
<!-- 暂态 -->
|
||||
<view class="transientBox">
|
||||
<view class="statistics pd20">
|
||||
<view class="box" v-for="item in list" @click="filterValue = item.key">
|
||||
<view
|
||||
class="box"
|
||||
:class="{ boxClick: filterValue == item.key }"
|
||||
v-for="item in list"
|
||||
@click="filterValue = item.key"
|
||||
>
|
||||
<!-- <text class="num">{{ item.value }}</text> -->
|
||||
<text class="num">{{
|
||||
store &&
|
||||
@@ -37,7 +42,11 @@
|
||||
</view>
|
||||
</view>
|
||||
<!-- 卡片 -->
|
||||
<view
|
||||
<scroll-view
|
||||
scroll-y="true"
|
||||
@refresherrefresh="refresherrefresh"
|
||||
:refresher-triggered="triggered"
|
||||
refresher-enabled="true"
|
||||
class="event-list"
|
||||
v-if="curSub == 0"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }"
|
||||
@@ -45,7 +54,7 @@
|
||||
<!-- 循环渲染事件项 -->
|
||||
<uni-card
|
||||
class="event-item"
|
||||
:class="judgment(item.showName)"
|
||||
:class="judgment(item.showName).type"
|
||||
v-for="(item, index) in (store.data || []).filter((k) =>
|
||||
filterValue == '' ? k : k.showName == filterValue,
|
||||
)"
|
||||
@@ -57,22 +66,10 @@
|
||||
<view class="event-icon">
|
||||
<!-- 动态图标:根据类型切换 -->
|
||||
<uni-icons
|
||||
:custom-prefix="judgment(item.showName) == 'interrupt' ? 'custom-icon' : 'iconfont'"
|
||||
:type="
|
||||
judgment(item.showName) == 'sag'
|
||||
? 'icon-xiajiang'
|
||||
: judgment(item.showName) == 'swell'
|
||||
? 'icon-shangsheng'
|
||||
: 'minus'
|
||||
"
|
||||
:color="
|
||||
judgment(item.showName) == 'sag'
|
||||
? '#2563eb '
|
||||
: judgment(item.showName) == 'swell'
|
||||
? '#e6a23c'
|
||||
: '#909399'
|
||||
"
|
||||
:size="judgment(item.showName) == 'interrupt' ? '50' : '25'"
|
||||
:custom-prefix="'iconfont'"
|
||||
:type="judgment(item.showName).icon"
|
||||
:color="judgment(item.showName).color"
|
||||
:size="judgment(item.showName).size"
|
||||
></uni-icons>
|
||||
<!-- 0未读 1已读 -->
|
||||
<view class="badge1" v-if="item.status == 0"> </view>
|
||||
@@ -80,7 +77,9 @@
|
||||
<view class="event-info">
|
||||
<view class="event-title">
|
||||
<text class="event-id">{{ item.equipmentName }}</text>
|
||||
<text class="event-tag" :class="`${judgment(item.showName)}-tag`">{{ item.showName }}</text>
|
||||
<text class="event-tag" :class="`${judgment(item.showName).type}-tag`">{{
|
||||
item.showName
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="event-desc">
|
||||
<text>工程名称:{{ item.engineeringName }}</text>
|
||||
@@ -88,7 +87,7 @@
|
||||
<text>监测点名称:{{ item.lineName }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="event-action"> 🔍 </view>
|
||||
<view class="event-action"> <uni-icons type="search" size="25" color="#376cf3"></uni-icons> </view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
@@ -104,17 +103,19 @@
|
||||
:status="store.status"
|
||||
></uni-load-more>
|
||||
<Cn-empty v-else style="top: 20%"></Cn-empty>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- ITIC 列表 -->
|
||||
<ITIC
|
||||
v-if="subsectionList[curSub] == 'ITIC'"
|
||||
:store="store"
|
||||
:filterValue="filterValue"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }"
|
||||
></ITIC>
|
||||
<!-- F47 列表 -->
|
||||
<F47
|
||||
v-if="subsectionList[curSub] == 'F47'"
|
||||
:store="store"
|
||||
:filterValue="filterValue"
|
||||
:style="{ height: 'calc(100vh - ' + (navHeight + height) + 'px)', overflow: 'auto' }"
|
||||
></F47>
|
||||
</view>
|
||||
@@ -124,6 +125,7 @@ import list from '@/common/js/list'
|
||||
import { queryUserPushConfig } from '@/common/api/mine'
|
||||
import ITIC from './comp/ITIC.vue'
|
||||
import F47 from './comp/F47.vue'
|
||||
|
||||
export default {
|
||||
components: { ITIC, F47 },
|
||||
props: {
|
||||
@@ -151,12 +153,14 @@ export default {
|
||||
subsectionList: [], //'列表', 'ITIC', 'F47'
|
||||
status: 'noMore', //more加载前 loading加载中 noMore加载后
|
||||
sort: 0,
|
||||
triggered: true,
|
||||
// config: {},
|
||||
array: ['发生时间', '暂降深度', '持续时间'],
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.getConfig()
|
||||
uni.createSelectorQuery()
|
||||
.select('.transientBox')
|
||||
.boundingClientRect((rect) => {
|
||||
@@ -185,7 +189,6 @@ export default {
|
||||
this.store.params.startTime = this.$util.getMonthFirstAndLastDay(this.selectValue.date).firstDay
|
||||
this.store.params.endTime = this.$util.getMonthFirstAndLastDay(this.selectValue.date).lastDay
|
||||
this.store.loadedCallback = () => {
|
||||
this.getConfig()
|
||||
this.filterValue = ''
|
||||
this.loading = false
|
||||
}
|
||||
@@ -194,25 +197,56 @@ export default {
|
||||
getConfig() {
|
||||
queryUserPushConfig().then((res) => {
|
||||
// this.config = res.data
|
||||
|
||||
this.subsectionList = [
|
||||
let list = [
|
||||
'列表',
|
||||
res.data.iticFunction == 1 ? 'ITIC' : '',
|
||||
res.data.f47Function == 1 ? 'F47' : '',
|
||||
].filter((item) => item)
|
||||
this.curSub = !list[this.curSub] ? 0 : this.curSub
|
||||
this.subsectionList = JSON.parse(JSON.stringify(list))
|
||||
})
|
||||
},
|
||||
|
||||
judgment(val) {
|
||||
judgment(val, key) {
|
||||
switch (val) {
|
||||
case '电压暂降':
|
||||
return 'sag'
|
||||
return {
|
||||
type: 'sag',
|
||||
icon: 'icon-a-svg4',
|
||||
color: '#2563eb',
|
||||
size: '25',
|
||||
}
|
||||
case '电压暂升':
|
||||
return 'swell'
|
||||
return {
|
||||
type: 'swell',
|
||||
icon: 'icon-a-svg5',
|
||||
color: '#e6a23c',
|
||||
size: '25',
|
||||
}
|
||||
case '电压中断':
|
||||
return 'interrupt'
|
||||
return {
|
||||
type: 'interrupt',
|
||||
icon: 'icon-zhongduan2',
|
||||
color: '#6b7280',
|
||||
size: '35',
|
||||
}
|
||||
case '瞬态':
|
||||
return {
|
||||
type: 'transient',
|
||||
icon: 'icon-shuntaishijian',
|
||||
color: '#8b5cf6',
|
||||
size: '40',
|
||||
}
|
||||
case '未知':
|
||||
return {
|
||||
type: 'unknown',
|
||||
icon: 'icon-wenhao',
|
||||
color: '#6b7280',
|
||||
size: '45',
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 点击查看详情
|
||||
jump(item) {
|
||||
let str = JSON.stringify(item).replace(/%/g, '百分比')
|
||||
@@ -227,6 +261,14 @@ export default {
|
||||
sectionChange(e) {
|
||||
this.curSub = e.currentIndex
|
||||
},
|
||||
// 下拉
|
||||
refresherrefresh() {
|
||||
this.triggered = true
|
||||
uni.startPullDownRefresh()
|
||||
setTimeout(() => {
|
||||
this.triggered = false
|
||||
}, 500)
|
||||
},
|
||||
},
|
||||
onShow() {
|
||||
this.curSub = 0
|
||||
@@ -248,4 +290,8 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import './index.scss';
|
||||
/deep/ .uni-scroll-view-refresher {
|
||||
display: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -1,28 +1,48 @@
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view class="mine" slot="body">
|
||||
<view class="mine-nav" style="margin-top: 20rpx">
|
||||
<view class="mine-nav-label">运行事件</view>
|
||||
<switch style="transform: scale(0.8)" color="#376cf3" @change="change('runInfo')" :checked="config.runInfo === 1"/>
|
||||
</view>
|
||||
<view class="mine-nav" style="border-bottom: none">
|
||||
<view class="mine-nav mt20" style="border-bottom: none">
|
||||
<view class="mine-nav-label">暂态事件</view>
|
||||
<switch style="transform: scale(0.8)" color="#376cf3" @change="change('eventInfo')" :checked="config.eventInfo === 1"/>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('eventInfo')"
|
||||
:checked="config.eventInfo === 1"
|
||||
/>
|
||||
</view>
|
||||
<view class="mine-nav" style="border-bottom: none">
|
||||
<view class="mine-nav-label">稳态事件</view>
|
||||
<switch style="transform: scale(0.8)" color="#376cf3" @change="change('harmonicInfo')" :checked="config.harmonicInfo === 1"/>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('harmonicInfo')"
|
||||
:checked="config.harmonicInfo === 1"
|
||||
/>
|
||||
</view>
|
||||
<view class="mine-nav" style="border-bottom: none">
|
||||
<view class="mine-nav-label">设备告警</view>
|
||||
<switch style="transform: scale(0.8)" color="#376cf3" @change="change('alarmInfo')" :checked="config.alarmInfo === 1"/>
|
||||
<view class="mine-nav-label">运行告警</view>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('alarmInfo')"
|
||||
:checked="config.alarmInfo === 1"
|
||||
/>
|
||||
</view>
|
||||
<view class="mine-nav" >
|
||||
<view class="mine-nav-label">运行事件</view>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('runInfo')"
|
||||
:checked="config.runInfo === 1"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {queryUserPushConfig, updatePushConfig} from '@/common/api/mine'
|
||||
import { queryUserPushConfig, updatePushConfig } from '@/common/api/mine'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -33,34 +53,32 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
queryUserPushConfig().then(res => {
|
||||
console.log(123123,res);
|
||||
queryUserPushConfig().then((res) => {
|
||||
this.config = res.data
|
||||
console.log(this.config)
|
||||
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
change(type) {
|
||||
this.config[type] = this.config[type] === 1 ? 0 : 1
|
||||
updatePushConfig(this.config).then(res => {
|
||||
let str = ''
|
||||
switch (type){
|
||||
case 'runInfo':
|
||||
str = '运行事件'
|
||||
break
|
||||
case 'eventInfo':
|
||||
str = '暂态事件'
|
||||
break
|
||||
case 'harmonicInfo':
|
||||
str = '稳态事件'
|
||||
break
|
||||
case 'alarmInfo':
|
||||
str = '设备告警'
|
||||
break
|
||||
}
|
||||
this.$util.toast(`${str}推送${this.config[type] === 1 ? '开启' : '关闭'}成功`)
|
||||
})
|
||||
// updatePushConfig(this.config).then((res) => {
|
||||
// let str = ''
|
||||
// switch (type) {
|
||||
// case 'runInfo':
|
||||
// str = '运行事件'
|
||||
// break
|
||||
// case 'eventInfo':
|
||||
// str = '暂态事件'
|
||||
// break
|
||||
// case 'harmonicInfo':
|
||||
// str = '稳态事件'
|
||||
// break
|
||||
// case 'alarmInfo':
|
||||
// str = '设备告警'
|
||||
// break
|
||||
// }
|
||||
// this.$util.toast(`${str}推送${this.config[type] === 1 ? '开启' : '关闭'}成功`)
|
||||
// })
|
||||
},
|
||||
jump(type) {
|
||||
switch (type) {
|
||||
@@ -81,6 +99,11 @@ export default {
|
||||
break
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
updatePushConfig(this.config).then((res) => {
|
||||
// this.$util.toast(`配置修改成功!`)
|
||||
})
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
|
||||
@@ -40,29 +40,33 @@ export default {
|
||||
init() {
|
||||
queryUserPushConfig().then((res) => {
|
||||
this.config = res.data
|
||||
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
change(type) {
|
||||
this.config[type] = this.config[type] === 1 ? 0 : 1
|
||||
updatePushConfig(this.config).then((res) => {
|
||||
let str = ''
|
||||
switch (type) {
|
||||
case 'iticFunction':
|
||||
str = 'ITIC'
|
||||
break
|
||||
case 'f47Function':
|
||||
str = 'F47'
|
||||
break
|
||||
}
|
||||
this.$util.toast(`${str}配置${this.config[type] === 1 ? '开启' : '关闭'}成功`)
|
||||
})
|
||||
// updatePushConfig(this.config).then((res) => {
|
||||
// let str = ''
|
||||
// switch (type) {
|
||||
// case 'iticFunction':
|
||||
// str = 'ITIC'
|
||||
// break
|
||||
// case 'f47Function':
|
||||
// str = 'F47'
|
||||
// break
|
||||
// }
|
||||
// this.$util.toast(`${str}配置${this.config[type] === 1 ? '开启' : '关闭'}成功`)
|
||||
// })
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
},
|
||||
onUnload() {
|
||||
updatePushConfig(this.config).then((res) => {
|
||||
// this.$util.toast(`配置修改成功!`)
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -135,7 +135,8 @@ export default {
|
||||
return this.$util.toast('请输入手机号!')
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '请稍等',
|
||||
title: '请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
apiGetYms({
|
||||
phone: type == 5 ? this.formData.phone : this.formData.phone2,
|
||||
|
||||
@@ -107,7 +107,8 @@ export default {
|
||||
methods: {
|
||||
getCode() {
|
||||
uni.showLoading({
|
||||
title: '请稍等',
|
||||
title: '请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
apiGetYms({
|
||||
phone: this.formData.phone,
|
||||
@@ -225,7 +226,7 @@ export default {
|
||||
}
|
||||
|
||||
.login-box-input-btn {
|
||||
padding:0 40rpx;
|
||||
padding: 0 40rpx;
|
||||
margin-left: 40rpx;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
|
||||
@@ -114,7 +114,8 @@ export default {
|
||||
return this.$util.toast('请输入手机号!')
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '请稍等',
|
||||
title: '请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
apiGetYms({
|
||||
phone: this.formData.phone,
|
||||
|
||||
@@ -121,7 +121,8 @@ export default {
|
||||
return this.$util.toast('请输入手机号!')
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '请稍等',
|
||||
title: '请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
apiGetYms({
|
||||
phone: this.phone,
|
||||
|
||||
@@ -135,7 +135,8 @@ export default {
|
||||
return this.$util.toast('请输入手机号!')
|
||||
}
|
||||
uni.showLoading({
|
||||
title: '请稍等',
|
||||
title: '请稍等...',
|
||||
mask: true,
|
||||
})
|
||||
apiGetYms({
|
||||
phone: this.formData.phone,
|
||||
|
||||
@@ -11,6 +11,50 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-baogaoguanli:before {
|
||||
content: "\e663";
|
||||
}
|
||||
|
||||
.icon-a-svg5:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.icon-a-svg4:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-shebei4:before {
|
||||
content: "\e719";
|
||||
}
|
||||
|
||||
.icon-shebeizhuangtai:before {
|
||||
content: "\ec23";
|
||||
}
|
||||
|
||||
.icon-shebei3:before {
|
||||
content: "\e62e";
|
||||
}
|
||||
|
||||
.icon-zj:before {
|
||||
content: "\e79a";
|
||||
}
|
||||
|
||||
.icon-zs:before {
|
||||
content: "\e79b";
|
||||
}
|
||||
|
||||
.icon-zhongduan2:before {
|
||||
content: "\e6c8";
|
||||
}
|
||||
|
||||
.icon-wenhao:before {
|
||||
content: "\e637";
|
||||
}
|
||||
|
||||
.icon-shuntaishijian:before {
|
||||
content: "\e6ff";
|
||||
}
|
||||
|
||||
.icon-zaixianjianceshebei:before {
|
||||
content: "\e683";
|
||||
}
|
||||
|
||||
Binary file not shown.
60
uni_modules/uni-swipe-action/changelog.md
Normal file
60
uni_modules/uni-swipe-action/changelog.md
Normal file
@@ -0,0 +1,60 @@
|
||||
## 1.3.17(2026-02-09)
|
||||
- 修复 pc 触屏问题
|
||||
## 1.3.16(2025-06-11)
|
||||
- 修复 鸿蒙 next 浏览器上无法滑动的问题
|
||||
## 1.3.14(2025-06-09)
|
||||
- 优化 更新示例项目
|
||||
## 1.3.13(2025-04-15)
|
||||
- 修复 app 端 缺少leftOptions 或 rightOptions 时无法滑动的问题
|
||||
## 1.3.12(2025-04-14)
|
||||
- 修复 由上一个兼容版本引发的 安卓运行报错且无法回弹的问题
|
||||
## 1.3.11(2025-04-08)
|
||||
- 优化 兼容鸿蒙平台
|
||||
- 修复 WEB 平台控制台报错
|
||||
## 1.3.10(2024-01-17)
|
||||
- 修复 点击按钮时,按钮会被点击穿透导致自动收缩的 bug(兼容阿里/百度/抖音小程序)
|
||||
## 1.3.9(2024-01-17)
|
||||
- 修复 点击按钮时,按钮会被点击穿透导致自动收缩的 bug
|
||||
## 1.3.8(2023-04-13)
|
||||
- 修复`uni-swipe-action`和`uni-swipe-action-item`不同时使用导致 closeOther 方法报错的 bug
|
||||
## 1.3.7(2022-06-06)
|
||||
- 修复 vue3 下使用组件不能正常运行的Bug
|
||||
## 1.3.6(2022-05-31)
|
||||
- 修复 h5端点击click触发两次的Bug
|
||||
## 1.3.5(2022-05-23)
|
||||
- 修复 isPC 找不到的Bug
|
||||
## 1.3.4(2022-05-19)
|
||||
- 修复 在 nvue 下 disabled 失效的bug
|
||||
## 1.3.3(2022-03-31)
|
||||
- 修复 按钮字体大小不能设置的bug
|
||||
## 1.3.2(2022-03-16)
|
||||
- 修复 h5和app端下报el错误的bug
|
||||
## 1.3.1(2022-03-07)
|
||||
- 修复 HBuilderX 1.4.X 版本中,h5和app端下报错的bug
|
||||
## 1.3.0(2021-11-19)
|
||||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-swipe-action](https://uniapp.dcloud.io/component/uniui/uni-swipe-action)
|
||||
## 1.2.4(2021-08-20)
|
||||
- 优化 close-all 方法
|
||||
## 1.2.3(2021-08-20)
|
||||
- 新增 close-all 方法,关闭所有已打开的组件
|
||||
## 1.2.2(2021-08-17)
|
||||
- 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件
|
||||
- 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题
|
||||
- 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
|
||||
## 1.2.1(2021-07-30)
|
||||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||
- 修复 跨页面修改组件数据 ,导致不能滑动的问题
|
||||
## 1.1.10(2021-06-17)
|
||||
- 修复 按钮点击执行两次的bug
|
||||
## 1.1.9(2021-05-12)
|
||||
- 新增 项目示例地址
|
||||
## 1.1.8(2021-03-26)
|
||||
- 修复 微信小程序 nv_navigator is not defined 报错的bug
|
||||
## 1.1.7(2021-02-05)
|
||||
- 调整为uni_modules目录规范
|
||||
- 新增 左侧滑动
|
||||
- 新增 插槽使用方式
|
||||
- 新增 threshold 属性,可以控制滑动缺省值
|
||||
- 优化 长列表滚动性能
|
||||
- 修复 滚动页面时触发组件滑动的Bug
|
||||
@@ -0,0 +1,302 @@
|
||||
let bindIngXMixins = {}
|
||||
|
||||
// #ifdef APP-NVUE
|
||||
const BindingX = uni.requireNativePlugin('bindingx');
|
||||
const dom = uni.requireNativePlugin('dom');
|
||||
const animation = uni.requireNativePlugin('animation');
|
||||
|
||||
bindIngXMixins = {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
watch: {
|
||||
show(newVal) {
|
||||
if (this.autoClose) return
|
||||
if (this.stop) return
|
||||
this.stop = true
|
||||
if (newVal) {
|
||||
this.open(newVal)
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
},
|
||||
leftOptions() {
|
||||
this.getSelectorQuery()
|
||||
this.init()
|
||||
},
|
||||
rightOptions(newVal) {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.swipeaction = this.getSwipeAction()
|
||||
if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
|
||||
this.swipeaction.children.push(this)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.box = this.getEl(this.$refs['selector-box--hock'])
|
||||
this.selector = this.getEl(this.$refs['selector-content--hock']);
|
||||
this.leftButton = this.getEl(this.$refs['selector-left-button--hock']);
|
||||
this.rightButton = this.getEl(this.$refs['selector-right-button--hock']);
|
||||
this.init()
|
||||
},
|
||||
// beforeDestroy() {
|
||||
// this.swipeaction.children.forEach((item, index) => {
|
||||
// if (item === this) {
|
||||
// this.swipeaction.children.splice(index, 1)
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
methods: {
|
||||
init() {
|
||||
this.$nextTick(() => {
|
||||
this.x = 0
|
||||
this.button = {
|
||||
show: false
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.getSelectorQuery()
|
||||
}, 200)
|
||||
})
|
||||
},
|
||||
onClick(index, item, position) {
|
||||
this.$emit('click', {
|
||||
content: item,
|
||||
index,
|
||||
position
|
||||
})
|
||||
},
|
||||
touchstart(e) {
|
||||
// fix by mehaotian 禁止滑动
|
||||
if (this.disabled) return
|
||||
// 每次只触发一次,避免多次监听造成闪烁
|
||||
if (this.stop) return
|
||||
this.stop = true
|
||||
if (this.autoClose && this.swipeaction) {
|
||||
this.swipeaction.closeOther(this)
|
||||
}
|
||||
|
||||
const leftWidth = this.button.left.width
|
||||
const rightWidth = this.button.right.width
|
||||
let expression = this.range(this.x, -rightWidth, leftWidth)
|
||||
let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0)
|
||||
let rightExpression = this.range(this.x + rightWidth, 0, rightWidth)
|
||||
|
||||
this.eventpan = BindingX.bind({
|
||||
anchor: this.box,
|
||||
eventType: 'pan',
|
||||
props: [{
|
||||
element: this.selector,
|
||||
property: 'transform.translateX',
|
||||
expression
|
||||
}, {
|
||||
element: this.leftButton,
|
||||
property: 'transform.translateX',
|
||||
expression: leftExpression
|
||||
}, {
|
||||
element: this.rightButton,
|
||||
property: 'transform.translateX',
|
||||
expression: rightExpression
|
||||
}, ]
|
||||
}, (e) => {
|
||||
// nope
|
||||
if (e.state === 'end') {
|
||||
this.x = e.deltaX + this.x;
|
||||
this.isclick = true
|
||||
this.bindTiming(e.deltaX)
|
||||
}
|
||||
});
|
||||
},
|
||||
touchend(e) {
|
||||
if (this.isopen !== 'none' && !this.isclick) {
|
||||
this.open('none')
|
||||
}
|
||||
},
|
||||
bindTiming(x) {
|
||||
const left = this.x
|
||||
const leftWidth = this.button.left.width
|
||||
const rightWidth = this.button.right.width
|
||||
const threshold = this.threshold
|
||||
if (!this.isopen || this.isopen === 'none') {
|
||||
if (left > threshold) {
|
||||
this.open('left')
|
||||
} else if (left < -threshold) {
|
||||
this.open('right')
|
||||
} else {
|
||||
this.open('none')
|
||||
}
|
||||
} else {
|
||||
if ((x > -leftWidth && x < 0) || x > rightWidth) {
|
||||
if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) {
|
||||
this.open('left')
|
||||
} else {
|
||||
this.open('none')
|
||||
}
|
||||
} else {
|
||||
if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) {
|
||||
this.open('right')
|
||||
} else {
|
||||
this.open('none')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 移动范围
|
||||
* @param {Object} num
|
||||
* @param {Object} mix
|
||||
* @param {Object} max
|
||||
*/
|
||||
range(num, mix, max) {
|
||||
return `min(max(x+${num}, ${mix}), ${max})`
|
||||
},
|
||||
|
||||
/**
|
||||
* 开启swipe
|
||||
*/
|
||||
open(type) {
|
||||
this.animation(type)
|
||||
},
|
||||
|
||||
/**
|
||||
* 关闭swipe
|
||||
*/
|
||||
close() {
|
||||
this.animation('none')
|
||||
},
|
||||
|
||||
/**
|
||||
* 开启关闭动画
|
||||
* @param {Object} type
|
||||
*/
|
||||
animation(type) {
|
||||
const time = 300
|
||||
const leftWidth = this.button.left.width
|
||||
const rightWidth = this.button.right.width
|
||||
if (this.eventpan && this.eventpan.token) {
|
||||
BindingX.unbind({
|
||||
token: this.eventpan.token,
|
||||
eventType: 'pan'
|
||||
})
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case 'left':
|
||||
Promise.all([
|
||||
this.move(this.selector, leftWidth),
|
||||
this.move(this.leftButton, 0),
|
||||
this.move(this.rightButton, rightWidth * 2)
|
||||
]).then(() => {
|
||||
this.setEmit(leftWidth, type)
|
||||
})
|
||||
break
|
||||
case 'right':
|
||||
Promise.all([
|
||||
this.move(this.selector, -rightWidth),
|
||||
this.move(this.leftButton, -leftWidth * 2),
|
||||
this.move(this.rightButton, 0)
|
||||
]).then(() => {
|
||||
this.setEmit(-rightWidth, type)
|
||||
})
|
||||
break
|
||||
default:
|
||||
Promise.all([
|
||||
this.move(this.selector, 0),
|
||||
this.move(this.leftButton, -leftWidth),
|
||||
this.move(this.rightButton, rightWidth)
|
||||
]).then(() => {
|
||||
this.setEmit(0, type)
|
||||
})
|
||||
|
||||
}
|
||||
},
|
||||
setEmit(x, type) {
|
||||
const leftWidth = this.button.left.width
|
||||
const rightWidth = this.button.right.width
|
||||
this.isopen = this.isopen || 'none'
|
||||
this.stop = false
|
||||
this.isclick = false
|
||||
// 只有状态不一致才会返回结果
|
||||
if (this.isopen !== type && this.x !== x) {
|
||||
if (type === 'left' && leftWidth > 0) {
|
||||
this.$emit('change', 'left')
|
||||
}
|
||||
if (type === 'right' && rightWidth > 0) {
|
||||
this.$emit('change', 'right')
|
||||
}
|
||||
if (type === 'none') {
|
||||
this.$emit('change', 'none')
|
||||
}
|
||||
}
|
||||
this.x = x
|
||||
this.isopen = type
|
||||
},
|
||||
move(ref, value) {
|
||||
return new Promise((resolve, reject) => {
|
||||
animation.transition(ref, {
|
||||
styles: {
|
||||
transform: `translateX(${value})`,
|
||||
},
|
||||
duration: 150, //ms
|
||||
timingFunction: 'linear',
|
||||
needLayout: false,
|
||||
delay: 0 //ms
|
||||
}, function(res) {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取ref
|
||||
* @param {Object} el
|
||||
*/
|
||||
getEl(el) {
|
||||
return el.ref
|
||||
},
|
||||
/**
|
||||
* 获取节点信息
|
||||
*/
|
||||
getSelectorQuery() {
|
||||
Promise.all([
|
||||
this.getDom('left'),
|
||||
this.getDom('right'),
|
||||
]).then((data) => {
|
||||
let show = 'none'
|
||||
if (this.autoClose) {
|
||||
show = 'none'
|
||||
} else {
|
||||
show = this.show
|
||||
}
|
||||
|
||||
if (show === 'none') {
|
||||
// this.close()
|
||||
} else {
|
||||
this.open(show)
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
},
|
||||
getDom(str) {
|
||||
return new Promise((resolve, reject) => {
|
||||
dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => {
|
||||
if (data) {
|
||||
this.button[str] = data.size
|
||||
resolve(data)
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
export default bindIngXMixins
|
||||
@@ -0,0 +1,22 @@
|
||||
export function isPC() {
|
||||
var userAgentInfo = navigator.userAgent || '';
|
||||
var info = typeof uni !== 'undefined' && uni.getSystemInfoSync ? uni.getSystemInfoSync() : null;
|
||||
if (info && info.deviceType) {
|
||||
if (info.deviceType === 'pc') return true;
|
||||
if (info.deviceType === 'phone' || info.deviceType === 'pad') return false;
|
||||
}
|
||||
var isMobileUA = /Android|iPhone|SymbianOS|Windows Phone|iPad|iPod|Mobile|Harmony|HarmonyOS/i.test(userAgentInfo);
|
||||
if (isMobileUA) return false;
|
||||
var hasTouch = false;
|
||||
if (typeof navigator.maxTouchPoints === 'number') {
|
||||
hasTouch = navigator.maxTouchPoints > 0;
|
||||
} else if (typeof window !== 'undefined') {
|
||||
hasTouch = 'ontouchstart' in window;
|
||||
}
|
||||
if (hasTouch && typeof window !== 'undefined' && window.matchMedia) {
|
||||
var finePointer = window.matchMedia('(pointer: fine)').matches;
|
||||
var canHover = window.matchMedia('(hover: hover)').matches;
|
||||
return finePointer || canHover;
|
||||
}
|
||||
return !hasTouch;
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
x: 0,
|
||||
transition: false,
|
||||
width: 0,
|
||||
viewWidth: 0,
|
||||
swipeShow: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(newVal) {
|
||||
if (this.autoClose) return
|
||||
if (newVal && newVal !== 'none') {
|
||||
this.transition = true
|
||||
this.open(newVal)
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.swipeaction = this.getSwipeAction()
|
||||
if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
|
||||
this.swipeaction.children.push(this)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.isopen = false
|
||||
setTimeout(() => {
|
||||
this.getQuerySelect()
|
||||
}, 50)
|
||||
},
|
||||
methods: {
|
||||
appTouchStart(e) {
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
this.clientX = clientX
|
||||
this.timestamp = new Date().getTime()
|
||||
},
|
||||
appTouchEnd(e, index, item, position) {
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
|
||||
let diff = Math.abs(this.clientX - clientX)
|
||||
let time = (new Date().getTime()) - this.timestamp
|
||||
if (diff < 40 && time < 300) {
|
||||
this.$emit('click', {
|
||||
content: item,
|
||||
index,
|
||||
position
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 移动触发
|
||||
* @param {Object} e
|
||||
*/
|
||||
onChange(e) {
|
||||
this.moveX = e.detail.x
|
||||
this.isclose = false
|
||||
},
|
||||
touchstart(e) {
|
||||
this.transition = false
|
||||
this.isclose = true
|
||||
if (this.autoClose && this.swipeaction) {
|
||||
this.swipeaction.closeOther(this)
|
||||
}
|
||||
},
|
||||
touchmove(e) {},
|
||||
touchend(e) {
|
||||
// 0的位置什么都不执行
|
||||
if (this.isclose && this.isopen === 'none') return
|
||||
if (this.isclose && this.isopen !== 'none') {
|
||||
this.transition = true
|
||||
this.close()
|
||||
} else {
|
||||
this.move(this.moveX + this.leftWidth)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 移动
|
||||
* @param {Object} moveX
|
||||
*/
|
||||
move(moveX) {
|
||||
// 打开关闭的处理逻辑不太一样
|
||||
this.transition = true
|
||||
// 未打开状态
|
||||
if (!this.isopen || this.isopen === 'none') {
|
||||
if (moveX > this.threshold) {
|
||||
this.open('left')
|
||||
} else if (moveX < -this.threshold) {
|
||||
this.open('right')
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
} else {
|
||||
if (moveX < 0 && moveX < this.rightWidth) {
|
||||
const rightX = this.rightWidth + moveX
|
||||
if (rightX < this.threshold) {
|
||||
this.open('right')
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
} else if (moveX > 0 && moveX < this.leftWidth) {
|
||||
const leftX = this.leftWidth - moveX
|
||||
if (leftX < this.threshold) {
|
||||
this.open('left')
|
||||
} else {
|
||||
this.close()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开
|
||||
*/
|
||||
open(type) {
|
||||
this.x = this.moveX
|
||||
this.animation(type)
|
||||
},
|
||||
|
||||
/**
|
||||
* 关闭
|
||||
*/
|
||||
close() {
|
||||
this.x = this.moveX
|
||||
// TODO 解决 x 值不更新的问题,所以会多触发一次 nextTick ,待优化
|
||||
this.$nextTick(() => {
|
||||
this.x = -this.leftWidth
|
||||
if (this.isopen !== 'none') {
|
||||
this.$emit('change', 'none')
|
||||
}
|
||||
this.isopen = 'none'
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 执行结束动画
|
||||
* @param {Object} type
|
||||
*/
|
||||
animation(type) {
|
||||
this.$nextTick(() => {
|
||||
if (type === 'left') {
|
||||
this.x = 0
|
||||
} else {
|
||||
this.x = -this.rightWidth - this.leftWidth
|
||||
}
|
||||
|
||||
if (this.isopen !== type) {
|
||||
this.$emit('change', type)
|
||||
}
|
||||
this.isopen = type
|
||||
})
|
||||
|
||||
},
|
||||
getSlide(x) {},
|
||||
getQuerySelect() {
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.selectAll('.movable-view--hock').boundingClientRect(data => {
|
||||
this.leftWidth = data[1].width
|
||||
this.rightWidth = data[2].width
|
||||
this.width = data[0].width
|
||||
this.viewWidth = this.width + this.rightWidth + this.leftWidth
|
||||
if (this.leftWidth === 0) {
|
||||
// TODO 疑似bug ,初始化的时候如果x 是0,会导致移动位置错误,所以让元素超出一点
|
||||
this.x = -0.1
|
||||
} else {
|
||||
this.x = -this.leftWidth
|
||||
}
|
||||
this.moveX = this.x
|
||||
this.$nextTick(() => {
|
||||
this.swipeShow = 1
|
||||
})
|
||||
|
||||
if (!this.buttonWidth) {
|
||||
this.disabledView = true
|
||||
}
|
||||
|
||||
if (this.autoClose) return
|
||||
if (this.show !== 'none') {
|
||||
this.transition = true
|
||||
this.open(this.shows)
|
||||
}
|
||||
}).exec();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
let otherMixins = {}
|
||||
|
||||
// #ifndef APP-PLUS|| MP-WEIXIN || H5
|
||||
const MIN_DISTANCE = 10;
|
||||
otherMixins = {
|
||||
data() {
|
||||
// TODO 随机生生元素ID,解决百度小程序获取同一个元素位置信息的bug
|
||||
const elClass = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}`
|
||||
return {
|
||||
uniShow: false,
|
||||
left: 0,
|
||||
buttonShow: 'none',
|
||||
ani: false,
|
||||
moveLeft: '',
|
||||
elClass
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(newVal) {
|
||||
if (this.autoClose) return
|
||||
this.openState(newVal)
|
||||
},
|
||||
left() {
|
||||
this.moveLeft = `translateX(${this.left}px)`
|
||||
},
|
||||
buttonShow(newVal) {
|
||||
if (this.autoClose) return
|
||||
this.openState(newVal)
|
||||
},
|
||||
leftOptions() {
|
||||
this.init()
|
||||
},
|
||||
rightOptions() {
|
||||
this.init()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.swipeaction = this.getSwipeAction()
|
||||
if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
|
||||
this.swipeaction.children.push(this)
|
||||
}
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
clearTimeout(this.timer)
|
||||
this.timer = setTimeout(() => {
|
||||
this.getSelectorQuery()
|
||||
}, 100)
|
||||
// 移动距离
|
||||
this.left = 0
|
||||
this.x = 0
|
||||
},
|
||||
|
||||
closeSwipe(e) {
|
||||
if (this.autoClose && this.swipeaction) {
|
||||
this.swipeaction.closeOther(this)
|
||||
}
|
||||
},
|
||||
appTouchStart(e) {
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
this.clientX = clientX
|
||||
this.timestamp = new Date().getTime()
|
||||
},
|
||||
appTouchEnd(e, index, item, position) {
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
|
||||
let diff = Math.abs(this.clientX - clientX)
|
||||
let time = (new Date().getTime()) - this.timestamp
|
||||
if (diff < 40 && time < 300) {
|
||||
this.$emit('click', {
|
||||
content: item,
|
||||
index,
|
||||
position
|
||||
})
|
||||
}
|
||||
},
|
||||
touchstart(e) {
|
||||
if (this.disabled) return
|
||||
this.ani = false
|
||||
this.x = this.left || 0
|
||||
this.stopTouchStart(e)
|
||||
this.autoClose && this.closeSwipe()
|
||||
},
|
||||
touchmove(e) {
|
||||
if (this.disabled) return
|
||||
// 是否可以滑动页面
|
||||
this.stopTouchMove(e);
|
||||
if (this.direction !== 'horizontal') {
|
||||
return;
|
||||
}
|
||||
this.move(this.x + this.deltaX)
|
||||
return false
|
||||
},
|
||||
touchend() {
|
||||
if (this.disabled) return
|
||||
this.moveDirection(this.left)
|
||||
},
|
||||
/**
|
||||
* 设置移动距离
|
||||
* @param {Object} value
|
||||
*/
|
||||
move(value) {
|
||||
value = value || 0
|
||||
const leftWidth = this.leftWidth
|
||||
const rightWidth = this.rightWidth
|
||||
// 获取可滑动范围
|
||||
this.left = this.range(value, -rightWidth, leftWidth);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取范围
|
||||
* @param {Object} num
|
||||
* @param {Object} min
|
||||
* @param {Object} max
|
||||
*/
|
||||
range(num, min, max) {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
},
|
||||
/**
|
||||
* 移动方向判断
|
||||
* @param {Object} left
|
||||
* @param {Object} value
|
||||
*/
|
||||
moveDirection(left) {
|
||||
const threshold = this.threshold
|
||||
const isopen = this.isopen || 'none'
|
||||
const leftWidth = this.leftWidth
|
||||
const rightWidth = this.rightWidth
|
||||
if (this.deltaX === 0) {
|
||||
this.openState('none')
|
||||
return
|
||||
}
|
||||
if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth >
|
||||
0 && rightWidth +
|
||||
left < threshold)) {
|
||||
// right
|
||||
this.openState('right')
|
||||
} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth >
|
||||
0 &&
|
||||
leftWidth - left < threshold)) {
|
||||
// left
|
||||
this.openState('left')
|
||||
} else {
|
||||
// default
|
||||
this.openState('none')
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 开启状态
|
||||
* @param {Boolean} type
|
||||
*/
|
||||
openState(type) {
|
||||
const leftWidth = this.leftWidth
|
||||
const rightWidth = this.rightWidth
|
||||
let left = ''
|
||||
this.isopen = this.isopen ? this.isopen : 'none'
|
||||
switch (type) {
|
||||
case "left":
|
||||
left = leftWidth
|
||||
break
|
||||
case "right":
|
||||
left = -rightWidth
|
||||
break
|
||||
default:
|
||||
left = 0
|
||||
}
|
||||
|
||||
|
||||
if (this.isopen !== type) {
|
||||
this.throttle = true
|
||||
this.$emit('change', type)
|
||||
}
|
||||
|
||||
this.isopen = type
|
||||
// 添加动画类
|
||||
this.ani = true
|
||||
this.$nextTick(() => {
|
||||
this.move(left)
|
||||
})
|
||||
// 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
|
||||
},
|
||||
close() {
|
||||
this.openState('none')
|
||||
},
|
||||
getDirection(x, y) {
|
||||
if (x > y && x > MIN_DISTANCE) {
|
||||
return 'horizontal';
|
||||
}
|
||||
if (y > x && y > MIN_DISTANCE) {
|
||||
return 'vertical';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置滑动状态
|
||||
* @param {Object} event
|
||||
*/
|
||||
resetTouchStatus() {
|
||||
this.direction = '';
|
||||
this.deltaX = 0;
|
||||
this.deltaY = 0;
|
||||
this.offsetX = 0;
|
||||
this.offsetY = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置滑动开始位置
|
||||
* @param {Object} event
|
||||
*/
|
||||
stopTouchStart(event) {
|
||||
this.resetTouchStatus();
|
||||
const touch = event.touches[0];
|
||||
this.startX = touch.clientX;
|
||||
this.startY = touch.clientY;
|
||||
},
|
||||
|
||||
/**
|
||||
* 滑动中,是否禁止打开
|
||||
* @param {Object} event
|
||||
*/
|
||||
stopTouchMove(event) {
|
||||
const touch = event.touches[0];
|
||||
this.deltaX = touch.clientX - this.startX;
|
||||
this.deltaY = touch.clientY - this.startY;
|
||||
this.offsetX = Math.abs(this.deltaX);
|
||||
this.offsetY = Math.abs(this.deltaY);
|
||||
this.direction = this.direction || this.getDirection(this.offsetX, this.offsetY);
|
||||
},
|
||||
|
||||
getSelectorQuery() {
|
||||
const views = uni.createSelectorQuery().in(this)
|
||||
views
|
||||
.selectAll('.' + this.elClass)
|
||||
.boundingClientRect(data => {
|
||||
if (data.length === 0) return
|
||||
let show = 'none'
|
||||
if (this.autoClose) {
|
||||
show = 'none'
|
||||
} else {
|
||||
show = this.show
|
||||
}
|
||||
this.leftWidth = data[0].width || 0
|
||||
this.rightWidth = data[1].width || 0
|
||||
this.buttonShow = show
|
||||
})
|
||||
.exec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
|
||||
export default otherMixins
|
||||
@@ -0,0 +1,84 @@
|
||||
let mpMixins = {}
|
||||
let is_pc = null
|
||||
// #ifdef H5
|
||||
import {
|
||||
isPC
|
||||
} from "./isPC"
|
||||
is_pc = isPC()
|
||||
// #endif
|
||||
// #ifdef APP-VUE || APP-HARMONY || MP-WEIXIN || H5
|
||||
|
||||
mpMixins = {
|
||||
data() {
|
||||
return {
|
||||
is_show: 'none'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
show(newVal) {
|
||||
this.is_show = this.show
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.swipeaction = this.getSwipeAction()
|
||||
if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
|
||||
this.swipeaction.children.push(this)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.is_show = this.show
|
||||
},
|
||||
methods: {
|
||||
// wxs 中调用
|
||||
closeSwipe(e) {
|
||||
if (this.autoClose && this.swipeaction) {
|
||||
this.swipeaction.closeOther(this)
|
||||
}
|
||||
},
|
||||
|
||||
change(e) {
|
||||
this.$emit('change', e.open)
|
||||
if (this.is_show !== e.open) {
|
||||
this.is_show = e.open
|
||||
}
|
||||
},
|
||||
|
||||
appTouchStart(e) {
|
||||
if (is_pc) return
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
this.clientX = clientX
|
||||
this.timestamp = new Date().getTime()
|
||||
},
|
||||
appTouchEnd(e, index, item, position) {
|
||||
if (is_pc) return
|
||||
const {
|
||||
clientX
|
||||
} = e.changedTouches[0]
|
||||
// fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题
|
||||
let diff = Math.abs(this.clientX - clientX)
|
||||
let time = (new Date().getTime()) - this.timestamp
|
||||
if (diff < 40 && time < 300) {
|
||||
this.$emit('click', {
|
||||
content: item,
|
||||
index,
|
||||
position
|
||||
})
|
||||
}
|
||||
},
|
||||
onClickForPC(index, item, position) {
|
||||
if (!is_pc) return
|
||||
// #ifdef H5
|
||||
this.$emit('click', {
|
||||
content: item,
|
||||
index,
|
||||
position
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// #endif
|
||||
export default mpMixins
|
||||
@@ -0,0 +1,277 @@
|
||||
const MIN_DISTANCE = 10;
|
||||
export default {
|
||||
showWatch(newVal, oldVal, ownerInstance, instance, self) {
|
||||
var state = self.state || {}
|
||||
var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el
|
||||
if (!$el) return
|
||||
this.getDom(instance, ownerInstance, self)
|
||||
if (newVal && newVal !== 'none') {
|
||||
this.openState(newVal, instance, ownerInstance, self)
|
||||
return
|
||||
}
|
||||
|
||||
if (state.left) {
|
||||
this.openState('none', instance, ownerInstance, self)
|
||||
}
|
||||
this.resetTouchStatus(instance, self)
|
||||
},
|
||||
|
||||
/**
|
||||
* 开始触摸操作
|
||||
* @param {Object} e
|
||||
* @param {Object} ins
|
||||
*/
|
||||
touchstart(e, ownerInstance, self) {
|
||||
let instance = e.instance;
|
||||
let disabled = instance.getDataset().disabled
|
||||
let state = self.state || {};
|
||||
this.getDom(instance, ownerInstance, self)
|
||||
// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
|
||||
disabled = this.getDisabledType(disabled)
|
||||
if (disabled) return
|
||||
// 开始触摸时移除动画类
|
||||
instance.requestAnimationFrame(function() {
|
||||
instance.removeClass('ani');
|
||||
ownerInstance.callMethod('closeSwipe');
|
||||
})
|
||||
|
||||
// 记录上次的位置
|
||||
state.x = state.left || 0
|
||||
// 计算滑动开始位置
|
||||
this.stopTouchStart(e, ownerInstance, self)
|
||||
},
|
||||
|
||||
/**
|
||||
* 开始滑动操作
|
||||
* @param {Object} e
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
touchmove(e, ownerInstance, self) {
|
||||
let instance = e.instance;
|
||||
// 删除之后已经那不到实例了
|
||||
if (!instance) return;
|
||||
let disabled = instance.getDataset().disabled
|
||||
let state = self.state || {}
|
||||
// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
|
||||
disabled = this.getDisabledType(disabled)
|
||||
if (disabled) return
|
||||
// 是否可以滑动页面
|
||||
this.stopTouchMove(e, self);
|
||||
if (state.direction !== 'horizontal') {
|
||||
return;
|
||||
}
|
||||
if (e.preventDefault) {
|
||||
// 阻止页面滚动
|
||||
e.preventDefault()
|
||||
}
|
||||
let x = state.x + state.deltaX
|
||||
this.move(x, instance, ownerInstance, self)
|
||||
},
|
||||
|
||||
/**
|
||||
* 结束触摸操作
|
||||
* @param {Object} e
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
touchend(e, ownerInstance, self) {
|
||||
let instance = e.instance;
|
||||
let disabled = instance.getDataset().disabled
|
||||
let state = self.state || {}
|
||||
// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
|
||||
disabled = this.getDisabledType(disabled)
|
||||
|
||||
if (disabled) return
|
||||
// 滑动过程中触摸结束,通过阙值判断是开启还是关闭
|
||||
// fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13
|
||||
this.moveDirection(state.left, instance, ownerInstance, self)
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置移动距离
|
||||
* @param {Object} value
|
||||
* @param {Object} instance
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
move(value, instance, ownerInstance, self) {
|
||||
value = value || 0
|
||||
let state = self.state || {}
|
||||
let leftWidth = state.leftWidth
|
||||
let rightWidth = state.rightWidth
|
||||
// 获取可滑动范围
|
||||
state.left = this.range(value, -rightWidth, leftWidth);
|
||||
instance.requestAnimationFrame(function() {
|
||||
instance.setStyle({
|
||||
transform: 'translateX(' + state.left + 'px)',
|
||||
'-webkit-transform': 'translateX(' + state.left + 'px)'
|
||||
})
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取元素信息
|
||||
* @param {Object} instance
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
getDom(instance, ownerInstance, self) {
|
||||
var state = self.state || {}
|
||||
var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el
|
||||
var leftDom = $el.querySelector('.button-group--left')
|
||||
var rightDom = $el.querySelector('.button-group--right')
|
||||
if (leftDom && leftDom.offsetWidth) {
|
||||
state.leftWidth = leftDom.offsetWidth || 0
|
||||
} else {
|
||||
state.leftWidth = 0
|
||||
}
|
||||
if (rightDom && rightDom.offsetWidth) {
|
||||
state.rightWidth = rightDom.offsetWidth || 0
|
||||
} else {
|
||||
state.rightWidth = 0
|
||||
}
|
||||
state.threshold = instance.getDataset().threshold
|
||||
},
|
||||
|
||||
getDisabledType(value) {
|
||||
return (typeof(value) === 'string' ? JSON.parse(value) : value) || false;
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取范围
|
||||
* @param {Object} num
|
||||
* @param {Object} min
|
||||
* @param {Object} max
|
||||
*/
|
||||
range(num, min, max) {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 移动方向判断
|
||||
* @param {Object} left
|
||||
* @param {Object} value
|
||||
* @param {Object} ownerInstance
|
||||
* @param {Object} ins
|
||||
*/
|
||||
moveDirection(left, ins, ownerInstance, self) {
|
||||
var state = self.state || {}
|
||||
var threshold = state.threshold
|
||||
var position = state.position
|
||||
var isopen = state.isopen || 'none'
|
||||
var leftWidth = state.leftWidth
|
||||
var rightWidth = state.rightWidth
|
||||
if (state.deltaX === 0) {
|
||||
this.openState('none', ins, ownerInstance, self)
|
||||
return
|
||||
}
|
||||
if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 &&
|
||||
rightWidth +
|
||||
left < threshold)) {
|
||||
// right
|
||||
this.openState('right', ins, ownerInstance, self)
|
||||
} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
|
||||
leftWidth - left < threshold)) {
|
||||
// left
|
||||
this.openState('left', ins, ownerInstance, self)
|
||||
} else {
|
||||
// default
|
||||
this.openState('none', ins, ownerInstance, self)
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 开启状态
|
||||
* @param {Boolean} type
|
||||
* @param {Object} ins
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
openState(type, ins, ownerInstance, self) {
|
||||
let state = self.state || {}
|
||||
let leftWidth = state.leftWidth
|
||||
let rightWidth = state.rightWidth
|
||||
let left = ''
|
||||
state.isopen = state.isopen ? state.isopen : 'none'
|
||||
switch (type) {
|
||||
case "left":
|
||||
left = leftWidth
|
||||
break
|
||||
case "right":
|
||||
left = -rightWidth
|
||||
break
|
||||
default:
|
||||
left = 0
|
||||
}
|
||||
|
||||
// && !state.throttle
|
||||
|
||||
if (state.isopen !== type) {
|
||||
state.throttle = true
|
||||
ownerInstance.callMethod('change', {
|
||||
open: type
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
state.isopen = type
|
||||
// 添加动画类
|
||||
ins.requestAnimationFrame(() => {
|
||||
ins.addClass('ani');
|
||||
this.move(left, ins, ownerInstance, self)
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
getDirection(x, y) {
|
||||
if (x > y && x > MIN_DISTANCE) {
|
||||
return 'horizontal';
|
||||
}
|
||||
if (y > x && y > MIN_DISTANCE) {
|
||||
return 'vertical';
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置滑动状态
|
||||
* @param {Object} event
|
||||
*/
|
||||
resetTouchStatus(instance, self) {
|
||||
let state = self.state || {};
|
||||
state.direction = '';
|
||||
state.deltaX = 0;
|
||||
state.deltaY = 0;
|
||||
state.offsetX = 0;
|
||||
state.offsetY = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* 设置滑动开始位置
|
||||
* @param {Object} event
|
||||
*/
|
||||
stopTouchStart(event, ownerInstance, self) {
|
||||
let instance = event.instance;
|
||||
let state = self.state || {}
|
||||
this.resetTouchStatus(instance, self);
|
||||
var touch = event.touches[0];
|
||||
state.startX = touch.clientX;
|
||||
state.startY = touch.clientY;
|
||||
},
|
||||
|
||||
/**
|
||||
* 滑动中,是否禁止打开
|
||||
* @param {Object} event
|
||||
*/
|
||||
stopTouchMove(event, self) {
|
||||
let instance = event.instance;
|
||||
let state = self.state || {};
|
||||
let touch = event.touches[0];
|
||||
|
||||
state.deltaX = touch.clientX - state.startX;
|
||||
state.deltaY = touch.clientY - state.startY;
|
||||
state.offsetY = Math.abs(state.deltaY);
|
||||
state.offsetX = Math.abs(state.deltaX);
|
||||
state.direction = state.direction || this.getDirection(state.offsetX, state.offsetY);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,354 @@
|
||||
<template>
|
||||
<!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
|
||||
<!-- #ifdef APP-VUE || APP-HARMONY || MP-WEIXIN || H5 -->
|
||||
<view class="uni-swipe">
|
||||
<!-- #ifdef H5 -->
|
||||
<view class="uni-swipe_box" :change:prop="wxsswipe.showWatch" :prop="is_show" :data-threshold="threshold"
|
||||
:data-disabled="disabled" @touchstart="wxsswipe.touchstart" @touchmove="wxsswipe.touchmove"
|
||||
@touchend="wxsswipe.touchend" @mousedown="wxsswipe.mousedown" @mousemove="wxsswipe.mousemove"
|
||||
@mouseup="wxsswipe.mouseup" @mouseleave="wxsswipe.mouseleave">
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="uni-swipe_box" :change:prop="wxsswipe.showWatch" :prop="is_show" :data-threshold="threshold"
|
||||
:data-disabled="disabled" @touchstart="wxsswipe.touchstart" @touchmove="wxsswipe.touchmove"
|
||||
@touchend="wxsswipe.touchend">
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN || H5 -->
|
||||
<view class="uni-swipe_box" :change:prop="renderswipe.showWatch" :prop="is_show" :data-threshold="threshold"
|
||||
:data-disabled="disabled+''" @touchstart="renderswipe.touchstart" @touchmove="renderswipe.touchmove"
|
||||
@touchend="renderswipe.touchend">
|
||||
<!-- #endif -->
|
||||
<!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
|
||||
<view class="uni-swipe_button-group button-group--left">
|
||||
<slot name="left">
|
||||
<view v-for="(item,index) in leftOptions" :key="index" :style="{
|
||||
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
|
||||
}" class="uni-swipe_button button-hock" @touchstart.stop="appTouchStart"
|
||||
@touchend.stop="appTouchEnd($event,index,item,'left')" @click.stop="onClickForPC(index,item,'left')">
|
||||
<text class="uni-swipe_button-text"
|
||||
:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
<view class="uni-swipe_text--center">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<view class="uni-swipe_button-group button-group--right">
|
||||
<slot name="right">
|
||||
<view v-for="(item,index) in rightOptions" :key="index" :style="{
|
||||
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
|
||||
}" class="uni-swipe_button button-hock" @touchstart.stop="appTouchStart"
|
||||
@touchend.stop="appTouchEnd($event,index,item,'right')" @click.stop="onClickForPC(index,item,'right')"><text
|
||||
class="uni-swipe_button-text"
|
||||
:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- app nvue端 使用 bindingx -->
|
||||
<!-- #ifdef APP-NVUE -->
|
||||
<view ref="selector-box--hock" class="uni-swipe" @horizontalpan="touchstart" @touchend="touchend">
|
||||
<view ref='selector-left-button--hock' class="uni-swipe_button-group button-group--left">
|
||||
<slot name="left">
|
||||
<view v-for="(item,index) in leftOptions" :key="index" :style="{
|
||||
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
|
||||
}" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'left')">
|
||||
<text class="uni-swipe_button-text"
|
||||
:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF', fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">
|
||||
{{ item.text }}
|
||||
</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
<view ref='selector-right-button--hock' class="uni-swipe_button-group button-group--right">
|
||||
<slot name="right">
|
||||
<view v-for="(item,index) in rightOptions" :key="index" :style="{
|
||||
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
|
||||
}" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'right')"><text
|
||||
class="uni-swipe_button-text"
|
||||
:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
<view ref='selector-content--hock' class="uni-swipe_box">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- 其他平台使用 js ,长列表性能可能会有影响-->
|
||||
<!-- #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ || MP-HARMONY -->
|
||||
<view class="uni-swipe">
|
||||
<view class="uni-swipe_box" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"
|
||||
:style="{transform:moveLeft}" :class="{ani:ani}">
|
||||
<view class="uni-swipe_button-group button-group--left" :class="[elClass]">
|
||||
<slot name="left">
|
||||
<view v-for="(item,index) in leftOptions" :key="index" :style="{
|
||||
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
|
||||
fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
|
||||
}" class="uni-swipe_button button-hock" @touchstart.stop="appTouchStart"
|
||||
@touchend.stop="appTouchEnd($event,index,item,'left')"><text class="uni-swipe_button-text"
|
||||
:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
<slot></slot>
|
||||
<view class="uni-swipe_button-group button-group--right" :class="[elClass]">
|
||||
<slot name="right">
|
||||
<view v-for="(item,index) in rightOptions" :key="index" :style="{
|
||||
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
|
||||
fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
|
||||
}" @touchstart.stop="appTouchStart" @touchend.stop="appTouchEnd($event,index,item,'right')"
|
||||
class="uni-swipe_button button-hock"><text class="uni-swipe_button-text"
|
||||
:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
|
||||
</view>
|
||||
</slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
</template>
|
||||
<script src="./wx.wxs" module="wxsswipe" lang="wxs"></script>
|
||||
|
||||
<script module="renderswipe" lang="renderjs">
|
||||
import render from './render.js'
|
||||
export default {
|
||||
mounted(e, ins, owner) {
|
||||
this.state = {}
|
||||
},
|
||||
methods: {
|
||||
showWatch(newVal, oldVal, ownerInstance, instance) {
|
||||
render.showWatch(newVal, oldVal, ownerInstance, instance, this)
|
||||
},
|
||||
touchstart(e, ownerInstance) {
|
||||
render.touchstart(e, ownerInstance, this)
|
||||
},
|
||||
touchmove(e, ownerInstance) {
|
||||
render.touchmove(e, ownerInstance, this)
|
||||
},
|
||||
touchend(e, ownerInstance) {
|
||||
render.touchend(e, ownerInstance, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
import mpwxs from './mpwxs'
|
||||
import bindingx from './bindingx.js'
|
||||
import mpother from './mpother'
|
||||
|
||||
/**
|
||||
* SwipeActionItem 滑动操作子组件
|
||||
* @description 通过滑动触发选项的容器
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=181
|
||||
* @property {Boolean} show = [left|right|none] 开启关闭组件,auto-close = false 时生效
|
||||
* @property {Boolean} disabled = [true|false] 是否禁止滑动
|
||||
* @property {Boolean} autoClose = [true|false] 滑动打开当前组件,是否关闭其他组件
|
||||
* @property {Number} threshold 滑动缺省值
|
||||
* @property {Array} leftOptions 左侧选项内容及样式
|
||||
* @property {Array} rightOptions 右侧选项内容及样式
|
||||
* @event {Function} click 点击选项按钮时触发事件,e = {content,index} ,content(点击内容)、index(下标)
|
||||
* @event {Function} change 组件打开或关闭时触发,left\right\none
|
||||
*/
|
||||
|
||||
export default {
|
||||
mixins: [mpwxs, bindingx, mpother],
|
||||
emits: ['click', 'change'],
|
||||
props: {
|
||||
// 控制开关
|
||||
show: {
|
||||
type: String,
|
||||
default: 'none'
|
||||
},
|
||||
|
||||
// 禁用
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
|
||||
// 是否自动关闭
|
||||
autoClose: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
|
||||
// 滑动缺省距离
|
||||
threshold: {
|
||||
type: Number,
|
||||
default: 20
|
||||
},
|
||||
|
||||
// 左侧按钮内容
|
||||
leftOptions: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
|
||||
// 右侧按钮内容
|
||||
rightOptions: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
// #ifndef VUE3
|
||||
// TODO vue2
|
||||
destroyed() {
|
||||
if (this.__isUnmounted) return
|
||||
this.uninstall()
|
||||
},
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
// TODO vue3
|
||||
unmounted() {
|
||||
this.__isUnmounted = true
|
||||
this.uninstall()
|
||||
},
|
||||
// #endif
|
||||
|
||||
methods: {
|
||||
uninstall() {
|
||||
if (this.swipeaction) {
|
||||
this.swipeaction.children.forEach((item, index) => {
|
||||
if (item === this) {
|
||||
this.swipeaction.children.splice(index, 1)
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 获取父元素实例
|
||||
*/
|
||||
getSwipeAction(name = 'uniSwipeAction') {
|
||||
let parent = this.$parent;
|
||||
let parentName = parent.$options.name;
|
||||
while (parentName !== name) {
|
||||
parent = parent.$parent;
|
||||
if (!parent) return false;
|
||||
parentName = parent.$options.name;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.uni-swipe {
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
overflow: hidden;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-swipe_box {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
// touch-action: none;
|
||||
/* #endif */
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.uni-swipe_content {
|
||||
// border: 1px red solid;
|
||||
}
|
||||
|
||||
.uni-swipe_text--center {
|
||||
width: 100%;
|
||||
/* #ifndef APP-NVUE */
|
||||
cursor: grab;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-swipe_button-group {
|
||||
/* #ifndef APP-NVUE */
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.button-group--left {
|
||||
left: 0;
|
||||
transform: translateX(-100%)
|
||||
}
|
||||
|
||||
.button-group--right {
|
||||
right: 0;
|
||||
transform: translateX(100%)
|
||||
}
|
||||
|
||||
.uni-swipe_button {
|
||||
/* #ifdef APP-NVUE */
|
||||
flex: 1;
|
||||
/* #endif */
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.uni-swipe_button-text {
|
||||
/* #ifndef APP-NVUE */
|
||||
flex-shrink: 0;
|
||||
/* #endif */
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.ani {
|
||||
transition-property: transform;
|
||||
transition-duration: 0.3s;
|
||||
transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
}
|
||||
|
||||
/* #ifdef MP-ALIPAY */
|
||||
.movable-area {
|
||||
/* width: 100%; */
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
.movable-view {
|
||||
display: flex;
|
||||
/* justify-content: center; */
|
||||
position: relative;
|
||||
flex: 1;
|
||||
height: 45px;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.movable-view-button {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-direction: row;
|
||||
height: 100%;
|
||||
background: #C0C0C0;
|
||||
}
|
||||
|
||||
/* .transition {
|
||||
transition: all 0.3s;
|
||||
} */
|
||||
|
||||
.movable-view-box {
|
||||
flex-shrink: 0;
|
||||
height: 100%;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
</style>
|
||||
@@ -0,0 +1,346 @@
|
||||
var MIN_DISTANCE = 10;
|
||||
|
||||
/**
|
||||
* 判断当前是否为H5、app-vue
|
||||
*/
|
||||
var IS_HTML5 = false
|
||||
if (typeof window === 'object') IS_HTML5 = true
|
||||
|
||||
/**
|
||||
* 监听页面内值的变化,主要用于动态开关swipe-action
|
||||
* @param {Object} newValue
|
||||
* @param {Object} oldValue
|
||||
* @param {Object} ownerInstance
|
||||
* @param {Object} instance
|
||||
*/
|
||||
function showWatch(newVal, oldVal, ownerInstance, instance) {
|
||||
var state = instance.getState()
|
||||
getDom(instance, ownerInstance)
|
||||
if (newVal && newVal !== 'none') {
|
||||
openState(newVal, instance, ownerInstance)
|
||||
return
|
||||
}
|
||||
|
||||
if (state.left) {
|
||||
openState('none', instance, ownerInstance)
|
||||
}
|
||||
resetTouchStatus(instance)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始触摸操作
|
||||
* @param {Object} e
|
||||
* @param {Object} ins
|
||||
*/
|
||||
function touchstart(e, ownerInstance) {
|
||||
var instance = e.instance;
|
||||
var disabled = instance.getDataset().disabled
|
||||
var state = instance.getState();
|
||||
getDom(instance, ownerInstance)
|
||||
// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
|
||||
disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
|
||||
if (disabled) return
|
||||
// 开始触摸时移除动画类
|
||||
instance.requestAnimationFrame(function() {
|
||||
instance.removeClass('ani');
|
||||
ownerInstance.callMethod('closeSwipe');
|
||||
})
|
||||
|
||||
// 记录上次的位置
|
||||
state.x = state.left || 0
|
||||
// 计算滑动开始位置
|
||||
stopTouchStart(e, ownerInstance)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始滑动操作
|
||||
* @param {Object} e
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
function touchmove(e, ownerInstance) {
|
||||
var instance = e.instance;
|
||||
var disabled = instance.getDataset().disabled
|
||||
var state = instance.getState()
|
||||
// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
|
||||
disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
|
||||
if (disabled) return
|
||||
// 是否可以滑动页面
|
||||
stopTouchMove(e);
|
||||
if (state.direction !== 'horizontal') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.preventDefault) {
|
||||
// 阻止页面滚动
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
move(state.x + state.deltaX, instance, ownerInstance)
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束触摸操作
|
||||
* @param {Object} e
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
function touchend(e, ownerInstance) {
|
||||
var instance = e.instance;
|
||||
var disabled = instance.getDataset().disabled
|
||||
var state = instance.getState()
|
||||
// fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复
|
||||
disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false;
|
||||
|
||||
if (disabled) return
|
||||
// 滑动过程中触摸结束,通过阙值判断是开启还是关闭
|
||||
// fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13
|
||||
moveDirection(state.left, instance, ownerInstance)
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置移动距离
|
||||
* @param {Object} value
|
||||
* @param {Object} instance
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
function move(value, instance, ownerInstance) {
|
||||
value = value || 0
|
||||
var state = instance.getState()
|
||||
var leftWidth = state.leftWidth
|
||||
var rightWidth = state.rightWidth
|
||||
// 获取可滑动范围
|
||||
state.left = range(value, -rightWidth, leftWidth);
|
||||
instance.requestAnimationFrame(function() {
|
||||
instance.setStyle({
|
||||
transform: 'translateX(' + state.left + 'px)',
|
||||
'-webkit-transform': 'translateX(' + state.left + 'px)'
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取元素信息
|
||||
* @param {Object} instance
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
function getDom(instance, ownerInstance) {
|
||||
var state = instance.getState()
|
||||
var leftDom = ownerInstance.selectComponent('.button-group--left')
|
||||
var rightDom = ownerInstance.selectComponent('.button-group--right')
|
||||
var leftStyles = {
|
||||
width: 0
|
||||
}
|
||||
var rightStyles = {
|
||||
width: 0
|
||||
}
|
||||
|
||||
if (leftDom) {
|
||||
leftStyles = leftDom.getBoundingClientRect()
|
||||
}
|
||||
|
||||
if (rightDom) {
|
||||
rightStyles = rightDom.getBoundingClientRect()
|
||||
}
|
||||
state.leftWidth = leftStyles.width || 0
|
||||
state.rightWidth = rightStyles.width || 0
|
||||
state.threshold = instance.getDataset().threshold
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取范围
|
||||
* @param {Object} num
|
||||
* @param {Object} min
|
||||
* @param {Object} max
|
||||
*/
|
||||
function range(num, min, max) {
|
||||
return Math.min(Math.max(num, min), max);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 移动方向判断
|
||||
* @param {Object} left
|
||||
* @param {Object} value
|
||||
* @param {Object} ownerInstance
|
||||
* @param {Object} ins
|
||||
*/
|
||||
function moveDirection(left, ins, ownerInstance) {
|
||||
var state = ins.getState()
|
||||
var threshold = state.threshold
|
||||
var position = state.position
|
||||
var isopen = state.isopen || 'none'
|
||||
var leftWidth = state.leftWidth
|
||||
var rightWidth = state.rightWidth
|
||||
if (state.deltaX === 0) {
|
||||
openState('none', ins, ownerInstance)
|
||||
return
|
||||
}
|
||||
if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 &&
|
||||
rightWidth +
|
||||
left < threshold)) {
|
||||
// right
|
||||
openState('right', ins, ownerInstance)
|
||||
} else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 &&
|
||||
leftWidth - left < threshold)) {
|
||||
// left
|
||||
openState('left', ins, ownerInstance)
|
||||
} else {
|
||||
// default
|
||||
openState('none', ins, ownerInstance)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 开启状态
|
||||
* @param {Boolean} type
|
||||
* @param {Object} ins
|
||||
* @param {Object} ownerInstance
|
||||
*/
|
||||
function openState(type, ins, ownerInstance) {
|
||||
var state = ins.getState()
|
||||
var leftWidth = state.leftWidth
|
||||
var rightWidth = state.rightWidth
|
||||
var left = ''
|
||||
state.isopen = state.isopen ? state.isopen : 'none'
|
||||
switch (type) {
|
||||
case "left":
|
||||
left = leftWidth
|
||||
break
|
||||
case "right":
|
||||
left = -rightWidth
|
||||
break
|
||||
default:
|
||||
left = 0
|
||||
}
|
||||
|
||||
// && !state.throttle
|
||||
|
||||
if (state.isopen !== type) {
|
||||
state.throttle = true
|
||||
ownerInstance.callMethod('change', {
|
||||
open: type
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
state.isopen = type
|
||||
// 添加动画类
|
||||
ins.requestAnimationFrame(function() {
|
||||
ins.addClass('ani');
|
||||
move(left, ins, ownerInstance)
|
||||
})
|
||||
// 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的
|
||||
}
|
||||
|
||||
|
||||
function getDirection(x, y) {
|
||||
if (x > y && x > MIN_DISTANCE) {
|
||||
return 'horizontal';
|
||||
}
|
||||
if (y > x && y > MIN_DISTANCE) {
|
||||
return 'vertical';
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置滑动状态
|
||||
* @param {Object} event
|
||||
*/
|
||||
function resetTouchStatus(instance) {
|
||||
var state = instance.getState();
|
||||
state.direction = '';
|
||||
state.deltaX = 0;
|
||||
state.deltaY = 0;
|
||||
state.offsetX = 0;
|
||||
state.offsetY = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置滑动开始位置
|
||||
* @param {Object} event
|
||||
*/
|
||||
function stopTouchStart(event) {
|
||||
var instance = event.instance;
|
||||
var state = instance.getState();
|
||||
resetTouchStatus(instance);
|
||||
var touch = event.touches[0];
|
||||
if (IS_HTML5 && isPC()) {
|
||||
touch = event;
|
||||
}
|
||||
state.startX = touch.clientX;
|
||||
state.startY = touch.clientY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 滑动中,是否禁止打开
|
||||
* @param {Object} event
|
||||
*/
|
||||
function stopTouchMove(event) {
|
||||
var instance = event.instance;
|
||||
var state = instance.getState();
|
||||
var touch = event.touches[0];
|
||||
if (IS_HTML5 && isPC()) {
|
||||
touch = event;
|
||||
}
|
||||
state.deltaX = touch.clientX - state.startX;
|
||||
state.deltaY = touch.clientY - state.startY;
|
||||
state.offsetY = Math.abs(state.deltaY);
|
||||
state.offsetX = Math.abs(state.deltaX);
|
||||
state.direction = state.direction || getDirection(state.offsetX, state.offsetY);
|
||||
}
|
||||
|
||||
function isPC() {
|
||||
var userAgentInfo = navigator.userAgent;
|
||||
var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod", "Mobile", "Harmony", "HarmonyOS"];
|
||||
var flag = true;
|
||||
for (var v = 0; v < Agents.length; v++) {
|
||||
if (userAgentInfo.indexOf(Agents[v]) > 0) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
var movable = false
|
||||
|
||||
function mousedown(e, ins) {
|
||||
if (!IS_HTML5) return
|
||||
if (!isPC()) return
|
||||
touchstart(e, ins)
|
||||
movable = true
|
||||
}
|
||||
|
||||
function mousemove(e, ins) {
|
||||
if (!IS_HTML5) return
|
||||
if (!isPC()) return
|
||||
if (!movable) return
|
||||
touchmove(e, ins)
|
||||
}
|
||||
|
||||
function mouseup(e, ins) {
|
||||
if (!IS_HTML5) return
|
||||
if (!isPC()) return
|
||||
touchend(e, ins)
|
||||
movable = false
|
||||
}
|
||||
|
||||
function mouseleave(e, ins) {
|
||||
if (!IS_HTML5) return
|
||||
if (!isPC()) return
|
||||
movable = false
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
showWatch: showWatch,
|
||||
touchstart: touchstart,
|
||||
touchmove: touchmove,
|
||||
touchend: touchend,
|
||||
mousedown: mousedown,
|
||||
mousemove: mousemove,
|
||||
mouseup: mouseup,
|
||||
mouseleave: mouseleave
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<view>
|
||||
<slot></slot>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* SwipeAction 滑动操作
|
||||
* @description 通过滑动触发选项的容器
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=181
|
||||
*/
|
||||
export default {
|
||||
name:"uniSwipeAction",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {
|
||||
this.children = [];
|
||||
},
|
||||
methods: {
|
||||
// 公开给用户使用,重制组件样式
|
||||
resize(){
|
||||
// wxs 会自己计算组件大小,所以无需执行下面代码
|
||||
// #ifndef APP-VUE || H5 || MP-WEIXIN || MP-HARMONY
|
||||
this.children.forEach(vm=>{
|
||||
vm.init()
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
// 公开给用户使用,关闭全部 已经打开的组件
|
||||
closeAll(){
|
||||
this.children.forEach(vm=>{
|
||||
// #ifdef APP-VUE || H5 || MP-WEIXIN || MP-HARMONY
|
||||
vm.is_show = 'none'
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-VUE || H5 || MP-WEIXIN || MP-HARMONY
|
||||
vm.close()
|
||||
// #endif
|
||||
})
|
||||
},
|
||||
closeOther(vm) {
|
||||
if (this.openItem && this.openItem !== vm) {
|
||||
// #ifdef APP-VUE || H5 || MP-WEIXIN || MP-HARMONY
|
||||
this.openItem.is_show = 'none'
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-VUE || H5 || MP-WEIXIN || MP-HARMONY
|
||||
this.openItem.close()
|
||||
// #endif
|
||||
}
|
||||
// 记录上一个打开的 swipe-action-item ,用于 auto-close
|
||||
this.openItem = vm
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
113
uni_modules/uni-swipe-action/package.json
Normal file
113
uni_modules/uni-swipe-action/package.json
Normal file
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"id": "uni-swipe-action",
|
||||
"displayName": "uni-swipe-action 滑动操作",
|
||||
"version": "1.3.17",
|
||||
"description": "SwipeAction 滑动操作操作组件",
|
||||
"keywords": [
|
||||
"",
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"滑动删除",
|
||||
"侧滑删除"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": "",
|
||||
"uni-app": "^4.27",
|
||||
"uni-app-x": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||
"type": "component-vue",
|
||||
"darkmode": "x",
|
||||
"i18n": "x",
|
||||
"widescreen": "x"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [
|
||||
"uni-scss"
|
||||
],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "x",
|
||||
"aliyun": "x",
|
||||
"alipay": "x"
|
||||
},
|
||||
"client": {
|
||||
"uni-app": {
|
||||
"vue": {
|
||||
"vue2": {
|
||||
"extVersion": "1.3.14",
|
||||
"minVersion": ""
|
||||
},
|
||||
"vue3": {
|
||||
"extVersion": "1.3.14",
|
||||
"minVersion": ""
|
||||
}
|
||||
},
|
||||
"web": {
|
||||
"safari": "√",
|
||||
"chrome": "√"
|
||||
},
|
||||
"app": {
|
||||
"vue": "√",
|
||||
"nvue": "√",
|
||||
"android": "√",
|
||||
"ios": "√",
|
||||
"harmony": "√"
|
||||
},
|
||||
"mp": {
|
||||
"weixin": "√",
|
||||
"alipay": "√",
|
||||
"toutiao": "√",
|
||||
"baidu": "√",
|
||||
"kuaishou": "-",
|
||||
"jd": "-",
|
||||
"harmony": "-",
|
||||
"qq": "√",
|
||||
"lark": "-",
|
||||
"xhs": "-"
|
||||
},
|
||||
"quickapp": {
|
||||
"huawei": "√",
|
||||
"union": "√"
|
||||
}
|
||||
},
|
||||
"uni-app-x": {
|
||||
"web": {
|
||||
"safari": "-",
|
||||
"chrome": "-"
|
||||
},
|
||||
"app": {
|
||||
"android": "-",
|
||||
"ios": "-",
|
||||
"harmony": "-"
|
||||
},
|
||||
"mp": {
|
||||
"weixin": "-"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
uni_modules/uni-swipe-action/readme.md
Normal file
10
uni_modules/uni-swipe-action/readme.md
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
## SwipeAction 滑动操作
|
||||
> **组件名:uni-swipe-action**
|
||||
> 代码块: `uSwipeAction`、`uSwipeActionItem`
|
||||
|
||||
|
||||
通过滑动触发选项的容器
|
||||
|
||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-swipe-action)
|
||||
Reference in New Issue
Block a user