Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
40899e6d55 | ||
|
|
1d73755a43 | ||
|
|
f008bcb4b8 |
5
App.vue
5
App.vue
@@ -1,11 +1,11 @@
|
||||
<script>
|
||||
import { queryDictDataCache } from './common/api/dictionary.js'
|
||||
import { getImageUrl } from '@/common/api/basic'
|
||||
import { checkAppUpdate } from './common/js/update.js'
|
||||
|
||||
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
checkAppUpdate()
|
||||
|
||||
// uni.onPushMessage((res) => {
|
||||
// console.log("收到推送消息:",res) //监听推送消息
|
||||
// })
|
||||
@@ -72,4 +72,5 @@ export default {
|
||||
// .uni-page-refresh__icon {
|
||||
// fill: #007aff !important; /* 改成你想要的颜色,比如红色 #ff0000 */
|
||||
// }
|
||||
|
||||
</style>
|
||||
|
||||
@@ -2,14 +2,14 @@
|
||||
"version" : "2",
|
||||
"prompt" : "template",
|
||||
"title" : "服务协议和隐私政策",
|
||||
"message" : " 请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"https://pqmcn.com:8092/#/agreement\">《服务协议》</a>和<a href=\"https://pqmcn.com:8092/#/policy\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
|
||||
"message" : " 请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/> 你可阅读<a href=\"http://www.pqmcc.com:27707/#/agreement\">《服务协议》</a>和<a href=\"http://www.pqmcc.com:27707/#/policy\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
|
||||
"buttonAccept" : "同意并接受",
|
||||
"buttonRefuse" : "暂不同意",
|
||||
"hrefLoader" : "system|default",
|
||||
"backToExit" : "false",
|
||||
"second" : {
|
||||
"title" : "确认提示",
|
||||
"message" : " 进入应用前,你需先同意<a href=\"https://pqmcn.com:8092/#/agreement\">《用户协议》</a>和<a href=\"https://pqmcn.com:8092/#/policy\">《隐私政策》</a>,否则将退出应用。",
|
||||
"message" : " 进入应用前,你需先同意<a href=\"http://www.pqmcc.com:27707/#/agreement\">《用户协议》</a>和<a href=\"http://www.pqmcc.com:27707/#/policy\">《隐私政策》</a>,否则将退出应用。",
|
||||
"buttonAccept" : "同意并继续",
|
||||
"buttonRefuse" : "退出应用"
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ export function addFeedBack(params) {
|
||||
console.log(files.length);
|
||||
let data = JSON.parse(JSON.stringify(params));
|
||||
delete data.files
|
||||
console.log("🚀 ~ addFeedBack ~ files.length:", files.length)
|
||||
if (files.length) {
|
||||
return uni.uploadFile({
|
||||
url: config.domain + '/cs-system-boot/feedback/addFeedBack', //仅为示例,非真实的接口地址
|
||||
|
||||
@@ -242,4 +242,4 @@ export function getLastData() {
|
||||
url: '/cs-system-boot/appVersion/getLastData?versionType=APP',
|
||||
method: 'POST',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
const debug = true // true 是连地服务端本地,false 是连接线上
|
||||
const debug = false // true 是连地服务端本地,false 是连接线上
|
||||
|
||||
const development = {
|
||||
domain: 'http://192.168.2.126:10215',
|
||||
// domain: 'http://192.168.1.103:10215',
|
||||
domain: 'http://192.168.1.102:27707/api',
|
||||
}
|
||||
|
||||
const production = {
|
||||
domain: 'https://pqmcn.com:8092/api',
|
||||
domain: 'http://www.pqmcc.com:27707/api',
|
||||
}
|
||||
|
||||
const config = debug ? development : production
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// export const MQTT_IP = 'pqmcn.com:8085/mqtt'//mqtt地址端口, 使用emqx时一定要加mqtt
|
||||
export const MQTT_IP = '192.168.1.103:38083/mqtt'//mqtt地址端口, 使用emqx时一定要加mqtt
|
||||
export const MQTT_IP = 'pqmcn.com:8085/mqtt'//mqtt地址端口, 使用emqx时一定要加mqtt
|
||||
// export const MQTT_IP = '192.168.1.103:38083/mqtt'//mqtt地址端口, 使用emqx时一定要加mqtt
|
||||
// export const MQTT_IP = '192.168.1.103:38083/mqtt'//mqtt地址端口, 使用emqx时一定要加mqtt
|
||||
|
||||
const MQTT_USERNAME = 't_user'//mqtt用户名
|
||||
const MQTT_PASSWORD = 'njcnpqs'//密码
|
||||
|
||||
@@ -83,7 +83,10 @@ function errHandler(res) {
|
||||
break
|
||||
default:
|
||||
uni.showToast({
|
||||
title: res.message || res.msg || '网络异常,请稍后再试',
|
||||
title:
|
||||
res.message.substring(res.message.indexOf(',') + 1) ||
|
||||
res.msg.substring(msg.indexOf(',') + 1) ||
|
||||
'网络异常,请稍后再试',
|
||||
duration: 2000,
|
||||
icon: 'none',
|
||||
})
|
||||
|
||||
@@ -1,52 +1,102 @@
|
||||
import { getLastData } from '../api/user.js'
|
||||
|
||||
/** 规范化版本号,如 v1.6.83 → [1, 6, 83] */
|
||||
const normalizeVersion = (version) => {
|
||||
if (!version) return []
|
||||
return String(version)
|
||||
.replace(/^v/i, '')
|
||||
.split('.')
|
||||
.map((part) => parseInt(part, 10) || 0)
|
||||
}
|
||||
|
||||
/**
|
||||
* 比较版本号
|
||||
* @returns 1 远端较新需更新 | 0 相同 | -1 本地较新
|
||||
*/
|
||||
const compareVersion = (remote, local) => {
|
||||
const remoteParts = normalizeVersion(remote)
|
||||
const localParts = normalizeVersion(local)
|
||||
const len = Math.max(remoteParts.length, localParts.length)
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
const rv = remoteParts[i] || 0
|
||||
const lv = localParts[i] || 0
|
||||
if (rv > lv) return 1
|
||||
if (rv < lv) return -1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
/** 自定义调试基座 / HBuilder 标准基座,不走线上更新 */
|
||||
const isCustomDebugBase = (appName = '') => {
|
||||
return /自定义基座|custom debug|HBuilder|DCloud/i.test(appName)
|
||||
}
|
||||
|
||||
export const checkAppUpdate = () => {
|
||||
// #ifndef APP-PLUS
|
||||
// return
|
||||
// #endif
|
||||
|
||||
// 开发环境跳过检查
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
// if (isDev) {
|
||||
if (isDev) {
|
||||
console.log('开发环境,不执行更新检查')
|
||||
return
|
||||
// }
|
||||
}
|
||||
|
||||
// 自定义基座调试,跳过更新检查
|
||||
// try {
|
||||
// const { appName } = uni.getSystemInfoSync()
|
||||
// if (isCustomDebugBase(appName)) {
|
||||
// console.log('自定义基座调试中,不执行更新检查')
|
||||
// return
|
||||
// }
|
||||
// } catch (e) {}
|
||||
|
||||
// 获取当前应用信息
|
||||
plus.runtime.getProperty(plus.runtime.appid, (info) => {
|
||||
// if (isCustomDebugBase(info?.name)) {
|
||||
// console.log('自定义基座调试中,不执行更新检查')
|
||||
// return
|
||||
// }
|
||||
|
||||
const currentVersion = info.version
|
||||
|
||||
getLastData()
|
||||
.then((res) => {
|
||||
.then((res) => {
|
||||
// let res = {
|
||||
// data: {
|
||||
// versionName: 'v1.6.83',
|
||||
// forceUpdate: '1',
|
||||
// androidPath: 'https://app.liuyingyong.cn/build/download/3c26e400-3a33-11f1-8997-a16e76fa35b3',
|
||||
// // androidPath: 'http://112.4.144.18:8040/shiningCloud/file/canneng_wulian.apk',
|
||||
// iosPath: 'xxxx',
|
||||
// },
|
||||
// }
|
||||
if (!res?.data) {
|
||||
console.log('未获取到版本信息')
|
||||
return
|
||||
}
|
||||
|
||||
// let res = {
|
||||
// data: {
|
||||
// versionName: 'v1.6.83',
|
||||
// forceUpdate: '1',
|
||||
// androidPath: 'https://app.liuyingyong.cn/build/download/3c26e400-3a33-11f1-8997-a16e76fa35b3',
|
||||
// // androidPath: 'http://112.4.144.18:8040/shiningCloud/file/canneng_wulian.apk',
|
||||
// iosPath: 'xxxx',
|
||||
// },
|
||||
// }
|
||||
if (!res?.data) {
|
||||
console.log('未获取到版本信息')
|
||||
return
|
||||
}
|
||||
// 适配新的接口返回格式,默认强制更新
|
||||
const { versionName, androidPath, iosPath, forceUpdate = '1' } = res.data
|
||||
console.log('🚀 ~ checkAppUpdate ~ versionName, currentVersion:', versionName, currentVersion)
|
||||
|
||||
// 适配新的接口返回格式
|
||||
const { versionName, androidPath, iosPath, forceUpdate = '1' } = res.data
|
||||
// 版本相同或本地较新则不需要更新
|
||||
if (compareVersion(versionName, currentVersion) <= 0) {
|
||||
console.log('已是最新版本')
|
||||
return
|
||||
}
|
||||
|
||||
// 版本相同则不需要更新
|
||||
if (versionName.includes(currentVersion)) {
|
||||
console.log('已是最新版本')
|
||||
return
|
||||
}
|
||||
const isForce = forceUpdate !== '0' // 默认强制更新,'0' 为可选更新
|
||||
|
||||
const isForce = forceUpdate === '1' // 字符串 '1' 表示强制更新
|
||||
const iosUrl = iosPath
|
||||
|
||||
const iosUrl = iosPath
|
||||
|
||||
handleUpdate({ version: versionName, androidPath, iosUrl, isForce })
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('获取版本接口失败', err)
|
||||
})
|
||||
handleUpdate({ version: versionName, androidPath, iosUrl, isForce })
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('获取版本接口失败', err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -58,9 +108,9 @@ const handleUpdate = ({ version, androidPath, iosUrl, isForce }) => {
|
||||
const isIOS = plus.os.name === 'iOS'
|
||||
|
||||
if (isAndroid) {
|
||||
handleAndroidUpdate({ androidPath, isForce })
|
||||
handleAndroidUpdate({ version, androidPath, isForce })
|
||||
} else if (isIOS) {
|
||||
handleIOSUpdate({ iosUrl, isForce })
|
||||
handleIOSUpdate({ version, iosUrl, isForce })
|
||||
} else {
|
||||
console.warn('未知操作系统')
|
||||
}
|
||||
@@ -69,7 +119,7 @@ const handleUpdate = ({ version, androidPath, iosUrl, isForce }) => {
|
||||
/**
|
||||
* 处理安卓更新
|
||||
*/
|
||||
const handleAndroidUpdate = ({ androidPath, isForce }) => {
|
||||
const handleAndroidUpdate = ({ version, androidPath, isForce }) => {
|
||||
if (!androidPath?.length) {
|
||||
console.error('未找到安卓安装包')
|
||||
uni.showToast({
|
||||
@@ -80,18 +130,18 @@ const handleAndroidUpdate = ({ androidPath, isForce }) => {
|
||||
}
|
||||
|
||||
const downloadUrl = androidPath
|
||||
const content = isForce ? `发现新版本 ${version},请立即更新后继续使用` : `发现新版本 ${version},是否立即更新?`
|
||||
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '发现新版本,是否立即更新?',
|
||||
showCancel: !isForce, // 强制更新隐藏取消按钮
|
||||
content,
|
||||
showCancel: false,
|
||||
confirmText: '去更新',
|
||||
cancelText: '暂不更新',
|
||||
success: (modalRes) => {
|
||||
if (modalRes.confirm) {
|
||||
downloadAndInstallApk(downloadUrl)
|
||||
} else if (isForce) {
|
||||
// 强制更新且用户取消,退出应用
|
||||
// 强制更新:用户按返回键关闭弹窗时退出
|
||||
plus.runtime.quit()
|
||||
}
|
||||
},
|
||||
@@ -101,7 +151,7 @@ const handleAndroidUpdate = ({ androidPath, isForce }) => {
|
||||
/**
|
||||
* 处理iOS更新
|
||||
*/
|
||||
const handleIOSUpdate = ({ iosUrl, isForce }) => {
|
||||
const handleIOSUpdate = ({ version, iosUrl, isForce }) => {
|
||||
if (!iosUrl) {
|
||||
console.error('未找到iOS下载链接')
|
||||
uni.showToast({
|
||||
@@ -111,22 +161,23 @@ const handleIOSUpdate = ({ iosUrl, isForce }) => {
|
||||
return
|
||||
}
|
||||
|
||||
const content = isForce
|
||||
? `发现新版本 ${version},请前往 App Store 更新后继续使用`
|
||||
: `发现新版本 ${version},请前往 App Store 更新`
|
||||
|
||||
uni.showModal({
|
||||
title: '更新提示',
|
||||
content: '发现新版本,请前往 App Store 更新',
|
||||
showCancel: !isForce,
|
||||
content,
|
||||
showCancel: false,
|
||||
confirmText: '去更新',
|
||||
cancelText: '暂不更新',
|
||||
success: (modalRes) => {
|
||||
if (modalRes.confirm) {
|
||||
plus.runtime.openURL(iosUrl)
|
||||
}
|
||||
|
||||
// 强制更新时,无论确认还是取消都退出应用
|
||||
if (isForce) {
|
||||
setTimeout(() => {
|
||||
plus.runtime.quit()
|
||||
}, 300) // 给跳转留一点时间
|
||||
}, 300)
|
||||
} else if (isForce) {
|
||||
// 强制更新且用户取消,退出应用
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -143,14 +194,22 @@ const downloadAndInstallApk = (url) => {
|
||||
close: false, // 不允许用户关闭
|
||||
padlock: true, // 锁定屏幕
|
||||
})
|
||||
let progressClosed = false
|
||||
|
||||
const closeProgress = () => {
|
||||
if (progressClosed) return
|
||||
progressClosed = true
|
||||
progressWaiting.close()
|
||||
}
|
||||
|
||||
const options = {
|
||||
filename: '_doc/update/canneng_wulian.apk',
|
||||
timeout: 120,
|
||||
timeout: 300,
|
||||
}
|
||||
|
||||
console.log('🚀 ~ downloadAndInstallApk ~ url:', url)
|
||||
const downloadTask = plus.downloader.createDownload(url, options, (downloadedFile, status) => {
|
||||
progressWaiting.close()
|
||||
closeProgress()
|
||||
|
||||
if (status === 200) {
|
||||
installApk(downloadedFile.filename, url)
|
||||
@@ -161,11 +220,12 @@ const downloadAndInstallApk = (url) => {
|
||||
|
||||
// // 更新进度
|
||||
downloadTask.addEventListener('statechanged', (task) => {
|
||||
if (progressClosed) return
|
||||
if (task.state === 3 && task.totalSize > 0) {
|
||||
const percent = ((task.downloadedSize / task.totalSize) * 100).toFixed(0)
|
||||
console.log("🚀 ~ downloadAndInstallApk ~ percent:", percent)
|
||||
console.log('🚀 ~ downloadAndInstallApk ~ percent:', percent)
|
||||
// 直接更新 waiting 的标题,不会闪烁
|
||||
progressWaiting.setTitle(`正在下载更新 ${percent}%`)
|
||||
progressWaiting.setTitle(`正在下载更新...`)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -197,11 +257,13 @@ const installApk = (filePath, downloadUrl) => {
|
||||
uni.showModal({
|
||||
title: '安装失败',
|
||||
content: `安装失败:${error.message}\n请检查是否已开启安装权限`,
|
||||
showCancel: false,
|
||||
confirmText: '重试',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
downloadAndInstallApk(downloadUrl)
|
||||
} else {
|
||||
plus.runtime.quit()
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -216,11 +278,13 @@ const handleDownloadError = (downloadUrl) => {
|
||||
uni.showModal({
|
||||
title: '下载失败',
|
||||
content: '网络异常或下载链接失效,是否重试?',
|
||||
showCancel: false,
|
||||
confirmText: '重试',
|
||||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
downloadAndInstallApk(downloadUrl)
|
||||
} else {
|
||||
plus.runtime.quit()
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -183,35 +183,6 @@ const validatePhoneNumber = (phone) => {
|
||||
return testReg.test(phone)
|
||||
}
|
||||
|
||||
const getUserLocation = (call) => {
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: function (address) {
|
||||
call(address)
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '定位失败,请打开定位权限',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
uni.openSetting({
|
||||
success: (resSett) => {
|
||||
if (resSett.authSetting['scope.userLocation']) {
|
||||
uni.getLocation({
|
||||
success: (address) => {
|
||||
call && call(address)
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 加载用户配置
|
||||
var globalConfigIsLoading = false,
|
||||
@@ -349,7 +320,6 @@ export default {
|
||||
formatTime,
|
||||
parseTime,
|
||||
h5Helper,
|
||||
getUserLocation,
|
||||
loadConfig,
|
||||
prePage,
|
||||
loginSuccess,
|
||||
|
||||
@@ -16,15 +16,15 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
svgHtml() {
|
||||
if (this.name == '电压暂降') {
|
||||
if (this.name == '暂降') {
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
|
||||
<path d="M8,50 L15,50 L18,38 L21,28 L24,38 L27,50 L30,62 L33,72 L36,62 L39,50 L42,38 L45,28 L48,38 L51,50 L54,56 L56,54 L58,55 L60,54 L63,56 L66,60 L68,62 L70,60 L72,56 L75,54 L77,52 L79,54 L81,56 L84,50 L87,38 L90,28 L93,38 L96,50" fill="none" stroke="#2563eb" stroke-width="4"/>
|
||||
</svg>`
|
||||
} else if (this.name == '电压暂升') {
|
||||
} else if (this.name == '暂升') {
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
|
||||
<path d="M8,50 L15,50 L18,38 L21,28 L24,38 L27,50 L30,62 L33,72 L36,62 L39,50 L42,38 L45,28 L48,38 L51,50 L54,43 L56,34 L58,26 L60,34 L63,43 L66,54 L68,60 L70,54 L72,43 L75,34 L77,26 L79,34 L81,43 L84,50 L87,38 L90,28 L93,38 L96,50" fill="none" stroke="#e6a23c" stroke-width="4"/>
|
||||
</svg>`
|
||||
} else if (this.name == '电压中断') {
|
||||
} else if (this.name == '中断') {
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
|
||||
<path d="M8,50 L15,50 L18,38 L21,28 L24,38 L27,50 L30,62 L33,72 L36,62 L39,50 L42,38 L45,28 L48,38 L51,50 L54,50 L57,50 L60,50 L63,50 L66,50 L69,50 L72,50 L75,50 L78,50 L81,50 L84,50 L87,38 L90,28 L93,38 L96,50" fill="none" stroke="#6b7280" stroke-width="4"/>
|
||||
</svg>`
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
:style="{ color: confirmColor }"
|
||||
hover-class="hover-c"
|
||||
@tap="_confirm"
|
||||
>确定</view
|
||||
>完成</view
|
||||
>
|
||||
</view>
|
||||
<view class="tki-tree-bar1">
|
||||
|
||||
@@ -1,201 +1,222 @@
|
||||
<template>
|
||||
<view>
|
||||
<!-- 遮罩 -->
|
||||
<view class="mask" v-if="show" @tap="show = false" @touchmove.stop.prevent></view>
|
||||
<!-- 按钮 -->
|
||||
<view class="major-box" :class="{ show: show }">
|
||||
<view
|
||||
class="click-btn"
|
||||
v-if="!show"
|
||||
@tap="show = !show"
|
||||
draggable="true"
|
||||
|
||||
>
|
||||
<!-- @touchstart="touchstart"
|
||||
@touchmove.stop.prevent="touchmove" -->
|
||||
<view>< </view>
|
||||
</view>
|
||||
<view class="nav-box" v-if="show" style="max-width: 320px;">
|
||||
<view class="nav-btn" v-for="(btn, index) in btnList" :key="index" @tap="clickBtn(btn)">
|
||||
<view class="nav-icon">
|
||||
<image class="icon" :src="btn.iconPath"></image>
|
||||
</view>
|
||||
<view class="nav-text">{{ btn.text }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
btnList: {
|
||||
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false, // 是否显示
|
||||
deviationTop: 0, // 偏移量
|
||||
windowHeight: uni.getSystemInfoSync().windowHeight, // 视图高度
|
||||
// btnList: [
|
||||
// // 所有按钮
|
||||
// {
|
||||
// text: '首页',
|
||||
// icon: '/static/report.png',
|
||||
// type: 1,
|
||||
// },
|
||||
// {
|
||||
// text: '列表',
|
||||
// icon: '../../static/icon-add.png',
|
||||
// type: 2,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// ],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 点击按钮
|
||||
clickBtn: function (type) {
|
||||
// console.log(`123`, type)
|
||||
this.$emit('trigger',type)
|
||||
},
|
||||
// 拖动开始,记录一下偏移量
|
||||
touchstart: function (e) {
|
||||
var touch = e.touches[0] || e.changedTouches[0]
|
||||
this.deviationTop = touch.clientY - this.top
|
||||
// console.log(this.deviationTop);
|
||||
},
|
||||
// 上下拖动时
|
||||
touchmove: function (e) {
|
||||
var touch = e.touches[0] || e.changedTouches[0]
|
||||
var top = touch.clientY
|
||||
top = top - this.deviationTop
|
||||
if (top < 0) {
|
||||
top = 0
|
||||
}
|
||||
if (top > this.windowHeight - 40) {
|
||||
top = this.windowHeight - 40
|
||||
}
|
||||
this.top = top
|
||||
return false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 遮罩 */
|
||||
.mask {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
/* background: rgba(248, 248, 248, 0.8); */
|
||||
}
|
||||
|
||||
/* 总盒子 */
|
||||
.major-box {
|
||||
border: 1px 0 solid;
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
bottom: 5%;
|
||||
right: 0;
|
||||
transition: left 0.5s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.click-btn,
|
||||
.nav-box {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.nav-box {
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 0 5px;
|
||||
}
|
||||
|
||||
.click-btn {
|
||||
width: 20px;
|
||||
height: 40px;
|
||||
background-color: #999;
|
||||
color: #fff;
|
||||
opacity: 0.8;
|
||||
text-align: center;
|
||||
border-radius: 50px 0 0 50px;
|
||||
padding: 6px 0;
|
||||
}
|
||||
|
||||
.click-btn uni-view {
|
||||
line-height: 40px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.click-btn view {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
/* 按钮盒子 */
|
||||
.nav-box {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
text-align: center;
|
||||
padding-left: 20px;
|
||||
/* justify-content: center; */
|
||||
background-color: #d8d7d7;
|
||||
color: #000;
|
||||
font-size: 12rpx;
|
||||
/* opacity: 0.8; */
|
||||
text-align: center;
|
||||
border-radius: 50px 0 0 50px;
|
||||
|
||||
/* border-width: 0px; */
|
||||
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
/* flex: 1; */
|
||||
border: 0px #000 solid;
|
||||
min-width: 63px;
|
||||
padding: 5px 0 5px 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin: 0 auto;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view>
|
||||
<!-- 遮罩 -->
|
||||
<view class="mask" v-if="show" @tap="show = false" @touchmove.stop.prevent></view>
|
||||
<!-- 按钮 -->
|
||||
<view class="major-box" :class="{ show: show }">
|
||||
<view class="click-btn" v-if="!show" @tap="show = !show" draggable="true">
|
||||
|
||||
<!-- <view>< </view> -->
|
||||
<uni-icons type="left" size="26" color="#645555"></uni-icons>
|
||||
</view>
|
||||
<view class="nav-box" v-if="show" style="max-width: 320px;">
|
||||
<view class="click-btn click-btn-right" @tap="show = !show" draggable="true">
|
||||
|
||||
<!-- <view>> </view> -->
|
||||
<uni-icons type="right" size="26" color="#645555"></uni-icons>
|
||||
</view>
|
||||
<view class="nav-box-list">
|
||||
<view class="nav-btn" v-for="(btn, index) in btnList" :key="index" @tap="clickBtn(btn)">
|
||||
<view class="nav-icon">
|
||||
<image class="icon" :src="btn.iconPath"></image>
|
||||
</view>
|
||||
<view class="nav-text">{{ btn.text }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
btnList: {
|
||||
|
||||
default: {},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
show: false, // 是否显示
|
||||
deviationTop: 0, // 偏移量
|
||||
windowHeight: uni.getSystemInfoSync().windowHeight, // 视图高度
|
||||
// btnList1: [
|
||||
// // 所有按钮
|
||||
// {
|
||||
// text: '首页',
|
||||
// icon: '/static/report.png',
|
||||
// type: 1,
|
||||
// },
|
||||
// {
|
||||
// text: '列表',
|
||||
// icon: '../../static/icon-add.png',
|
||||
// type: 2,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// {
|
||||
// text: '列表详情',
|
||||
// icon: '../../static/icon-visit.png',
|
||||
// type: 3,
|
||||
// },
|
||||
// ],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 点击按钮
|
||||
clickBtn: function (type) {
|
||||
// console.log(`123`, type)
|
||||
this.$emit('trigger', type)
|
||||
},
|
||||
// 拖动开始,记录一下偏移量
|
||||
touchstart: function (e) {
|
||||
var touch = e.touches[0] || e.changedTouches[0]
|
||||
this.deviationTop = touch.clientY - this.top
|
||||
// console.log(this.deviationTop);
|
||||
},
|
||||
// 上下拖动时
|
||||
touchmove: function (e) {
|
||||
var touch = e.touches[0] || e.changedTouches[0]
|
||||
var top = touch.clientY
|
||||
top = top - this.deviationTop
|
||||
if (top < 0) {
|
||||
top = 0
|
||||
}
|
||||
if (top > this.windowHeight - 40) {
|
||||
top = this.windowHeight - 40
|
||||
}
|
||||
this.top = top
|
||||
return false
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 遮罩 */
|
||||
.mask {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 99;
|
||||
/* background: rgba(248, 248, 248, 0.8); */
|
||||
}
|
||||
|
||||
/* 总盒子 */
|
||||
.major-box {
|
||||
border: 1px 0 solid;
|
||||
z-index: 100;
|
||||
position: fixed;
|
||||
bottom: 5%;
|
||||
right: 0;
|
||||
transition: left 0.5s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.click-btn,
|
||||
.nav-box {
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* 按钮样式 */
|
||||
.nav-box {
|
||||
background-color: #fff;
|
||||
border-radius: 0 0 0 5px;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.click-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
min-height: 40px;
|
||||
height: 100%;
|
||||
background-color: #d8d7d7;
|
||||
color: #fff;
|
||||
opacity: 0.8;
|
||||
text-align: center;
|
||||
border-radius: 50px 0 0 50px;
|
||||
padding: 6px 0;
|
||||
font-weight: 700;
|
||||
|
||||
}
|
||||
|
||||
.click-btn uni-view {
|
||||
line-height: 40px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.click-btn view {
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
||||
.click-btn-right {
|
||||
background-color: #d8d7d7;
|
||||
margin-left: 5px;
|
||||
|
||||
}
|
||||
|
||||
/* 按钮盒子 */
|
||||
.nav-box {
|
||||
display: flex;
|
||||
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
|
||||
background-color: #d8d7d7;
|
||||
color: #000;
|
||||
font-size: 12rpx;
|
||||
text-align: center;
|
||||
border-radius: 50px 0 0 50px;
|
||||
}
|
||||
.nav-box-list{
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
gap: 8px 0;
|
||||
background-color: #d8d7d7;
|
||||
color: #000;
|
||||
font-size: 12rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.nav-btn {
|
||||
/* flex: 1; */
|
||||
border: 0px #000 solid;
|
||||
min-width: 55px;
|
||||
|
||||
}
|
||||
|
||||
.icon {
|
||||
margin: 0 auto;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.nav-text {
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
"name" : "灿能物联",
|
||||
"appid" : "__UNI__88BC25B",
|
||||
"description" : "",
|
||||
"versionName" : "1.6.82",
|
||||
"versionCode" : 170,
|
||||
"versionName" : "2.0.1",
|
||||
"versionCode" : 176,
|
||||
"transformPx" : false,
|
||||
"sassImplementationName" : "node-sass",
|
||||
/* 5+App特有相关 */
|
||||
@@ -46,6 +46,7 @@
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
|
||||
"<uses-permission android:name=\"android.permission.REQUEST_INSTALL_PACKAGES\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
@@ -124,7 +125,10 @@
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
"usingComponents" : true,
|
||||
"unipush" : {
|
||||
"enable" : false
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
@@ -138,8 +142,9 @@
|
||||
"proxy" : {
|
||||
"/api" : {
|
||||
"https" : true,
|
||||
// "target" : "https://pqmcn.com:8092/api",
|
||||
"target" : "http://192.168.2.126:10215",
|
||||
"target" : "http://www.pqmcc.com:27707/api",
|
||||
// "target" : "http://192.168.1.102:27707/api",
|
||||
// "target" : "http://192.168.1.103:10215",
|
||||
"changOrigin" : true,
|
||||
"pathRewrite" : {
|
||||
"/api" : ""
|
||||
@@ -152,7 +157,7 @@
|
||||
"base" : ""
|
||||
},
|
||||
"unipush" : {
|
||||
"enable" : false
|
||||
"enable" : true
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
"maps" : {}
|
||||
|
||||
15
pages.json
15
pages.json
@@ -118,14 +118,14 @@
|
||||
{
|
||||
"path": "pages/mine/setupMessage",
|
||||
"style": {
|
||||
"navigationBarTitleText": "个性化推荐"
|
||||
"navigationBarTitleText": "推送通知配置"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "pages/index/comp/monitoringPoint",
|
||||
"style": {
|
||||
"navigationBarTitleText": "监测点电能质量信息",
|
||||
"navigationBarTitleText": "关键指标概览",
|
||||
"enablePullDownRefresh": true,
|
||||
"pullToRefresh": {
|
||||
"support":true,
|
||||
@@ -234,13 +234,13 @@
|
||||
{
|
||||
"path": "pages/device/APF/about",
|
||||
"style": {
|
||||
"navigationBarTitleText": "关于"
|
||||
"navigationBarTitleText": "详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/device/DVR/about",
|
||||
"style": {
|
||||
"navigationBarTitleText": "关于"
|
||||
"navigationBarTitleText": "详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -446,12 +446,7 @@
|
||||
"navigationBarTitleText": "服务内容配置"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mine/transientSetting",
|
||||
"style": {
|
||||
"navigationBarTitleText": "暂态事件配置"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "pages/user/erweima",
|
||||
"style": {
|
||||
|
||||
@@ -1,86 +1,70 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-load-more status="loading" v-if="IOData.length == 0"></uni-load-more>
|
||||
<view class="basic" v-else>
|
||||
<view class="grid-card">
|
||||
<text>
|
||||
<view class="grid-card-title grid-card-title-with-icon"></view>温度
|
||||
</text>
|
||||
<view class="grid-card-content-4">
|
||||
<template v-for="item in renderData">
|
||||
<view class="item item-title">{{ item[0].clDid }}
|
||||
<template v-if="item[0].clDid"> (°C)</template>
|
||||
<view class="basic mt10" v-else>
|
||||
<view class="params-wrap">
|
||||
<view class="section-title-row">
|
||||
<view class="section-title">
|
||||
<view class="grid-card-title-with-icon"></view>
|
||||
<text>温度</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="params-section">
|
||||
<view
|
||||
v-for="(rowItems, rowIdx) in chunkedChildren(temperatureCards)"
|
||||
:key="'temp-' + rowIdx"
|
||||
class="double-row"
|
||||
>
|
||||
<view v-for="(child, childIdx) in rowItems" :key="childIdx" class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ child.name }}</text>
|
||||
</view>
|
||||
<view class="param-value-wrap">
|
||||
<text class="param-value">{{ child.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item item-title">{{ item[1].clDid }}
|
||||
<template v-if="item[1].clDid"> (°C)</template>
|
||||
</view>
|
||||
<view class="item item-title">{{ item[2].clDid }}
|
||||
<template v-if="item[2].clDid"> (°C)</template>
|
||||
</view>
|
||||
<view class="item item-title">{{ item[3].clDid }}
|
||||
<template v-if="item[3].clDid"> (°C)</template>
|
||||
</view>
|
||||
<view class="item">{{ item[0].clDid ? Math.round(item[0].value) || '-' : '' }}</view>
|
||||
<view class="item">{{ item[1].clDid ? Math.round(item[1].value) || '-' : '' }}</view>
|
||||
<view class="item">{{ item[2].clDid ? Math.round(item[2].value) || '-' : '' }}</view>
|
||||
<view class="item">{{ item[3].clDid ? Math.round(item[3].value) || '-' : '' }}</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 运维管理员、工程用户 可看 -->
|
||||
<view class="grid-card"
|
||||
v-if="(userInfo.authorities == 'operation_manager' || userInfo.authorities == 'engineering_user') && moduleData.length > 0">
|
||||
<view class="grid-card-title">
|
||||
|
||||
<text><view class="grid-card-title-with-icon"></view>状态</text>
|
||||
|
||||
<view class="params-wrap" v-if="showModuleSection">
|
||||
<view class="section-title-row">
|
||||
<view class="section-title">
|
||||
<view class="grid-card-title-with-icon"></view>
|
||||
<text>状态</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-card-content-4">
|
||||
<template v-for="(item, index) in moduleData">
|
||||
<view class="item item-title">{{ item[0].moduleName }}
|
||||
<template v-if="item[0].moduleName"></template>
|
||||
<view class="params-section">
|
||||
<view
|
||||
v-for="(rowItems, rowIdx) in chunkedChildren(moduleCards)"
|
||||
:key="'module-' + rowIdx"
|
||||
class="double-row"
|
||||
>
|
||||
<view v-for="(child, childIdx) in rowItems" :key="childIdx" class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ child.name }}</text>
|
||||
</view>
|
||||
<view class="param-value-wrap">
|
||||
<text
|
||||
class="param-value"
|
||||
:class="{ 'param-value--offline': child.value === '离线' }"
|
||||
>{{ child.value }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item item-title">{{ item[1].moduleName }}
|
||||
<template v-if="item[1].moduleName"></template>
|
||||
</view>
|
||||
<view class="item item-title">{{ item[2].moduleName }}
|
||||
<template v-if="item[2].moduleName"></template>
|
||||
</view>
|
||||
<view class="item item-title">{{ item[3].moduleName }}
|
||||
<template v-if="item[3].moduleName"></template>
|
||||
</view>
|
||||
<!-- <uni-tag :text="item[0].moduleState" :type=" item[0].moduleState=='离线'?'error' : 'success'" /> -->
|
||||
<view class="item">{{ item[0].moduleState }}</view>
|
||||
<view class="item">{{ item[1].moduleState }}</view>
|
||||
<view class="item">{{ item[2].moduleState }}</view>
|
||||
<view class="item">{{ item[3].moduleState }}</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <view class="grid-card">-->
|
||||
<!-- <view class="grid-card-title">干接点</view>-->
|
||||
<!-- <view class="grid-card-content-4">-->
|
||||
<!-- <view class="item item-title">干接点1</view>-->
|
||||
<!-- <view class="item item-title">干接点2</view>-->
|
||||
<!-- <view class="item item-title"></view>-->
|
||||
<!-- <view class="item item-title"></view>-->
|
||||
<!-- <view class="item">正常</view>-->
|
||||
<!-- <view class="item">正常</view>-->
|
||||
<!-- <view class="item"></view>-->
|
||||
<!-- <view class="item"></view>-->
|
||||
<!-- </view>-->
|
||||
<!-- </view>-->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import { getModuleState } from '@/common/api/harmonic.js'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
IOData: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
},
|
||||
default: () => [],
|
||||
},
|
||||
ndid: {
|
||||
type: String,
|
||||
@@ -90,87 +74,174 @@ export default {
|
||||
return {
|
||||
list: [],
|
||||
userInfo: {},
|
||||
flag: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
renderData() {
|
||||
let arr = []
|
||||
|
||||
// 把IOData转换成每4个一组的二维数组
|
||||
for (let i = 0; i < this.IOData.length; i += 4) {
|
||||
this.IOData.slice(i, i + 4).forEach((item) => {
|
||||
if (Number.isInteger(item.value) || item.value == '') {
|
||||
} else {
|
||||
item.value = (item.value - 0).toFixed(2)
|
||||
const arr = []
|
||||
const data = this.IOData || []
|
||||
for (let i = 0; i < data.length; i += 4) {
|
||||
const group = data.slice(i, i + 4).map((item) => {
|
||||
const next = { ...item }
|
||||
if (!Number.isInteger(next.value) && next.value !== '') {
|
||||
next.value = (next.value - 0).toFixed(2)
|
||||
}
|
||||
return next
|
||||
})
|
||||
arr.push(this.IOData.slice(i, i + 4))
|
||||
}
|
||||
// 把每组的长度补齐到4
|
||||
arr.forEach((item) => {
|
||||
if (item.length < 4) {
|
||||
let length = 4 - item.length
|
||||
for (let i = 0; i < length; i++) {
|
||||
item.push({})
|
||||
}
|
||||
while (group.length < 4) {
|
||||
group.push({})
|
||||
}
|
||||
})
|
||||
arr.push(group)
|
||||
}
|
||||
return arr
|
||||
},
|
||||
moduleData() {
|
||||
let arr = []
|
||||
// 把IOData转换成每4个一组的二维数组
|
||||
const arr = []
|
||||
for (let i = 0; i < this.list.length; i += 4) {
|
||||
arr.push(this.list.slice(i, i + 4))
|
||||
}
|
||||
// 把每组的长度补齐到4
|
||||
arr.forEach((item) => {
|
||||
if (item.length < 4) {
|
||||
let length = 4 - item.length
|
||||
for (let i = 0; i < length; i++) {
|
||||
item.push({})
|
||||
}
|
||||
const group = this.list.slice(i, i + 4)
|
||||
while (group.length < 4) {
|
||||
group.push({})
|
||||
}
|
||||
})
|
||||
console.warn(arr)
|
||||
arr.push(group)
|
||||
}
|
||||
return arr
|
||||
},
|
||||
temperatureCards() {
|
||||
const cards = []
|
||||
this.renderData.forEach((row) => {
|
||||
row.forEach((item) => {
|
||||
if (!item.clDid) return
|
||||
cards.push({
|
||||
name: `${item.clDid} (°C)`,
|
||||
value: Math.round(item.value) ,
|
||||
})
|
||||
})
|
||||
})
|
||||
return cards
|
||||
},
|
||||
moduleCards() {
|
||||
const cards = []
|
||||
this.moduleData.forEach((row) => {
|
||||
row.forEach((item) => {
|
||||
if (!item.moduleName) return
|
||||
cards.push({
|
||||
name: item.moduleName,
|
||||
value: item.moduleState ,
|
||||
})
|
||||
})
|
||||
})
|
||||
return cards
|
||||
},
|
||||
showModuleSection() {
|
||||
return (
|
||||
(this.userInfo.authorities === 'operation_manager' ||
|
||||
this.userInfo.authorities === 'engineering_user') &&
|
||||
this.moduleCards.length > 0
|
||||
)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
|
||||
this.info()
|
||||
},
|
||||
methods: {
|
||||
info() {
|
||||
getModuleState({
|
||||
id: this.ndid,
|
||||
}).then((res) => {
|
||||
this.list = res.data
|
||||
this.list = res.data || []
|
||||
})
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
|
||||
|
||||
this.info()
|
||||
chunkedChildren(children) {
|
||||
const result = []
|
||||
for (let i = 0; i < children.length; i += 2) {
|
||||
result.push(children.slice(i, i + 2))
|
||||
}
|
||||
return result
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.basic {
|
||||
.params-wrap {
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
padding: 20rpx 20rpx 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.grid-card-title-with-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 12rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
.params-section {
|
||||
padding: 16rpx 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.double-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.param-group {
|
||||
min-width: 0;
|
||||
background: #f3f3f3;
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 8rpx 12rpx;
|
||||
}
|
||||
|
||||
.param-title {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 8rpx;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
.param-value-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rpx;
|
||||
}
|
||||
|
||||
.param-value {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #333;
|
||||
|
||||
&--offline {
|
||||
color: #ff3b30;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,115 +1,105 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-load-more status="loading"
|
||||
v-if="renderData.电网电流.length == 0 || renderData.电网电压.length == 0 || renderData.负载电流.length == 0 || renderData.补偿电流.length == 0"></uni-load-more>
|
||||
<view class="basic" v-else>
|
||||
<view class="grid-card">
|
||||
|
||||
<text>
|
||||
<view class="grid-card-title grid-card-title-with-icon"></view>电网电流
|
||||
</text>
|
||||
|
||||
<view class="grid-card-content-3">
|
||||
<view class="item item-title">名称</view>
|
||||
<view class="item item-title">有效值(A)</view>
|
||||
<view class="item item-title">畸变率(%)</view>
|
||||
<template v-for="(item, index) in renderData.电网电流">
|
||||
<view class="item">{{ item.phase }}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_RmsI_Sys(A)'] > 0 ? item['Apf_RmsI_Sys(A)'].toFixed(2) : item['Apf_RmsI_Sys(A)']
|
||||
}}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_ThdA_Sys(%)'] > 0 ? item['Apf_ThdA_Sys(%)'].toFixed(2) : item['Apf_ThdA_Sys(%)']
|
||||
}}</view>
|
||||
</template>
|
||||
<uni-load-more status="loading" v-if="!isDataReady"></uni-load-more>
|
||||
<view class="basic mt10" v-else>
|
||||
<view class="params-wrap" v-for="(section, ind) in sections" :key="section.title">
|
||||
<view class="section-title-row">
|
||||
<view class="section-title">
|
||||
<view class="grid-card-title-with-icon"></view>
|
||||
<text>{{ section.title }}</text>
|
||||
</view>
|
||||
<view class="legend-row" v-if="ind == 0">
|
||||
<view class="legend-item" v-for="phase in phaseColors" :key="phase.name">
|
||||
<view class="legend-dot" :style="{ background: phase.color }" />
|
||||
<text class="legend-text">{{ phase.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-card">
|
||||
|
||||
<text>
|
||||
<view class="grid-card-title grid-card-title-with-icon"></view>电网电压
|
||||
</text>
|
||||
|
||||
<view class="grid-card-content-4">
|
||||
<view class="item item-title">名称</view>
|
||||
<view class="item item-title">电压(V)</view>
|
||||
<view class="item item-title">频率(Hz)</view>
|
||||
<view class="item item-title">畸变率(%)</view>
|
||||
<template v-for="(item, index) in renderData.电网电压">
|
||||
<view class="item">{{ item.phase }}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_PhV_Sys(V)'] > 0 ? item['Apf_PhV_Sys(V)'].toFixed(2) : item['Apf_PhV_Sys(V)']
|
||||
}}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_Freq(Hz)'] > 0 ? item['Apf_Freq(Hz)'].toFixed(2) : item['Apf_Freq(Hz)']
|
||||
}}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_ThdU_Sys(%)'] > 0 ? item['Apf_ThdU_Sys(%)'].toFixed(2) : item['Apf_ThdU_Sys(%)']
|
||||
}}</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-card">
|
||||
|
||||
<text>
|
||||
<view class="grid-card-title grid-card-title-with-icon"></view>负载电流
|
||||
</text>
|
||||
|
||||
<view class="grid-card-content-3">
|
||||
<view class="item item-title">名称</view>
|
||||
<view class="item item-title">有效值(A)</view>
|
||||
<view class="item item-title">畸变率(%)</view>
|
||||
<template v-for="(item, index) in renderData.负载电流">
|
||||
<view class="item">{{ item.phase }}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_RmsI_Load(A)'] > 0
|
||||
? item['Apf_RmsI_Load(A)'].toFixed(2)
|
||||
: item['Apf_RmsI_Load(A)']
|
||||
}}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_ThdA_Load(%)'] > 0
|
||||
? item['Apf_ThdA_Load(%)'].toFixed(2)
|
||||
: item['Apf_ThdA_Load(%)']
|
||||
}}</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-card">
|
||||
|
||||
<text>
|
||||
<view class="grid-card-title grid-card-title-with-icon"></view>补偿电流
|
||||
</text>
|
||||
|
||||
<view class="grid-card-content-3">
|
||||
<view class="item item-title">名称</view>
|
||||
<view class="item item-title">有效值(A)</view>
|
||||
<view class="item item-title">负载率(%)</view>
|
||||
<template v-for="(item, index) in renderData.补偿电流">
|
||||
<view class="item">{{ item.phase }}</view>
|
||||
<view class="item">{{
|
||||
item['Apf_RmsI_TolOut(A)'] == 3.1415926
|
||||
? '-'
|
||||
: item['Apf_RmsI_TolOut(A)'] > 0
|
||||
? item['Apf_RmsI_TolOut(A)'].toFixed(2)
|
||||
: item['Apf_RmsI_TolOut(A)']
|
||||
}}</view>
|
||||
<view class="item">{{
|
||||
item['load_Rate'] == 3.1415926
|
||||
? '-'
|
||||
: item['load_Rate'] > 0
|
||||
? item['load_Rate'].toFixed(2)
|
||||
: item['load_Rate']
|
||||
}}</view>
|
||||
</template>
|
||||
<view class="params-section">
|
||||
<view v-for="(rowItems, rowIdx) in chunkedChildren(getSectionCards(section))" :key="rowIdx"
|
||||
class="double-row">
|
||||
<view v-for="(child, childIdx) in rowItems" :key="childIdx" class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ child.name }}</text>
|
||||
</view>
|
||||
<view class="phase-vertical">
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[0].color }">{{
|
||||
child.A
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[1].color }">{{
|
||||
child.B
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[2].color }">{{
|
||||
child.C
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const SECTIONS = [
|
||||
{
|
||||
title: '电网电流',
|
||||
dataKey: '电网电流',
|
||||
metrics: [
|
||||
{ label: '有效值(A)', field: 'Apf_RmsI_Sys(A)' },
|
||||
{ label: '畸变率(%)', field: 'Apf_ThdA_Sys(%)' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '电网电压',
|
||||
dataKey: '电网电压',
|
||||
metrics: [
|
||||
{ label: '电压(V)', field: 'Apf_PhV_Sys(V)' },
|
||||
{ label: '频率(Hz)', field: 'Apf_Freq(Hz)' },
|
||||
{ label: '畸变率(%)', field: 'Apf_ThdU_Sys(%)' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '负载电流',
|
||||
dataKey: '负载电流',
|
||||
metrics: [
|
||||
{ label: '有效值(A)', field: 'Apf_RmsI_Load(A)' },
|
||||
{ label: '畸变率(%)', field: 'Apf_ThdA_Load(%)' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '补偿电流',
|
||||
dataKey: '补偿电流',
|
||||
metrics: [
|
||||
{ label: '有效值(A)', field: 'Apf_RmsI_TolOut(A)' },
|
||||
{ label: '负载率(%)', field: 'load_Rate' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export default {
|
||||
props: {
|
||||
basicData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sections: SECTIONS,
|
||||
phaseColors: [
|
||||
{ name: 'A相', color: '#DAA520' },
|
||||
{ name: 'B相', color: '#2E8B57' },
|
||||
{ name: 'C相', color: '#D54941' },
|
||||
],
|
||||
renderData: {
|
||||
电网电流: [],
|
||||
电网电压: [],
|
||||
@@ -119,101 +109,209 @@ export default {
|
||||
},
|
||||
}
|
||||
},
|
||||
props: {
|
||||
basicData: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
},
|
||||
computed: {
|
||||
isDataReady() {
|
||||
return (
|
||||
this.renderData.电网电流.length > 0 &&
|
||||
this.renderData.电网电压.length > 0 &&
|
||||
this.renderData.负载电流.length > 0 &&
|
||||
this.renderData.补偿电流.length > 0
|
||||
)
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
basicData: {
|
||||
handler: function (newVal, oldVal) {
|
||||
newVal.forEach((item) => {
|
||||
if (item.phase === 'avg') {
|
||||
return
|
||||
}
|
||||
let key = ''
|
||||
switch (item.statisticalName) {
|
||||
case 'Apf_RmsI_Sys(A)':
|
||||
key = '电网电流'
|
||||
break
|
||||
case 'Apf_ThdA_Sys(%)':
|
||||
key = '电网电流'
|
||||
break
|
||||
case 'Apf_PhV_Sys(V)':
|
||||
key = '电网电压'
|
||||
break
|
||||
case 'Apf_Freq(Hz)':
|
||||
key = '电网电压'
|
||||
break
|
||||
case 'Apf_ThdU_Sys(%)':
|
||||
key = '电网电压'
|
||||
break
|
||||
case 'Apf_RmsI_Load(A)':
|
||||
key = '负载电流'
|
||||
break
|
||||
case 'Apf_ThdA_Load(%)':
|
||||
key = '负载电流'
|
||||
break
|
||||
case 'Apf_RmsI_TolOut(A)':
|
||||
key = '补偿电流'
|
||||
break
|
||||
case 'Apf_PhV_Sys(V)':
|
||||
key = '补偿电流'
|
||||
break
|
||||
case 'Apf_PhV_Sys(V)':
|
||||
key = '补偿电流'
|
||||
break
|
||||
case 'load_Rate':
|
||||
key = '补偿电流'
|
||||
break
|
||||
default:
|
||||
key = '未知'
|
||||
break
|
||||
}
|
||||
|
||||
let index = this.renderData[key].findIndex((item2) => {
|
||||
return item2.phase === item.phase
|
||||
handler(newVal) {
|
||||
this.renderData = {
|
||||
电网电流: [],
|
||||
电网电压: [],
|
||||
负载电流: [],
|
||||
补偿电流: [],
|
||||
未知: [],
|
||||
}
|
||||
; (newVal || []).forEach((item) => {
|
||||
if (item.phase === 'avg') {
|
||||
return
|
||||
}
|
||||
const key = this.getDataKey(item.statisticalName)
|
||||
const index = this.renderData[key].findIndex((item2) => item2.phase === item.phase)
|
||||
if (index > -1) {
|
||||
this.renderData[key][index][item.statisticalName] = item.statisticalData
|
||||
} else {
|
||||
this.renderData[key].push({
|
||||
phase: item.phase,
|
||||
[item.statisticalName]: item.statisticalData,
|
||||
})
|
||||
}
|
||||
})
|
||||
if (index > -1) {
|
||||
this.renderData[key][index][item.statisticalName] = item.statisticalData //
|
||||
} else {
|
||||
this.renderData[key].push({
|
||||
phase: item.phase,
|
||||
[item.statisticalName]: item.statisticalData, //,
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(this.renderData)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
getDataKey(statisticalName) {
|
||||
switch (statisticalName) {
|
||||
case 'Apf_RmsI_Sys(A)':
|
||||
case 'Apf_ThdA_Sys(%)':
|
||||
return '电网电流'
|
||||
case 'Apf_PhV_Sys(V)':
|
||||
case 'Apf_Freq(Hz)':
|
||||
case 'Apf_ThdU_Sys(%)':
|
||||
return '电网电压'
|
||||
case 'Apf_RmsI_Load(A)':
|
||||
case 'Apf_ThdA_Load(%)':
|
||||
return '负载电流'
|
||||
case 'Apf_RmsI_TolOut(A)':
|
||||
case 'load_Rate':
|
||||
return '补偿电流'
|
||||
default:
|
||||
return '未知'
|
||||
}
|
||||
},
|
||||
getSectionCards(section) {
|
||||
const list = this.renderData[section.dataKey] || []
|
||||
return section.metrics.map((metric) => ({
|
||||
name: metric.label,
|
||||
A: this.getPhaseValue(list, metric.field, 'A'),
|
||||
B: this.getPhaseValue(list, metric.field, 'B'),
|
||||
C: this.getPhaseValue(list, metric.field, 'C'),
|
||||
}))
|
||||
},
|
||||
getPhaseValue(list, field, phase) {
|
||||
const item = list.find(
|
||||
(row) => String(row.phase || '').toUpperCase() === phase,
|
||||
)
|
||||
return this.formatValue(item[field])
|
||||
},
|
||||
formatValue(value) {
|
||||
if (value == 3.1415926) return '-'
|
||||
if (value === undefined || value === null || value === '') return '-'
|
||||
const num = Number(value)
|
||||
if (Number.isNaN(num)) return value
|
||||
return num > 0 ? num.toFixed(2) : num
|
||||
},
|
||||
chunkedChildren(children) {
|
||||
const result = []
|
||||
for (let i = 0; i < children.length; i += 2) {
|
||||
result.push(children.slice(i, i + 2))
|
||||
}
|
||||
return result
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.basic {
|
||||
.params-wrap {
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
padding: 20rpx 20rpx 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.grid-card-title-with-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 12rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
.legend-row {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.legend-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.params-section {
|
||||
padding: 16rpx 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.double-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.param-group {
|
||||
min-width: 0;
|
||||
background: #f3f3f3;
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 8rpx 12rpx;
|
||||
}
|
||||
|
||||
.param-title {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 8rpx;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
.phase-vertical {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.phase-item-vertical {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rpx;
|
||||
}
|
||||
|
||||
.phase-value-vertical {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.phase-divider {
|
||||
width: 1px;
|
||||
background: #d2d2d2;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,119 +1,119 @@
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<uni-data-checkbox multiple v-model="checkbox" :localdata="hobby"></uni-data-checkbox>
|
||||
<view class="charts-box">
|
||||
<qiun-data-charts ontouch onzoom type="line" :opts="opts" :chartData="chartData" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
checkbox: [0, 1, 2],
|
||||
hobby: [{
|
||||
text: '电网电压1',
|
||||
value: 0
|
||||
}, {
|
||||
text: '电网电压2',
|
||||
value: 1
|
||||
}, {
|
||||
text: '电网电压3',
|
||||
value: 2
|
||||
}, {
|
||||
text: '电网电压3',
|
||||
value: 4
|
||||
}],
|
||||
chartData: {},
|
||||
//您可以通过修改 config-ucharts.js 文件中下标为 ['line'] 的节点来配置全局默认参数,如都是默认参数,此处可以不传 opts 。实际应用过程中 opts 只需传入与全局默认参数中不一致的【某一个属性】即可实现同类型的图表显示不同的样式,达到页面简洁的需求。
|
||||
opts: {
|
||||
color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
|
||||
padding: [15, 15, 0, 0],
|
||||
dataLabel: false,
|
||||
dataPointShape: false,
|
||||
enableScroll: true,
|
||||
legend: {},
|
||||
xAxis: {
|
||||
disableGrid: true,
|
||||
itemCount: 10240,
|
||||
},
|
||||
yAxis: {
|
||||
gridType: "dash",
|
||||
dashLength: 2,
|
||||
data: [
|
||||
{
|
||||
min: -100,
|
||||
max: 100
|
||||
}
|
||||
]
|
||||
},
|
||||
// extra: {
|
||||
// line: {
|
||||
// type: "curve",
|
||||
// width: 2,
|
||||
// activeType: "hollow",
|
||||
// linearType: "custom"
|
||||
// }
|
||||
// }
|
||||
},
|
||||
testDataA: [],
|
||||
testDataB: [],
|
||||
testDataC: [],
|
||||
testCategories: []
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
this.getServerData();
|
||||
},
|
||||
methods: {
|
||||
touchmove (e) {
|
||||
console.log(e)
|
||||
},
|
||||
getServerData () {
|
||||
//模拟从服务器获取数据时的延时
|
||||
setTimeout(() => {
|
||||
this.testDataA = [80, 60, 95, 50, 95]
|
||||
this.testDataB = [95, 50, 50, 95, 50]
|
||||
this.testDataC = [50, 60, 40, 50, 60]
|
||||
this.testCategories = ["0", "90", "180", "270", "360"]
|
||||
for (let index = 0; index < 9; index++) {
|
||||
this.testDataA.push(...this.testDataA)
|
||||
this.testDataB.push(...this.testDataB)
|
||||
this.testDataC.push(...this.testDataC)
|
||||
this.testCategories.push(...this.testCategories)
|
||||
}
|
||||
//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
|
||||
let res = {
|
||||
categories: this.testCategories,
|
||||
series: [
|
||||
{
|
||||
name: "成交量A",
|
||||
data: this.testDataA
|
||||
},
|
||||
// {
|
||||
// name: "成交量B",
|
||||
// data: this.testDataB
|
||||
// },
|
||||
// {
|
||||
// name: "成交量C",
|
||||
// data: this.testDataC
|
||||
// }
|
||||
]
|
||||
};
|
||||
this.chartData = JSON.parse(JSON.stringify(res));
|
||||
}, 500);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
|
||||
.charts-box {
|
||||
margin-top: 20rpx;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
<template>
|
||||
<view>
|
||||
<uni-data-checkbox multiple v-model="checkbox" :localdata="hobby"></uni-data-checkbox>
|
||||
<view class="charts-box">
|
||||
<qiun-data-charts ontouch onzoom type="line" :opts="opts" :chartData="chartData" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
checkbox: [0, 1, 2],
|
||||
hobby: [{
|
||||
text: '电网电压1',
|
||||
value: 0
|
||||
}, {
|
||||
text: '电网电压2',
|
||||
value: 1
|
||||
}, {
|
||||
text: '电网电压3',
|
||||
value: 2
|
||||
}, {
|
||||
text: '电网电压3',
|
||||
value: 4
|
||||
}],
|
||||
chartData: {},
|
||||
//您可以通过修改 config-ucharts.js 文件中下标为 ['line'] 的节点来配置全局默认参数,如都是默认参数,此处可以不传 opts 。实际应用过程中 opts 只需传入与全局默认参数中不一致的【某一个属性】即可实现同类型的图表显示不同的样式,达到页面简洁的需求。
|
||||
opts: {
|
||||
color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
|
||||
padding: [15, 15, 0, 0],
|
||||
dataLabel: false,
|
||||
dataPointShape: false,
|
||||
enableScroll: true,
|
||||
legend: {},
|
||||
xAxis: {
|
||||
disableGrid: true,
|
||||
itemCount: 10240,
|
||||
},
|
||||
yAxis: {
|
||||
gridType: "dash",
|
||||
dashLength: 2,
|
||||
data: [
|
||||
{
|
||||
min: -100,
|
||||
max: 100
|
||||
}
|
||||
]
|
||||
},
|
||||
// extra: {
|
||||
// line: {
|
||||
// type: "curve",
|
||||
// width: 2,
|
||||
// activeType: "hollow",
|
||||
// linearType: "custom"
|
||||
// }
|
||||
// }
|
||||
},
|
||||
testDataA: [],
|
||||
testDataB: [],
|
||||
testDataC: [],
|
||||
testCategories: []
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
this.getServerData();
|
||||
},
|
||||
methods: {
|
||||
touchmove (e) {
|
||||
console.log(e)
|
||||
},
|
||||
getServerData () {
|
||||
//模拟从服务器获取数据时的延时
|
||||
setTimeout(() => {
|
||||
this.testDataA = [80, 60, 95, 50, 95]
|
||||
this.testDataB = [95, 50, 50, 95, 50]
|
||||
this.testDataC = [50, 60, 40, 50, 60]
|
||||
this.testCategories = ["0", "90", "180", "270", "360"]
|
||||
for (let index = 0; index < 9; index++) {
|
||||
this.testDataA.push(...this.testDataA)
|
||||
this.testDataB.push(...this.testDataB)
|
||||
this.testDataC.push(...this.testDataC)
|
||||
this.testCategories.push(...this.testCategories)
|
||||
}
|
||||
//模拟服务器返回数据,如果数据格式和标准格式不同,需自行按下面的格式拼接
|
||||
let res = {
|
||||
categories: this.testCategories,
|
||||
series: [
|
||||
{
|
||||
name: "成交量A",
|
||||
data: this.testDataA
|
||||
},
|
||||
// {
|
||||
// name: "成交量B",
|
||||
// data: this.testDataB
|
||||
// },
|
||||
// {
|
||||
// name: "成交量C",
|
||||
// data: this.testDataC
|
||||
// }
|
||||
]
|
||||
};
|
||||
this.chartData = JSON.parse(JSON.stringify(res));
|
||||
}, 500);
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
|
||||
.charts-box {
|
||||
margin-top: 20rpx;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,64 +1,92 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-load-more status="loading" v-if="renderData.电网侧.length == 0 || renderData.负载侧.length == 0"></uni-load-more>
|
||||
<view class="basic" v-else>
|
||||
<view class="grid-card">
|
||||
<text>
|
||||
<view class="grid-card-title grid-card-title-with-icon"></view>电网侧
|
||||
</text>
|
||||
<view class="grid-card-content-5">
|
||||
<view class="item item-title">名称</view>
|
||||
<view class="item item-title">有功功率(kW)</view>
|
||||
<view class="item item-title">无功功率(kVar)</view>
|
||||
<view class="item item-title">视在功率(kVA)</view>
|
||||
<view class="item item-title">功率因数</view>
|
||||
<template v-for="(item, index) in renderData.电网侧">
|
||||
<view class="item">{{ item.phase }}</view>
|
||||
<view class="item">{{ item['Apf_P_Sys(W)'] == '-' ? '-' : (item['Apf_P_Sys(W)'] /
|
||||
1000).toFixed(2) }}
|
||||
<uni-load-more status="loading" v-if="!isDataReady"></uni-load-more>
|
||||
<view class="basic mt10" v-else>
|
||||
<view class="params-wrap" v-for="(section, ind) in sections" :key="section.title">
|
||||
<view class="section-title-row">
|
||||
<view class="section-title">
|
||||
<view class="grid-card-title-with-icon"></view>
|
||||
<text>{{ section.title }}</text>
|
||||
</view>
|
||||
<view class="legend-row" v-if="ind == 0">
|
||||
<view class="legend-item" v-for="phase in phaseColors" :key="phase.name">
|
||||
<view class="legend-dot" :style="{ background: phase.color }" />
|
||||
<text class="legend-text">{{ phase.name }}</text>
|
||||
</view>
|
||||
<view class="item">{{ item['Apf_Q_Sys(Var)'] == '-' ? '-' : (item['Apf_Q_Sys(Var)'] /
|
||||
1000).toFixed(2) }}
|
||||
</view>
|
||||
<view class="item">{{ item['Apf_S_Sys(VA)'] == '-' ? '-' : (item['Apf_S_Sys(VA)'] /
|
||||
1000).toFixed(2) }}
|
||||
</view>
|
||||
<view class="item">{{ item['Apf_PF_Sys(null)'] || '-' }}</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="grid-card">
|
||||
<text>
|
||||
<view class="grid-card-title grid-card-title-with-icon"></view>负载侧
|
||||
</text>
|
||||
<view class="grid-card-content-5">
|
||||
<view class="item item-title">名称</view>
|
||||
<view class="item item-title">有功功率(kW)</view>
|
||||
<view class="item item-title">无功功率(kVar)</view>
|
||||
<view class="item item-title">视在功率(kVA)</view>
|
||||
<view class="item item-title">功率因数</view>
|
||||
<template v-for="(item, index) in renderData.负载侧">
|
||||
<view class="item">{{ item.phase }}</view>
|
||||
<view class="item">{{ item['Apf_P_Load(W)'] == '-' ? '-' : (item['Apf_P_Load(W)'] /
|
||||
1000).toFixed(2) }}
|
||||
<view class="params-section">
|
||||
<view v-for="(rowItems, rowIdx) in chunkedChildren(getSectionCards(section))" :key="rowIdx"
|
||||
class="double-row">
|
||||
<view v-for="(child, childIdx) in rowItems" :key="childIdx" class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ child.name }}</text>
|
||||
</view>
|
||||
<view class="phase-vertical">
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[0].color }">{{
|
||||
child.A
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[1].color }">{{
|
||||
child.B
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[2].color }">{{
|
||||
child.C
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item">{{
|
||||
item['Apf_Q_Load(Var)'] == '-' ? '-' : (item['Apf_Q_Load(Var)'] / 1000).toFixed(2)
|
||||
}}</view>
|
||||
<view class="item">{{ item['Apf_S_Load(VA)'] == '-' ? '-' : (item['Apf_S_Load(VA)'] /
|
||||
1000).toFixed(2) }}
|
||||
</view>
|
||||
<view class="item">{{ item['Apf_PF_Load(null)'] || '-' }}</view>
|
||||
</template>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const SECTIONS = [
|
||||
{
|
||||
title: '电网侧',
|
||||
dataKey: '电网侧',
|
||||
metrics: [
|
||||
{ label: '有功功率(kW)', field: 'Apf_P_Sys(W)', divide: 1000 },
|
||||
{ label: '无功功率(kVar)', field: 'Apf_Q_Sys(Var)', divide: 1000 },
|
||||
{ label: '视在功率(kVA)', field: 'Apf_S_Sys(VA)', divide: 1000 },
|
||||
{ label: '功率因数', field: 'Apf_PF_Sys(null)' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '负载侧',
|
||||
dataKey: '负载侧',
|
||||
metrics: [
|
||||
{ label: '有功功率(kW)', field: 'Apf_P_Load(W)', divide: 1000 },
|
||||
{ label: '无功功率(kVar)', field: 'Apf_Q_Load(Var)', divide: 1000 },
|
||||
{ label: '视在功率(kVA)', field: 'Apf_S_Load(VA)', divide: 1000 },
|
||||
{ label: '功率因数', field: 'Apf_PF_Load(null)' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export default {
|
||||
props: {
|
||||
basicData: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
sections: SECTIONS,
|
||||
phaseColors: [
|
||||
{ name: 'A相', color: '#DAA520' },
|
||||
{ name: 'B相', color: '#2E8B57' },
|
||||
{ name: 'C相', color: '#D54941' },
|
||||
],
|
||||
renderData: {
|
||||
电网侧: [],
|
||||
负载侧: [],
|
||||
@@ -66,92 +94,210 @@ export default {
|
||||
},
|
||||
}
|
||||
},
|
||||
props: {
|
||||
basicData: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return []
|
||||
},
|
||||
computed: {
|
||||
isDataReady() {
|
||||
return this.renderData.电网侧.length > 0 && this.renderData.负载侧.length > 0
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
basicData: {
|
||||
handler: function (newVal, oldVal) {
|
||||
newVal.forEach((item) => {
|
||||
if (item.phase === 'avg') {
|
||||
return
|
||||
}
|
||||
let key = ''
|
||||
switch (item.statisticalName) {
|
||||
case 'Apf_P_Sys(W)':
|
||||
key = '电网侧'
|
||||
break
|
||||
case 'Apf_Q_Sys(Var)':
|
||||
key = '电网侧'
|
||||
break
|
||||
case 'Apf_S_Sys(VA)':
|
||||
key = '电网侧'
|
||||
break
|
||||
case 'Apf_PF_Sys(null)':
|
||||
key = '电网侧'
|
||||
break
|
||||
case 'Apf_P_Load(W)':
|
||||
key = '负载侧'
|
||||
break
|
||||
case 'Apf_Q_Load(Var)':
|
||||
key = '负载侧'
|
||||
break
|
||||
case 'Apf_S_Load(VA)':
|
||||
key = '负载侧'
|
||||
break
|
||||
case 'Apf_PF_Load(null)':
|
||||
key = '负载侧'
|
||||
break
|
||||
default:
|
||||
key = '未知'
|
||||
break
|
||||
}
|
||||
|
||||
let index = this.renderData[key].findIndex((item2) => {
|
||||
return item2.phase === item.phase
|
||||
handler(newVal) {
|
||||
this.renderData = {
|
||||
电网侧: [],
|
||||
负载侧: [],
|
||||
未知: [],
|
||||
}
|
||||
; (newVal || []).forEach((item) => {
|
||||
if (item.phase === 'avg') {
|
||||
return
|
||||
}
|
||||
const key = this.getDataKey(item.statisticalName)
|
||||
const index = this.renderData[key].findIndex((item2) => item2.phase === item.phase)
|
||||
if (index > -1) {
|
||||
this.renderData[key][index][item.statisticalName] = this.normalizeStatisticalData(
|
||||
item.statisticalData,
|
||||
)
|
||||
} else {
|
||||
this.renderData[key].push({
|
||||
phase: item.phase,
|
||||
[item.statisticalName]: this.normalizeStatisticalData(item.statisticalData),
|
||||
})
|
||||
}
|
||||
})
|
||||
if (index > -1) {
|
||||
this.renderData[key][index][item.statisticalName] = item.statisticalData || '-'
|
||||
} else {
|
||||
this.renderData[key].push({
|
||||
phase: item.phase,
|
||||
[item.statisticalName]: item.statisticalData || '-',
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log(this.renderData)
|
||||
},
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
getDataKey(statisticalName) {
|
||||
switch (statisticalName) {
|
||||
case 'Apf_P_Sys(W)':
|
||||
case 'Apf_Q_Sys(Var)':
|
||||
case 'Apf_S_Sys(VA)':
|
||||
case 'Apf_PF_Sys(null)':
|
||||
return '电网侧'
|
||||
case 'Apf_P_Load(W)':
|
||||
case 'Apf_Q_Load(Var)':
|
||||
case 'Apf_S_Load(VA)':
|
||||
case 'Apf_PF_Load(null)':
|
||||
return '负载侧'
|
||||
default:
|
||||
return '未知'
|
||||
}
|
||||
},
|
||||
getSectionCards(section) {
|
||||
const list = this.renderData[section.dataKey] || []
|
||||
return section.metrics.map((metric) => ({
|
||||
name: metric.label,
|
||||
A: this.getPhaseValue(list, metric, 'A'),
|
||||
B: this.getPhaseValue(list, metric, 'B'),
|
||||
C: this.getPhaseValue(list, metric, 'C'),
|
||||
}))
|
||||
},
|
||||
getPhaseValue(list, metric, phase = 'A') {
|
||||
const item = list.find((row) => String(row.phase || '').toUpperCase() === phase)
|
||||
return item ? this.formatValue(item[metric.field], metric.divide) : '-'
|
||||
},
|
||||
normalizeStatisticalData(value) {
|
||||
if (value == 3.1415926 || value === null || value === '') {
|
||||
return '-'
|
||||
}
|
||||
return value
|
||||
},
|
||||
formatValue(value, divide) {
|
||||
if (value == 3.1415926 || value === null || value === '' || value === '-') {
|
||||
return '-'
|
||||
}
|
||||
const num = Number(value)
|
||||
if (Number.isNaN(num)) return value
|
||||
if (divide) {
|
||||
// return (num / divide).toFixed(2)
|
||||
return num != 0 ? (num / divide).toFixed(2) : num.toFixed(2)
|
||||
}
|
||||
return num.toFixed(2)
|
||||
},
|
||||
chunkedChildren(children) {
|
||||
const result = []
|
||||
for (let i = 0; i < children.length; i += 2) {
|
||||
result.push(children.slice(i, i + 2))
|
||||
}
|
||||
return result
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.basic {
|
||||
.params-wrap {
|
||||
margin-bottom: 20rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 10rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.section-title-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: 12rpx;
|
||||
padding: 20rpx 20rpx 0;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.grid-card-title-with-icon {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
margin-right: 12rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
.legend-row {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.legend-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.params-section {
|
||||
padding: 16rpx 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.double-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.param-group {
|
||||
min-width: 0;
|
||||
background: #f3f3f3;
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 8rpx 12rpx;
|
||||
}
|
||||
|
||||
.param-title {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 8rpx;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
.phase-vertical {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.phase-item-vertical {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rpx;
|
||||
}
|
||||
|
||||
.phase-value-vertical {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.phase-divider {
|
||||
width: 1px;
|
||||
background: #d2d2d2;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,24 +1,14 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-load-more status="loading" v-if="basicData.length == 0"></uni-load-more>
|
||||
<view >
|
||||
<uni-load-more status="loading" v-if="loading"></uni-load-more>
|
||||
|
||||
<view v-else>
|
||||
<view v-else class="xieBo">
|
||||
<div class="header-form">
|
||||
<uni-data-select
|
||||
v-model="parity"
|
||||
:localdata="parityOption"
|
||||
@change="initEcharts"
|
||||
style="flex: 1"
|
||||
:clear="false"
|
||||
></uni-data-select>
|
||||
<uni-data-select v-model="parity" :localdata="parityOption" @change="initEcharts" style="flex: 1"
|
||||
:clear="false"></uni-data-select>
|
||||
<!-- <uni-data-checkbox v-model="dataRadio" :localdata="dataOptions" @change="initEcharts"></uni-data-checkbox> -->
|
||||
<uni-data-select
|
||||
v-model="dataRadio"
|
||||
:localdata="dataOptions"
|
||||
@change="initEcharts"
|
||||
style="flex: 2; margin-left: 20rpx"
|
||||
:clear="false"
|
||||
></uni-data-select>
|
||||
<uni-data-select v-model="dataRadio" :localdata="dataOptions" @change="initEcharts"
|
||||
style="flex: 2; margin-left: 20rpx" :clear="false"></uni-data-select>
|
||||
</div>
|
||||
<view class="charts-box">
|
||||
<!-- <view class="data-time">{{ time }}</view> -->
|
||||
@@ -54,6 +44,7 @@ export default {
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
loading: true,
|
||||
parity: 2,
|
||||
time: '',
|
||||
dataOptions: [],
|
||||
@@ -216,7 +207,6 @@ export default {
|
||||
watch: {
|
||||
basicData: {
|
||||
handler(newVal, oldVal) {
|
||||
console.log(this.basicData)
|
||||
let basicData = JSON.parse(JSON.stringify(this.basicData))
|
||||
// this.dataRadio = 0
|
||||
this.renderData = {
|
||||
@@ -284,9 +274,9 @@ export default {
|
||||
})
|
||||
})
|
||||
this.dataOptions = dataOptions
|
||||
console.log(dataOptions)
|
||||
|
||||
this.initEcharts()
|
||||
|
||||
this.loading = false
|
||||
this.time = this.$util.parseTime(this.dataTime - 8 * 60 * 60)
|
||||
},
|
||||
deep: true,
|
||||
@@ -365,13 +355,29 @@ export default {
|
||||
}, 100)
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.loading = true
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
}, 5000)
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.xieBo {
|
||||
margin-top: 10rpx;
|
||||
background-color: #fff;
|
||||
padding: 20rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.charts-box {
|
||||
margin-top: 20rpx;
|
||||
height: 100vh;
|
||||
|
||||
.data-time {
|
||||
position: absolute;
|
||||
right: 20rpx;
|
||||
@@ -379,6 +385,7 @@ export default {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.header-form {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
<template v-for="(item, index) in IOData">
|
||||
<view class="item">{{ item.clDid }}</view>
|
||||
<view class="item" style="font-weight: 700">
|
||||
{{ Math.floor(item.value) || '-' }}
|
||||
<view v-if="item.value"> °C</view>
|
||||
{{ Math.floor(item.value) }}
|
||||
<view> °C</view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-for="(item, index) in 3 - (IOData.length % 3)">
|
||||
@@ -170,7 +170,7 @@ export default {
|
||||
// },
|
||||
{
|
||||
iconPath: '/static/about.png',
|
||||
text: '关于',
|
||||
text: '详情',
|
||||
},
|
||||
// {
|
||||
// iconPath: '/static/access.png',
|
||||
@@ -235,7 +235,7 @@ export default {
|
||||
uni.switchTab({
|
||||
url: '/pages/index/message1',
|
||||
})
|
||||
} else if (e.text === '关于') {
|
||||
} else if (e.text === '详情') {
|
||||
uni.navigateTo({ url: '/pages/device/APF/about?id=' + this.devId })
|
||||
} else if (e.text === '移交') {
|
||||
uni.navigateTo({ url: '/pages/device/transfer?id=' + this.devId })
|
||||
@@ -673,8 +673,9 @@ export default {
|
||||
|
||||
.header {
|
||||
position: relative;
|
||||
width: 375px;
|
||||
margin: 0 auto;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
|
||||
image {
|
||||
@@ -691,7 +692,7 @@ export default {
|
||||
z-index: 2;
|
||||
text-align: center;
|
||||
color: #111;
|
||||
width: 150rpx;
|
||||
width: 180rpx;
|
||||
font-size: 16rpx;
|
||||
opacity: 0.8;
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ export default {
|
||||
// },
|
||||
{
|
||||
iconPath: '/static/about.png',
|
||||
text: '关于',
|
||||
text: '详情',
|
||||
},
|
||||
// {
|
||||
// iconPath: '/static/access.png',
|
||||
@@ -130,7 +130,7 @@ export default {
|
||||
uni.navigateTo({ url: '/pages/device/DVR/record' })
|
||||
} else if (e.text === '事件') {
|
||||
uni.navigateTo({ url: '/pages/device/DVR/report' })
|
||||
} else if (e.text === '关于') {
|
||||
} else if (e.text === '详情') {
|
||||
uni.navigateTo({ url: '/pages/device/DVR/about' })
|
||||
} else if (e.text === '移交') {
|
||||
uni.navigateTo({ url: '/pages/device/transfer' })
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
@change="positionChange" :clear="false" disabled></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="别名">
|
||||
<uni-easyinput :clearable="false" type="text" v-model="point.alias"
|
||||
<uni-easyinput :clearable="false" maxlength="24" type="text" v-model="point.alias"
|
||||
@change="aliasChange" placeholder="别名(非必填)" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="绑定指标">
|
||||
|
||||
@@ -492,6 +492,6 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
@change="positionChange" disabled :clear="false"></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="别名">
|
||||
<uni-easyinput :clearable="false" type="text" v-model="point.alias"
|
||||
<uni-easyinput :clearable="false" maxlength="24" type="text" v-model="point.alias"
|
||||
@change="aliasChange" placeholder="别名(非必填)" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="绑定指标">
|
||||
@@ -369,7 +369,7 @@ export default {
|
||||
},
|
||||
changeAuth() {
|
||||
uni.scanCode({
|
||||
onlyFromCamera: true,
|
||||
onlyFromCamera: false,
|
||||
success: (res) => {
|
||||
console.log('条码类型:' + res.scanType)
|
||||
console.log('条码内容:' + res.result)
|
||||
@@ -664,4 +664,19 @@ export default {
|
||||
left: -9999px;
|
||||
width: 375px;
|
||||
}
|
||||
</style>
|
||||
|
||||
/deep/ .uni-select__input-text {
|
||||
width: 170px !important;
|
||||
}
|
||||
|
||||
/deep/ .uni-select__selector-item {
|
||||
uni-text {
|
||||
white-space: nowrap !important;
|
||||
/* 强制不换行 */
|
||||
overflow: hidden !important;
|
||||
/* 溢出内容隐藏 */
|
||||
text-overflow: ellipsis !important;
|
||||
/* 溢出部分显示省略号 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -21,7 +21,10 @@
|
||||
所属工程:<view>{{ device.engineeringName }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
所属项目:<view>{{ device.equipmentName }}</view>
|
||||
所属项目:<view>{{ device.projectName }}</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
所属设备:<view>{{ device.equipmentName }}</view>
|
||||
</view>
|
||||
|
||||
<view class="info-item status">
|
||||
@@ -42,7 +45,7 @@
|
||||
{{ disabled ? `刷新(${countdown}s)` : '刷新' }}
|
||||
</button>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 仪表盘 -->
|
||||
<view>
|
||||
<view class="chartBox">
|
||||
@@ -87,9 +90,14 @@
|
||||
</view>
|
||||
|
||||
<!-- 底部指标数据 -->
|
||||
<view class="params-wrap">
|
||||
|
||||
<view class="params-section">
|
||||
<view class="params-wrap ">
|
||||
<view class="legend-row mt10">
|
||||
<view class="legend-item" v-for="phase in phaseColors" :key="phase.name">
|
||||
<view class="legend-dot" :style="{ background: phase.color }" />
|
||||
<text class="legend-text">{{ phase.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="params-section mb40">
|
||||
<view v-for="(rowItems, rowIdx) in chunkedChildren(realTimeData)" :key="rowIdx"
|
||||
class="double-row">
|
||||
<view v-for="(child, childIdx) in rowItems" :key="childIdx" class="param-group">
|
||||
@@ -135,7 +143,11 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
|
||||
phaseColors: [
|
||||
{ name: 'A相', color: '#DAA520' },
|
||||
{ name: 'B相', color: '#2E8B57' },
|
||||
{ name: 'C相', color: '#D54941' },
|
||||
],
|
||||
deviceInfo: {},
|
||||
// 使用上面定义的图表配置项
|
||||
option: {},
|
||||
@@ -145,7 +157,7 @@ export default {
|
||||
echartsDataV2: {},
|
||||
echartsDataV3: {},
|
||||
echartsDataA1: {},
|
||||
echartsDataA2: {},
|
||||
echartsDataA2: {},
|
||||
echartsDataA3: {},
|
||||
// 图表实例,用于后续操作
|
||||
echart0: null,
|
||||
@@ -173,8 +185,8 @@ export default {
|
||||
{ name: '电压总谐波畸变率(%)', A: '-', B: '-', C: '-' },
|
||||
],
|
||||
phaseColors: [
|
||||
{ name: 'A相', color: '#F1B22E' },
|
||||
{ name: 'B相', color: '#2BA471' },
|
||||
{ name: 'A相', color: '#DAA520' },
|
||||
{ name: 'B相', color: '#2E8B57' },
|
||||
{ name: 'C相', color: '#D54941' },
|
||||
],
|
||||
disabled: false,
|
||||
@@ -190,7 +202,7 @@ export default {
|
||||
},
|
||||
{
|
||||
iconPath: '/static/about.png',
|
||||
text: '关于',
|
||||
text: '详情',
|
||||
},
|
||||
],
|
||||
device: {},
|
||||
@@ -969,7 +981,7 @@ export default {
|
||||
url: '/pages/index/message1',
|
||||
})
|
||||
// uni.navigateTo({ url: '/pages/device/APF/report?id=' + this.device.equipmentId })
|
||||
} else if (e.text === '关于') {
|
||||
} else if (e.text === '详情') {
|
||||
uni.navigateTo({ url: '/pages/device/APF/about?id=' + this.device.equipmentId })
|
||||
} else if (e.text === '移交') {
|
||||
uni.navigateTo({ url: '/pages/device/transfer?id=' + this.device.equipmentId })
|
||||
@@ -1114,7 +1126,7 @@ export default {
|
||||
}
|
||||
|
||||
.phase-value-vertical {
|
||||
font-size: 28rpx;
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@@ -1191,4 +1203,29 @@ export default {
|
||||
height: 45rpx;
|
||||
line-height: 45rpx;
|
||||
}
|
||||
|
||||
.legend-row {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
padding: 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.legend-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,157 +1,142 @@
|
||||
<template>
|
||||
<view>
|
||||
<Cn-page :loading="loading" beforeRender>
|
||||
<view slot="body">
|
||||
<view class="transfer">
|
||||
<!-- <div class="transfer-img" ref="qrCodeUrl" /> -->
|
||||
<!-- <uqrcode ref="uqrcode" canvas-id="qrcode" :value="content" :options="{ margin: 10 }"></uqrcode> -->
|
||||
<uqrcode
|
||||
ref="uqrcode"
|
||||
canvas-id="qrcode"
|
||||
:value="content"
|
||||
size="200"
|
||||
@complete="complete"
|
||||
:loading="false"
|
||||
></uqrcode>
|
||||
<view style="height: 200rpx"></view>
|
||||
<view class="transfer-text">请让接收人员扫码接收</view>
|
||||
<view class="transfer-btn">
|
||||
<button class="transfer-btn-item" style="background-color: #fff; color: #111" @click="back">
|
||||
返回
|
||||
</button>
|
||||
<button class="transfer-btn-item ml20" @click="scan">扫一扫</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
<uni-popup ref="alertDialog" type="dialog">
|
||||
<uni-popup-dialog
|
||||
style="width: 90%; margin: 5%"
|
||||
type="info"
|
||||
cancelText="禁止"
|
||||
confirmText="允许"
|
||||
title="权限说明"
|
||||
content='是否允许"灿能物联"使用相机?'
|
||||
@confirm="handleScon('camera')"
|
||||
@close="dialogClose"
|
||||
></uni-popup-dialog>
|
||||
</uni-popup>
|
||||
<uni-popup ref="message" type="message">
|
||||
<uni-popup-message type="info" :duration="0" style="width: 90%; margin: 5%">
|
||||
<view style="color: #909399; font-style: 16px">相机权限使用说明:</view>
|
||||
<view style="color: #6c6c6c; margin-top: 3rpx; "> 用于相机扫描二维码!</view>
|
||||
</uni-popup-message>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// import QRCode from 'qrcodejs2'
|
||||
// import UQRCode from '@/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js';
|
||||
|
||||
import { transferDevice } from '@/common/api/device'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
content: '',
|
||||
options: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
complete() {
|
||||
this.loading = false
|
||||
},
|
||||
back() {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
},
|
||||
home() {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
},
|
||||
transferDevice(userId) {
|
||||
transferDevice(this.options.id, userId).then((res) => {
|
||||
uni.showToast({
|
||||
title: '移交成功',
|
||||
icon: 'none',
|
||||
})
|
||||
uni.navigateBack()
|
||||
})
|
||||
},
|
||||
scan() {
|
||||
if (
|
||||
plus.os.name == 'Android' &&
|
||||
plus.navigator.checkPermission('android.permission.CAMERA') === 'undetermined'
|
||||
) {
|
||||
//未授权
|
||||
this.$refs.message.open()
|
||||
this.$refs.alertDialog.open('bottom')
|
||||
} else {
|
||||
this.handleScon()
|
||||
}
|
||||
},
|
||||
handleScon() {
|
||||
this.$refs.message.close()
|
||||
uni.scanCode({
|
||||
onlyFromCamera:true,
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
let data = JSON.parse(res.result)
|
||||
if (data.type === 'userId') {
|
||||
this.transferDevice(data.id)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '请扫描正确的二维码',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
dialogClose() {this.$refs.message.close()},
|
||||
},
|
||||
onLoad(options) {
|
||||
this.options = options
|
||||
this.content = JSON.stringify({
|
||||
type: 'transferDevice',
|
||||
id: options.id,
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.transfer {
|
||||
padding: 200rpx 34rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.transfer-img {
|
||||
}
|
||||
|
||||
.transfer-text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.transfer-btn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 100rpx;
|
||||
width: 100%;
|
||||
|
||||
.transfer-btn-item {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: $uni-theme-color;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view>
|
||||
<Cn-page :loading="loading" beforeRender>
|
||||
<view slot="body">
|
||||
<view class="transfer">
|
||||
<!-- <div class="transfer-img" ref="qrCodeUrl" /> -->
|
||||
<!-- <uqrcode ref="uqrcode" canvas-id="qrcode" :value="content" :options="{ margin: 10 }"></uqrcode> -->
|
||||
<uqrcode ref="uqrcode" canvas-id="qrcode" :value="content" size="200" @complete="complete"
|
||||
:loading="false"></uqrcode>
|
||||
<view style="height: 200rpx"></view>
|
||||
<view class="transfer-text">请让接收人员扫码接收</view>
|
||||
<view class="transfer-btn">
|
||||
<button class="transfer-btn-item" style="background-color: #fff; color: #111" @click="back">
|
||||
返回
|
||||
</button>
|
||||
<button class="transfer-btn-item ml20" @click="scan">扫一扫</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
<uni-popup ref="alertDialog" type="dialog">
|
||||
<uni-popup-dialog style="width: 90%; margin: 5%" type="info" cancelText="禁止" confirmText="允许" title="权限说明"
|
||||
content='是否允许"灿能物联"使用相机?' @confirm="handleScon('camera')" @close="dialogClose"></uni-popup-dialog>
|
||||
</uni-popup>
|
||||
<uni-popup ref="message" type="message">
|
||||
<uni-popup-message type="info" :duration="0" style="width: 90%; margin: 5%">
|
||||
<view style="color: #909399; font-style: 16px">相机权限使用说明:</view>
|
||||
<view style="color: #6c6c6c; margin-top: 3rpx; "> 用于相机扫描二维码!</view>
|
||||
</uni-popup-message>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// import QRCode from 'qrcodejs2'
|
||||
// import UQRCode from '@/uni_modules/Sansnn-uQRCode/js_sdk/uqrcode/uqrcode.js';
|
||||
|
||||
import { transferDevice } from '@/common/api/device'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
content: '',
|
||||
options: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
complete() {
|
||||
this.loading = false
|
||||
},
|
||||
back() {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
},
|
||||
home() {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
},
|
||||
transferDevice(userId) {
|
||||
transferDevice(this.options.id, userId).then((res) => {
|
||||
uni.showToast({
|
||||
title: '移交成功',
|
||||
icon: 'none',
|
||||
})
|
||||
uni.navigateBack()
|
||||
})
|
||||
},
|
||||
scan() {
|
||||
if (
|
||||
plus.os.name == 'Android' &&
|
||||
plus.navigator.checkPermission('android.permission.CAMERA') === 'undetermined'
|
||||
) {
|
||||
//未授权
|
||||
this.$refs.message.open()
|
||||
this.$refs.alertDialog.open('bottom')
|
||||
} else {
|
||||
this.handleScon()
|
||||
}
|
||||
},
|
||||
handleScon() {
|
||||
this.$refs.message.close()
|
||||
uni.scanCode({
|
||||
// onlyFromCamera:false,
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
let data = JSON.parse(res.result)
|
||||
if (data.type === 'userId') {
|
||||
this.transferDevice(data.id)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '请扫描正确的二维码',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
dialogClose() { this.$refs.message.close() },
|
||||
},
|
||||
onLoad(options) {
|
||||
this.options = options
|
||||
this.content = JSON.stringify({
|
||||
type: 'transferDevice',
|
||||
id: options.id,
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.transfer {
|
||||
padding: 200rpx 34rpx 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.transfer-img {}
|
||||
|
||||
.transfer-text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
|
||||
.transfer-btn {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 100rpx;
|
||||
width: 100%;
|
||||
|
||||
.transfer-btn-item {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
background-color: $uni-theme-color;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,35 +10,32 @@
|
||||
<view class="message">
|
||||
|
||||
|
||||
<uni-swipe-action>
|
||||
<uni-swipe-action-item v-for="(item, index) in store.data"
|
||||
:style="{ marginTop: index === 0 ? '0' : '' }" :key="index" :threshold="0"
|
||||
:right-options="item.isTop == 0 ? options1 : options12" @click="bindClick($event, item)">
|
||||
<!-- extra="🔍" -->
|
||||
<uni-card class="boxClick" :title="item.name" @click="jump(item)">
|
||||
<view class="term-list-bottom">
|
||||
<view class="term-list-bottom-item">
|
||||
<view>区域</view>
|
||||
<view>{{ item.provinceName + item.cityName }}</view>
|
||||
</view>
|
||||
<view class="term-list-bottom-item">
|
||||
<view>创建时间</view>
|
||||
<view>{{ item.createTime }}</view>
|
||||
</view>
|
||||
|
||||
<view v-for="(item, index) in store.data" :key="index" style="margin: 0px 7px 7px;">
|
||||
<!-- extra="🔍" -->
|
||||
<uni-card class="boxClick" :title="item.name" @click="jump(item)">
|
||||
<view class="term-list-bottom">
|
||||
<view class="term-list-bottom-item">
|
||||
<view>区域</view>
|
||||
<view>{{ item.provinceName + item.cityName }}</view>
|
||||
</view>
|
||||
<view class="pinToTop" v-if="item.isTop == 1"> 置顶 </view>
|
||||
</uni-card>
|
||||
</uni-swipe-action-item>
|
||||
</uni-swipe-action>
|
||||
<view class="term-list-bottom-item">
|
||||
<view>创建时间</view>
|
||||
<view>{{ item.createTime }}</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
</uni-card>
|
||||
</view>
|
||||
|
||||
|
||||
|
||||
|
||||
<Cn-empty v-if="store.empty" style="padding-top: 400rpx"></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-if="store.empty" style="padding-top: 400rpx"></Cn-empty>
|
||||
<uni-load-more v-if="store.status == 'loading' || (store.data && store.data.length > 0)"
|
||||
:status="store.status"></uni-load-more>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,182 +1,182 @@
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view slot="body">
|
||||
<view class="new">
|
||||
<view class="content">
|
||||
<page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>
|
||||
<uni-forms :label-width="80">
|
||||
<uni-forms-item label="工程名称">
|
||||
<uni-easyinput type="text" v-model="formData.name" placeholder="请输入工程名称"/>
|
||||
</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-data-picker :localdata="localdata" @change="areaChange" v-model="value"
|
||||
@popupopened="show=true" @popupclosed="show=false">
|
||||
</uni-data-picker>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="描述">
|
||||
<uni-easyinput
|
||||
type="textarea"
|
||||
autoHeight
|
||||
maxlength="999"
|
||||
v-model="formData.description"
|
||||
placeholder="请输入工程描述"
|
||||
/>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="submit"> 提交</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
import {addEngineering, auditEngineering} from '../../common/api/engineering'
|
||||
import area from '../../common/js/area.json'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
localdata: area,
|
||||
loading: false,
|
||||
value: '',
|
||||
formData: {
|
||||
city: '',
|
||||
description: '',
|
||||
name: '',
|
||||
province: '',
|
||||
},
|
||||
engineering: {},
|
||||
show: false,
|
||||
options: {}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.options = options
|
||||
if (options.engineering) {
|
||||
this.engineering = JSON.parse(decodeURIComponent(options.engineering))
|
||||
console.log(this.engineering)
|
||||
for (let key in this.formData) {
|
||||
if (this.engineering[key]) {
|
||||
this.formData[key] = this.engineering[key]
|
||||
}
|
||||
}
|
||||
this.value = this.engineering.city
|
||||
this.formData.id = this.engineering.id
|
||||
uni.setNavigationBarTitle({title: '工程编辑'})
|
||||
}
|
||||
if (options.from === 'index') {
|
||||
this.$util.toast('请先创建一个工程')
|
||||
}
|
||||
// console.log(area);
|
||||
console.log(this.$util.prePage())
|
||||
},
|
||||
methods: {
|
||||
toJSON() {
|
||||
},
|
||||
areaChange(e) {
|
||||
if (e.detail.value.length) {
|
||||
this.formData.province = e.detail.value[0].value
|
||||
this.formData.city = e.detail.value[1].value
|
||||
} else {
|
||||
this.formData.province = ''
|
||||
this.formData.city = ''
|
||||
}
|
||||
},
|
||||
select(e) {
|
||||
console.log(e)
|
||||
},
|
||||
// chooseLocation() {
|
||||
// uni.chooseLocation({
|
||||
// success: function (res) {
|
||||
// this.address = res.name
|
||||
// console.log('位置名称:' + res.name)
|
||||
// console.log('详细地址:' + res.address)
|
||||
// console.log('纬度:' + res.latitude)
|
||||
// console.log('经度:' + res.longitude)
|
||||
// },
|
||||
// })
|
||||
// },
|
||||
async submit() {
|
||||
console.log(this.formData)
|
||||
if (!this.formData.name) {
|
||||
this.$util.toast('请输入工程名称')
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.formData.province) {
|
||||
this.$util.toast('请选择区域信息')
|
||||
return
|
||||
}
|
||||
if (!this.formData.description) {
|
||||
this.$util.toast('请输入工程描述')
|
||||
return
|
||||
}
|
||||
if (this.formData.id) {
|
||||
await auditEngineering(this.formData)
|
||||
this.$util.toast('工程修改成功')
|
||||
this.$util.refreshPrePage(2)
|
||||
} else {
|
||||
let res = await addEngineering(this.formData)
|
||||
this.$util.toast('工程创建成功')
|
||||
if (this.options.from === 'index') {
|
||||
uni.setStorageSync('engineering', res.data)
|
||||
uni.redirectTo({
|
||||
url: '/pages/device/new?type=' + this.options.type,
|
||||
})
|
||||
return
|
||||
} else {
|
||||
this.$util.refreshPrePage()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.new {
|
||||
padding: 34rpx;
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view slot="body">
|
||||
<view class="new">
|
||||
<view class="content">
|
||||
<page-meta :page-style="'overflow:'+(show?'hidden':'visible')"></page-meta>
|
||||
<uni-forms :label-width="80">
|
||||
<uni-forms-item label="工程名称">
|
||||
<uni-easyinput type="text" v-model="formData.name" maxlength="50" placeholder="请输入工程名称"/>
|
||||
</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-data-picker :localdata="localdata" @change="areaChange" v-model="value"
|
||||
@popupopened="show=true" @popupclosed="show=false">
|
||||
</uni-data-picker>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="描述">
|
||||
<uni-easyinput
|
||||
type="textarea"
|
||||
autoHeight
|
||||
maxlength="999"
|
||||
v-model="formData.description"
|
||||
placeholder="请输入工程描述"
|
||||
/>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="submit"> 提交</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
import {addEngineering, auditEngineering} from '../../common/api/engineering'
|
||||
import area from '../../common/js/area.json'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
localdata: area,
|
||||
loading: false,
|
||||
value: '',
|
||||
formData: {
|
||||
city: '',
|
||||
description: '',
|
||||
name: '',
|
||||
province: '',
|
||||
},
|
||||
engineering: {},
|
||||
show: false,
|
||||
options: {}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.options = options
|
||||
if (options.engineering) {
|
||||
this.engineering = JSON.parse(decodeURIComponent(options.engineering))
|
||||
console.log(this.engineering)
|
||||
for (let key in this.formData) {
|
||||
if (this.engineering[key]) {
|
||||
this.formData[key] = this.engineering[key]
|
||||
}
|
||||
}
|
||||
this.value = this.engineering.city
|
||||
this.formData.id = this.engineering.id
|
||||
uni.setNavigationBarTitle({title: '工程编辑'})
|
||||
}
|
||||
if (options.from === 'index') {
|
||||
this.$util.toast('请先创建一个工程')
|
||||
}
|
||||
// console.log(area);
|
||||
console.log(this.$util.prePage())
|
||||
},
|
||||
methods: {
|
||||
toJSON() {
|
||||
},
|
||||
areaChange(e) {
|
||||
if (e.detail.value.length) {
|
||||
this.formData.province = e.detail.value[0].value
|
||||
this.formData.city = e.detail.value[1].value
|
||||
} else {
|
||||
this.formData.province = ''
|
||||
this.formData.city = ''
|
||||
}
|
||||
},
|
||||
select(e) {
|
||||
console.log(e)
|
||||
},
|
||||
// chooseLocation() {
|
||||
// uni.chooseLocation({
|
||||
// success: function (res) {
|
||||
// this.address = res.name
|
||||
// console.log('位置名称:' + res.name)
|
||||
// console.log('详细地址:' + res.address)
|
||||
// console.log('纬度:' + res.latitude)
|
||||
// console.log('经度:' + res.longitude)
|
||||
// },
|
||||
// })
|
||||
// },
|
||||
async submit() {
|
||||
console.log(this.formData)
|
||||
if (!this.formData.name) {
|
||||
this.$util.toast('请输入工程名称')
|
||||
return
|
||||
}
|
||||
|
||||
if (!this.formData.province) {
|
||||
this.$util.toast('请选择区域信息')
|
||||
return
|
||||
}
|
||||
if (!this.formData.description) {
|
||||
this.$util.toast('请输入工程描述')
|
||||
return
|
||||
}
|
||||
if (this.formData.id) {
|
||||
await auditEngineering(this.formData)
|
||||
this.$util.toast('工程修改成功')
|
||||
this.$util.refreshPrePage(2)
|
||||
} else {
|
||||
let res = await addEngineering(this.formData)
|
||||
this.$util.toast('工程创建成功')
|
||||
if (this.options.from === 'index') {
|
||||
uni.setStorageSync('engineering', res.data)
|
||||
uni.redirectTo({
|
||||
url: '/pages/device/new?type=' + this.options.type,
|
||||
})
|
||||
return
|
||||
} else {
|
||||
this.$util.refreshPrePage()
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.new {
|
||||
padding: 34rpx;
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -25,11 +25,8 @@
|
||||
<template v-slot:header>
|
||||
<view class="slot-box">
|
||||
<view class="slot-box-left hide-txt mr20">{{ item.engineerName }}</view>
|
||||
<switch
|
||||
:checked="selectList.indexOf(item.engineerId) > -1"
|
||||
style="transform: scale(0.8)"
|
||||
@change="switchChange(item)"
|
||||
/>
|
||||
<switch :checked="selectList.indexOf(item.engineerId) > -1" style="transform: scale(0.8)"
|
||||
@change="switchChange(item)" />
|
||||
</view>
|
||||
</template>
|
||||
</uni-list-item>
|
||||
@@ -74,8 +71,9 @@ export default {
|
||||
init() {
|
||||
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
|
||||
queryAllEnginner().then((res) => {
|
||||
this.list = res.data
|
||||
console.log(this.list)
|
||||
this.list = (res.data || []).slice().sort((a, b) =>
|
||||
(a.engineerName || '').localeCompare(b.engineerName || '', 'zh', { sensitivity: 'accent' }),
|
||||
)
|
||||
this.selectList = res.data.filter((item) => item.isSelect === '1').map((item) => item.engineerId)
|
||||
console.log(this.selectList)
|
||||
this.loading = false
|
||||
|
||||
@@ -1,219 +1,219 @@
|
||||
<template>
|
||||
<view class='new'>
|
||||
<template v-if="type == 1">
|
||||
<view class="content">
|
||||
<uni-forms>
|
||||
<uni-forms-item label="网关识别码">
|
||||
<view style="display:flex">
|
||||
<uni-easyinput type="number" v-model="code" placeholder="请输入网关识别码" />
|
||||
<!-- <uni-icons type="camera" color="#007aff" size="26" class="ml20"
|
||||
@click="scanCode"></uni-icons> -->
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="register"> 发起注册 </view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="content">
|
||||
<uni-forms>
|
||||
<uni-forms-item label="项目">
|
||||
<uni-data-select v-model="formData.project" :localdata="projectRange"></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="位置">
|
||||
<view style="display:flex;">
|
||||
<uni-easyinput :clearable="false" type="textarea" autoHeight v-model="formData.address"
|
||||
placeholder="请输入位置信息" />
|
||||
<!-- <uni-icons type="location" color="#007aff" size="26" class="ml20"
|
||||
@click="chooseLocation"></uni-icons> -->
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="拓扑图">
|
||||
<view style="display:flex;">
|
||||
<view style="flex:1">
|
||||
<image class="gplot" src="/static/test2.pic.png" mode="aspectFill" />
|
||||
</view>
|
||||
<uni-icons type="image" color="#007aff" size="26" class="ml20"
|
||||
@click="chooseGplot"></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="submit"> 提交 </view>
|
||||
</view>
|
||||
</template>
|
||||
<uni-drawer ref="gplot" mode="right" :mask-click="false">
|
||||
<scroll-view style="height: 100%;" scroll-y="true">
|
||||
<view class="content">
|
||||
<image class="gplot gplot-box" mode="aspectFill" :class="{ 'gplot-active': key == activeGplot }"
|
||||
src="/static/test2.pic.png" @click="activeGplot = key" v-for="(item, key) in 3" :key="key" />
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="closeDrawer"> 取消 </view>
|
||||
<view class="btn-wrap-item ml20" @click="closeDrawer"> 确定 </view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</uni-drawer>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
code: '',
|
||||
type: 1,
|
||||
formData: {
|
||||
address: '',
|
||||
project:""
|
||||
},
|
||||
projectRange: [
|
||||
{ value: 1, text: "监测", point: 1 },
|
||||
{ value: 2, text: "治理", point: 2 },
|
||||
{ value: 3, text: "用能", point: 1 },
|
||||
],
|
||||
activeGplot: 1,
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
chooseGplot () {
|
||||
this.$refs.gplot.open()
|
||||
},
|
||||
closeDrawer () {
|
||||
this.$refs.gplot.close()
|
||||
},
|
||||
scanCode () {
|
||||
uni.scanCode({
|
||||
success: function (res) {
|
||||
console.log('条码类型:' + res.scanType);
|
||||
console.log('条码内容:' + res.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
register () {
|
||||
this.type = 2
|
||||
},
|
||||
// chooseLocation () {
|
||||
// uni.chooseLocation({
|
||||
// success: function (res) {
|
||||
// this.address = res.name
|
||||
// console.log('位置名称:' + res.name);
|
||||
// console.log('详细地址:' + res.address);
|
||||
// console.log('纬度:' + res.latitude);
|
||||
// console.log('经度:' + res.longitude);
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
submit () {
|
||||
this.$util.toast('提交成功')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1500);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.new {
|
||||
padding: 34rpx;
|
||||
|
||||
.new-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 80rpx auto 0;
|
||||
width: 320rpx;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.gplot {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 188rpx;
|
||||
}
|
||||
|
||||
.gplot-box {
|
||||
height: 280rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.gplot-active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 8rpx solid $uni-theme-color;
|
||||
// background: rgba(3, 3, 3, .5);
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.map-pin-box {
|
||||
position: relative;
|
||||
width: 375px;
|
||||
margin: 0 auto;
|
||||
|
||||
.map-pin-box-area {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.point {
|
||||
height: 100rpx;
|
||||
width: 100rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
<template>
|
||||
<view class='new'>
|
||||
<template v-if="type == 1">
|
||||
<view class="content">
|
||||
<uni-forms>
|
||||
<uni-forms-item label="网关识别码">
|
||||
<view style="display:flex">
|
||||
<uni-easyinput type="number" v-model="code" placeholder="请输入网关识别码" />
|
||||
<!-- <uni-icons type="camera" color="#007aff" size="26" class="ml20"
|
||||
@click="scanCode"></uni-icons> -->
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="register"> 发起注册 </view>
|
||||
</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<view class="content">
|
||||
<uni-forms>
|
||||
<uni-forms-item label="项目">
|
||||
<uni-data-select v-model="formData.project" :localdata="projectRange"></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="位置">
|
||||
<view style="display:flex;">
|
||||
<uni-easyinput :clearable="false" maxlength="250" type="textarea" autoHeight v-model="formData.address"
|
||||
placeholder="请输入位置信息" />
|
||||
<!-- <uni-icons type="location" color="#007aff" size="26" class="ml20"
|
||||
@click="chooseLocation"></uni-icons> -->
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="拓扑图">
|
||||
<view style="display:flex;">
|
||||
<view style="flex:1">
|
||||
<image class="gplot" src="/static/test2.pic.png" mode="aspectFill" />
|
||||
</view>
|
||||
<uni-icons type="image" color="#007aff" size="26" class="ml20"
|
||||
@click="chooseGplot"></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="submit"> 提交 </view>
|
||||
</view>
|
||||
</template>
|
||||
<uni-drawer ref="gplot" mode="right" :mask-click="false">
|
||||
<scroll-view style="height: 100%;" scroll-y="true">
|
||||
<view class="content">
|
||||
<image class="gplot gplot-box" mode="aspectFill" :class="{ 'gplot-active': key == activeGplot }"
|
||||
src="/static/test2.pic.png" @click="activeGplot = key" v-for="(item, key) in 3" :key="key" />
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="closeDrawer"> 取消 </view>
|
||||
<view class="btn-wrap-item ml20" @click="closeDrawer"> 确定 </view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</uni-drawer>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
code: '',
|
||||
type: 1,
|
||||
formData: {
|
||||
address: '',
|
||||
project:""
|
||||
},
|
||||
projectRange: [
|
||||
{ value: 1, text: "监测", point: 1 },
|
||||
{ value: 2, text: "治理", point: 2 },
|
||||
{ value: 3, text: "用能", point: 1 },
|
||||
],
|
||||
activeGplot: 1,
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
chooseGplot () {
|
||||
this.$refs.gplot.open()
|
||||
},
|
||||
closeDrawer () {
|
||||
this.$refs.gplot.close()
|
||||
},
|
||||
scanCode () {
|
||||
uni.scanCode({
|
||||
success: function (res) {
|
||||
console.log('条码类型:' + res.scanType);
|
||||
console.log('条码内容:' + res.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
register () {
|
||||
this.type = 2
|
||||
},
|
||||
// chooseLocation () {
|
||||
// uni.chooseLocation({
|
||||
// success: function (res) {
|
||||
// this.address = res.name
|
||||
// console.log('位置名称:' + res.name);
|
||||
// console.log('详细地址:' + res.address);
|
||||
// console.log('纬度:' + res.latitude);
|
||||
// console.log('经度:' + res.longitude);
|
||||
// }
|
||||
// });
|
||||
// },
|
||||
submit () {
|
||||
this.$util.toast('提交成功')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1500);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.new {
|
||||
padding: 34rpx;
|
||||
|
||||
.new-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 80rpx auto 0;
|
||||
width: 320rpx;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.gplot {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 188rpx;
|
||||
}
|
||||
|
||||
.gplot-box {
|
||||
height: 280rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.gplot-active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 8rpx solid $uni-theme-color;
|
||||
// background: rgba(3, 3, 3, .5);
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.map-pin-box {
|
||||
position: relative;
|
||||
width: 375px;
|
||||
margin: 0 auto;
|
||||
|
||||
.map-pin-box-area {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.point {
|
||||
height: 100rpx;
|
||||
width: 100rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
</style>
|
||||
@@ -1,403 +1,403 @@
|
||||
<template>
|
||||
<Cn-page :loading='loading'>
|
||||
<view slot='body'>
|
||||
<view class='index'>
|
||||
<view class="content" v-for="(item, index) in deviceList" :key="index">
|
||||
<uni-forms :label-width="80">
|
||||
<uni-forms-item label="型号">
|
||||
<uni-data-select v-model="item.type" :localdata="range"
|
||||
@change="typeChange(item)"></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="MAC地址">
|
||||
<uni-easyinput type="text" v-model="item.address" placeholder="请输入设备MAC地址" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="拓扑图">
|
||||
<view style="display:flex;">
|
||||
<view style="flex:1">
|
||||
<image class="gplot" src="/static/test2.pic.png" mode="aspectFill" />
|
||||
</view>
|
||||
<uni-icons type="image" color="#007aff" size="26" class="ml20"
|
||||
@click="chooseGplot(item)"></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<!-- <uni-forms-item label="监测点" v-if="item.pointList.length">
|
||||
<view class="point-item" v-for="(item2, index2) in item.pointList" :key="index2"
|
||||
@click="editPoint(item, index2)">
|
||||
<view style="flex:1" v-if="item2.pointName">{{ item2.pointName }}</view>
|
||||
<view style="flex:1;color:#999" v-else>请选择监测点</view>
|
||||
<uni-icons type="compose" color="#007aff" size="26" class="ml20"></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item> -->
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="addDevice"> 添加 </view>
|
||||
<view class="btn-wrap-item ml20" @click="submit"> 提交 </view>
|
||||
</view>
|
||||
<uni-drawer ref="gplot" mode="right" :mask-click="false">
|
||||
<scroll-view style="height: 100%;" scroll-y="true">
|
||||
<view class="content">
|
||||
<image class="gplot gplot-box" mode="aspectFill" :class="{ 'gplot-active': key == activeGplot }"
|
||||
src="/static/test2.pic.png" @click="activeGplot = key" v-for="(item, key) in 3"
|
||||
:key="key" />
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="closeDrawer"> 取消 </view>
|
||||
<view class="btn-wrap-item ml20" @click="confirmGplot"> 确定 </view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</uni-drawer>
|
||||
<uni-drawer ref="point" mode="right" :mask-click="false">
|
||||
<scroll-view style="height: 100%;" scroll-y="true">
|
||||
<view style="background:#fff">
|
||||
<view class="map-pin-box">
|
||||
<image class="gplot" mode="widthFix" src="/static/test2.pic.png" />
|
||||
<movable-area class="map-pin-box-area">
|
||||
<movable-view :x="point.x" :y="point.y" direction="all" @change="dragPoint">
|
||||
<view class="point center">
|
||||
<image src="/static/point.png" mode="scaleToFill" />
|
||||
<!-- <uni-icons type="map-pin" color="#007aff" size="26" class="ml20"></uni-icons> -->
|
||||
</view>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="content-des">请拖动图中的蓝色定位图标选择监测点位置(左上角)</view>
|
||||
<uni-forms>
|
||||
<uni-easyinput type="text" v-model="pointName" placeholder="请输入设监测点名称" />
|
||||
</uni-forms>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="closeDrawer"> 取消 </view>
|
||||
<view class="btn-wrap-item ml20" @click="savePoint"> 确定 </view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</uni-drawer>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
deviceList: [
|
||||
{
|
||||
type: '',
|
||||
address: '',
|
||||
pointList: [],
|
||||
gplot: 1,
|
||||
}
|
||||
],
|
||||
range: [
|
||||
{ value: 1, text: "POS-882AX", point: 1 },
|
||||
{ value: 2, text: "NPOS-681", point: 2 },
|
||||
{ value: 3, text: "NPOS-681", point: 1 },
|
||||
{ value: 4, text: "POV-500", point: 2 },
|
||||
{ value: 5, text: "PQV-300", point: 1 },
|
||||
{ value: 6, text: "NPOS-571W", point: 3 },
|
||||
{ value: 7, text: "NPQS-572W", point: 3 },
|
||||
{ value: 8, text: "POS-882B6", point: 2 },
|
||||
{ value: 9, text: "PQS-882B5", point: 1 },
|
||||
{ value: 10, text: "POS-882B4", point: 2 },
|
||||
{ value: 11, text: "PQS-882B2", point: 1 },
|
||||
{ value: 12, text: "POS-882A", point: 2 },
|
||||
{ value: 13, text: "POS-883A", point: 1 },
|
||||
{ value: 14, text: "NPOS-581", point: 2 },
|
||||
{ value: 15, text: "PQS-681", point: 1 },
|
||||
{ value: 16, text: "POS-8825", point: 3 },
|
||||
{ value: 17, text: "PQS-782", point: 1 },
|
||||
{ value: 18, text: "POS-880X", point: 3 },
|
||||
{ value: 19, text: "NPQS-580", point: 1 },
|
||||
{ value: 20, text: "NPOS-572", point: 2 },
|
||||
],
|
||||
point: {
|
||||
x: 170,
|
||||
y: 100,
|
||||
},
|
||||
pointName: '',
|
||||
activeGplot: 1,
|
||||
nowDevice: {},
|
||||
nowDeviceEditIndex: -1,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
typeChange (item) {
|
||||
console.log(item.type);
|
||||
setTimeout(() => {
|
||||
if (!item.type) return
|
||||
let rangeIndex = this.range.findIndex((v) => v.value == item.type)
|
||||
item.pointList = []
|
||||
for (let index = 0; index < this.range[rangeIndex].point; index++) {
|
||||
item.pointList.push({
|
||||
name: '',
|
||||
x: 170,
|
||||
y: 100,
|
||||
})
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
addDevice () {
|
||||
console.log(this.formData);
|
||||
this.deviceList.push({
|
||||
type: '',
|
||||
address: '',
|
||||
pointList: [],
|
||||
gplot: 1,
|
||||
})
|
||||
},
|
||||
chooseGplot (item) {
|
||||
this.activeGplot = item.gplot
|
||||
this.nowDevice = item
|
||||
this.$refs.gplot.open()
|
||||
},
|
||||
confirmGplot () {
|
||||
this.nowDevice.gplot = this.activeGplot
|
||||
this.$refs.gplot.close()
|
||||
},
|
||||
closeDrawer () {
|
||||
this.pointName = ''
|
||||
this.point = {
|
||||
x: 170,
|
||||
y: 100,
|
||||
}
|
||||
this.$refs.gplot.close()
|
||||
this.$refs.point.close()
|
||||
},
|
||||
// 添加新的监测点
|
||||
addNewPoint (item) {
|
||||
this.nowDevice = item
|
||||
this.$refs.point.open()
|
||||
},
|
||||
// 保存监测点
|
||||
savePoint () {
|
||||
if (!this.pointName) {
|
||||
this.$util.toast('请输入监测点名称')
|
||||
return
|
||||
}
|
||||
if (this.nowDeviceEditIndex > -1) {
|
||||
let arr = this.nowDevice.pointList.filter((item, index) => {
|
||||
if (index == this.nowDeviceEditIndex) {
|
||||
return false
|
||||
}
|
||||
return item.pointName == this.pointName
|
||||
})
|
||||
if (arr.length > 0) {
|
||||
this.$util.toast('监测点名称已存在')
|
||||
return
|
||||
}
|
||||
this.nowDevice.pointList[this.nowDeviceEditIndex] = {
|
||||
x: this.point.x,
|
||||
y: this.point.y,
|
||||
pointName: this.pointName,
|
||||
}
|
||||
this.nowDeviceEditIndex = -1
|
||||
} else {
|
||||
let arr = this.nowDevice.pointList.filter((item, index) => {
|
||||
if (index == this.nowDeviceEditIndex) {
|
||||
return false
|
||||
}
|
||||
return item.pointName == this.pointName
|
||||
})
|
||||
if (arr.length > 0) {
|
||||
this.$util.toast('监测点名称已存在')
|
||||
return
|
||||
}
|
||||
this.nowDevice.pointList.push({
|
||||
x: this.point.x,
|
||||
y: this.point.y,
|
||||
pointName: this.pointName,
|
||||
})
|
||||
}
|
||||
console.log(this.pointList);
|
||||
this.closeDrawer()
|
||||
},
|
||||
// 删除一个监测点
|
||||
deletePoint (item, index) {
|
||||
console.log(item, index);
|
||||
item.pointList.splice(index, 1)
|
||||
},
|
||||
// 编辑监测点
|
||||
editPoint (item, index) {
|
||||
this.nowDeviceEditIndex = index
|
||||
this.nowDevice = item
|
||||
this.point.x = item.pointList[index].x
|
||||
this.point.y = item.pointList[index].y
|
||||
this.pointName = item.pointList[index].pointName
|
||||
this.$refs.point.open()
|
||||
},
|
||||
dragPoint (e) {
|
||||
console.log(e)
|
||||
this.point.x = e.detail.x
|
||||
this.point.y = e.detail.y
|
||||
},
|
||||
submit () {
|
||||
this.$util.toast('提交成功')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1500);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.index {
|
||||
padding: 20rpx;
|
||||
|
||||
.content {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.index {
|
||||
padding: 20rpx;
|
||||
|
||||
.new-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 80rpx auto 0;
|
||||
width: 320rpx;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.gplot {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 188rpx;
|
||||
}
|
||||
|
||||
.gplot-box {
|
||||
height: 280rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.gplot-active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 8rpx solid $uni-theme-color;
|
||||
// background: rgba(3, 3, 3, .5);
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.map-pin-box {
|
||||
position: relative;
|
||||
width: 375px;
|
||||
margin: 0 auto;
|
||||
|
||||
.map-pin-box-area {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.point {
|
||||
height: 100rpx;
|
||||
width: 100rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
|
||||
.add-point {
|
||||
height: 72rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx solid #ccc;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
border-color: rgb(229, 229, 229);
|
||||
background-color: rgb(255, 255, 255);
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.point-item {
|
||||
height: 72rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top: 2rpx solid #e5e5e5;
|
||||
border-color: rgb(229, 229, 229);
|
||||
}
|
||||
|
||||
.point-item:first-of-type {
|
||||
border-top: none;
|
||||
}
|
||||
<template>
|
||||
<Cn-page :loading='loading'>
|
||||
<view slot='body'>
|
||||
<view class='index'>
|
||||
<view class="content" v-for="(item, index) in deviceList" :key="index">
|
||||
<uni-forms :label-width="80">
|
||||
<uni-forms-item label="型号">
|
||||
<uni-data-select v-model="item.type" :localdata="range"
|
||||
@change="typeChange(item)"></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="MAC地址">
|
||||
<uni-easyinput type="text" v-model="item.address" placeholder="请输入设备MAC地址" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="拓扑图">
|
||||
<view style="display:flex;">
|
||||
<view style="flex:1">
|
||||
<image class="gplot" src="/static/test2.pic.png" mode="aspectFill" />
|
||||
</view>
|
||||
<uni-icons type="image" color="#007aff" size="26" class="ml20"
|
||||
@click="chooseGplot(item)"></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<!-- <uni-forms-item label="监测点" v-if="item.pointList.length">
|
||||
<view class="point-item" v-for="(item2, index2) in item.pointList" :key="index2"
|
||||
@click="editPoint(item, index2)">
|
||||
<view style="flex:1" v-if="item2.pointName">{{ item2.pointName }}</view>
|
||||
<view style="flex:1;color:#999" v-else>请选择监测点</view>
|
||||
<uni-icons type="compose" color="#007aff" size="26" class="ml20"></uni-icons>
|
||||
</view>
|
||||
</uni-forms-item> -->
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="addDevice"> 添加 </view>
|
||||
<view class="btn-wrap-item ml20" @click="submit"> 提交 </view>
|
||||
</view>
|
||||
<uni-drawer ref="gplot" mode="right" :mask-click="false">
|
||||
<scroll-view style="height: 100%;" scroll-y="true">
|
||||
<view class="content">
|
||||
<image class="gplot gplot-box" mode="aspectFill" :class="{ 'gplot-active': key == activeGplot }"
|
||||
src="/static/test2.pic.png" @click="activeGplot = key" v-for="(item, key) in 3"
|
||||
:key="key" />
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="closeDrawer"> 取消 </view>
|
||||
<view class="btn-wrap-item ml20" @click="confirmGplot"> 确定 </view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</uni-drawer>
|
||||
<uni-drawer ref="point" mode="right" :mask-click="false">
|
||||
<scroll-view style="height: 100%;" scroll-y="true">
|
||||
<view style="background:#fff">
|
||||
<view class="map-pin-box">
|
||||
<image class="gplot" mode="widthFix" src="/static/test2.pic.png" />
|
||||
<movable-area class="map-pin-box-area">
|
||||
<movable-view :x="point.x" :y="point.y" direction="all" @change="dragPoint">
|
||||
<view class="point center">
|
||||
<image src="/static/point.png" mode="scaleToFill" />
|
||||
<!-- <uni-icons type="map-pin" color="#007aff" size="26" class="ml20"></uni-icons> -->
|
||||
</view>
|
||||
</movable-view>
|
||||
</movable-area>
|
||||
</view>
|
||||
</view>
|
||||
<view class="content">
|
||||
<view class="content-des">请拖动图中的蓝色定位图标选择监测点位置(左上角)</view>
|
||||
<uni-forms>
|
||||
<uni-easyinput type="text" v-model="pointName" maxlength="24" placeholder="请输入设监测点名称" />
|
||||
</uni-forms>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="closeDrawer"> 取消 </view>
|
||||
<view class="btn-wrap-item ml20" @click="savePoint"> 确定 </view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</uni-drawer>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
deviceList: [
|
||||
{
|
||||
type: '',
|
||||
address: '',
|
||||
pointList: [],
|
||||
gplot: 1,
|
||||
}
|
||||
],
|
||||
range: [
|
||||
{ value: 1, text: "POS-882AX", point: 1 },
|
||||
{ value: 2, text: "NPOS-681", point: 2 },
|
||||
{ value: 3, text: "NPOS-681", point: 1 },
|
||||
{ value: 4, text: "POV-500", point: 2 },
|
||||
{ value: 5, text: "PQV-300", point: 1 },
|
||||
{ value: 6, text: "NPOS-571W", point: 3 },
|
||||
{ value: 7, text: "NPQS-572W", point: 3 },
|
||||
{ value: 8, text: "POS-882B6", point: 2 },
|
||||
{ value: 9, text: "PQS-882B5", point: 1 },
|
||||
{ value: 10, text: "POS-882B4", point: 2 },
|
||||
{ value: 11, text: "PQS-882B2", point: 1 },
|
||||
{ value: 12, text: "POS-882A", point: 2 },
|
||||
{ value: 13, text: "POS-883A", point: 1 },
|
||||
{ value: 14, text: "NPOS-581", point: 2 },
|
||||
{ value: 15, text: "PQS-681", point: 1 },
|
||||
{ value: 16, text: "POS-8825", point: 3 },
|
||||
{ value: 17, text: "PQS-782", point: 1 },
|
||||
{ value: 18, text: "POS-880X", point: 3 },
|
||||
{ value: 19, text: "NPQS-580", point: 1 },
|
||||
{ value: 20, text: "NPOS-572", point: 2 },
|
||||
],
|
||||
point: {
|
||||
x: 170,
|
||||
y: 100,
|
||||
},
|
||||
pointName: '',
|
||||
activeGplot: 1,
|
||||
nowDevice: {},
|
||||
nowDeviceEditIndex: -1,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
typeChange (item) {
|
||||
console.log(item.type);
|
||||
setTimeout(() => {
|
||||
if (!item.type) return
|
||||
let rangeIndex = this.range.findIndex((v) => v.value == item.type)
|
||||
item.pointList = []
|
||||
for (let index = 0; index < this.range[rangeIndex].point; index++) {
|
||||
item.pointList.push({
|
||||
name: '',
|
||||
x: 170,
|
||||
y: 100,
|
||||
})
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
addDevice () {
|
||||
console.log(this.formData);
|
||||
this.deviceList.push({
|
||||
type: '',
|
||||
address: '',
|
||||
pointList: [],
|
||||
gplot: 1,
|
||||
})
|
||||
},
|
||||
chooseGplot (item) {
|
||||
this.activeGplot = item.gplot
|
||||
this.nowDevice = item
|
||||
this.$refs.gplot.open()
|
||||
},
|
||||
confirmGplot () {
|
||||
this.nowDevice.gplot = this.activeGplot
|
||||
this.$refs.gplot.close()
|
||||
},
|
||||
closeDrawer () {
|
||||
this.pointName = ''
|
||||
this.point = {
|
||||
x: 170,
|
||||
y: 100,
|
||||
}
|
||||
this.$refs.gplot.close()
|
||||
this.$refs.point.close()
|
||||
},
|
||||
// 添加新的监测点
|
||||
addNewPoint (item) {
|
||||
this.nowDevice = item
|
||||
this.$refs.point.open()
|
||||
},
|
||||
// 保存监测点
|
||||
savePoint () {
|
||||
if (!this.pointName) {
|
||||
this.$util.toast('请输入监测点名称')
|
||||
return
|
||||
}
|
||||
if (this.nowDeviceEditIndex > -1) {
|
||||
let arr = this.nowDevice.pointList.filter((item, index) => {
|
||||
if (index == this.nowDeviceEditIndex) {
|
||||
return false
|
||||
}
|
||||
return item.pointName == this.pointName
|
||||
})
|
||||
if (arr.length > 0) {
|
||||
this.$util.toast('监测点名称已存在')
|
||||
return
|
||||
}
|
||||
this.nowDevice.pointList[this.nowDeviceEditIndex] = {
|
||||
x: this.point.x,
|
||||
y: this.point.y,
|
||||
pointName: this.pointName,
|
||||
}
|
||||
this.nowDeviceEditIndex = -1
|
||||
} else {
|
||||
let arr = this.nowDevice.pointList.filter((item, index) => {
|
||||
if (index == this.nowDeviceEditIndex) {
|
||||
return false
|
||||
}
|
||||
return item.pointName == this.pointName
|
||||
})
|
||||
if (arr.length > 0) {
|
||||
this.$util.toast('监测点名称已存在')
|
||||
return
|
||||
}
|
||||
this.nowDevice.pointList.push({
|
||||
x: this.point.x,
|
||||
y: this.point.y,
|
||||
pointName: this.pointName,
|
||||
})
|
||||
}
|
||||
console.log(this.pointList);
|
||||
this.closeDrawer()
|
||||
},
|
||||
// 删除一个监测点
|
||||
deletePoint (item, index) {
|
||||
console.log(item, index);
|
||||
item.pointList.splice(index, 1)
|
||||
},
|
||||
// 编辑监测点
|
||||
editPoint (item, index) {
|
||||
this.nowDeviceEditIndex = index
|
||||
this.nowDevice = item
|
||||
this.point.x = item.pointList[index].x
|
||||
this.point.y = item.pointList[index].y
|
||||
this.pointName = item.pointList[index].pointName
|
||||
this.$refs.point.open()
|
||||
},
|
||||
dragPoint (e) {
|
||||
console.log(e)
|
||||
this.point.x = e.detail.x
|
||||
this.point.y = e.detail.y
|
||||
},
|
||||
submit () {
|
||||
this.$util.toast('提交成功')
|
||||
setTimeout(() => {
|
||||
uni.navigateBack({ delta: 1 })
|
||||
}, 1500);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.index {
|
||||
padding: 20rpx;
|
||||
|
||||
.content {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.index {
|
||||
padding: 20rpx;
|
||||
|
||||
.new-btn {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 80rpx auto 0;
|
||||
width: 320rpx;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.gplot {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 188rpx;
|
||||
}
|
||||
|
||||
.gplot-box {
|
||||
height: 280rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.gplot-active::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border: 8rpx solid $uni-theme-color;
|
||||
// background: rgba(3, 3, 3, .5);
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.map-pin-box {
|
||||
position: relative;
|
||||
width: 375px;
|
||||
margin: 0 auto;
|
||||
|
||||
.map-pin-box-area {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.point {
|
||||
height: 100rpx;
|
||||
width: 100rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
|
||||
.add-point {
|
||||
height: 72rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 2rpx solid #ccc;
|
||||
border-radius: 12rpx;
|
||||
font-size: 28rpx;
|
||||
border-color: rgb(229, 229, 229);
|
||||
background-color: rgb(255, 255, 255);
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.point-item {
|
||||
height: 72rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-top: 2rpx solid #e5e5e5;
|
||||
border-color: rgb(229, 229, 229);
|
||||
}
|
||||
|
||||
.point-item:first-of-type {
|
||||
border-top: none;
|
||||
}
|
||||
</style>
|
||||
@@ -8,10 +8,10 @@
|
||||
<uni-data-select v-model="item.type" :localdata="range"></uni-data-select>
|
||||
</uni-forms-item> -->
|
||||
<uni-forms-item label="标题">
|
||||
<uni-easyinput type="text" v-model="formData.title" placeholder="请输入问题简要"/>
|
||||
<uni-easyinput type="text" v-model="formData.title" maxlength="32" placeholder="请输入问题简要"/>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="描述">
|
||||
<uni-easyinput type="textarea" v-model="formData.description" placeholder="请输入详细描述"/>
|
||||
<uni-easyinput type="textarea" v-model="formData.description" maxlength="999" placeholder="请输入详细描述"/>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="图片">
|
||||
<uni-file-picker :auto-upload="false" @select="fileChange" @delete="delImg">
|
||||
@@ -23,9 +23,9 @@
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item " @click="submit"> 提交</view>
|
||||
</view>
|
||||
<navigator url="/pages/home/service" hover-class="none" class="fixed-btn">
|
||||
<!-- <navigator url="/pages/home/service" hover-class="none" class="fixed-btn">
|
||||
<image src="/static/service.png" style="height:66rpx;width:66rpx"/>
|
||||
</navigator>
|
||||
</navigator> -->
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
@@ -83,6 +83,7 @@ export default {
|
||||
})
|
||||
return
|
||||
}
|
||||
console.log("🚀 ~ this.formData:", this.formData)
|
||||
addFeedBack(this.formData).then(res => {
|
||||
console.log(res)
|
||||
console.log(this.formData.files.length)
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
</view>
|
||||
<view class="smallLabel mt20">
|
||||
<view class="boxCenter">
|
||||
<view>
|
||||
<!-- <view>
|
||||
<checkbox-group @change="changeBox" class="boxCenter"
|
||||
><checkbox value="true" :checked="checkedAll" />全选
|
||||
</checkbox-group></view
|
||||
>
|
||||
> -->
|
||||
已选择 {{ checkedTotal }} 条事件
|
||||
</view>
|
||||
<view class="nav-menu nav-menu-btn" @click="selectDevice">申请报告 </view>
|
||||
@@ -127,7 +127,7 @@ export default {
|
||||
checkedAll: false,
|
||||
checkedTotal: 0,
|
||||
sort: 0,
|
||||
array: ['发生时间', '暂降深度', '持续时间'],
|
||||
array: ['发生时间', '暂降幅值', '持续时间'],
|
||||
}
|
||||
},
|
||||
mounted() {},
|
||||
@@ -222,21 +222,21 @@ export default {
|
||||
},
|
||||
judgment(val, key) {
|
||||
switch (val) {
|
||||
case '电压暂降':
|
||||
case '暂降':
|
||||
return {
|
||||
type: 'sag',
|
||||
icon: 'icon-a-svg4',
|
||||
color: '#2563eb',
|
||||
size: '25',
|
||||
}
|
||||
case '电压暂升':
|
||||
case '暂升':
|
||||
return {
|
||||
type: 'swell',
|
||||
icon: 'icon-a-svg5',
|
||||
color: '#e6a23c',
|
||||
size: '25',
|
||||
}
|
||||
case '电压中断':
|
||||
case '中断':
|
||||
return {
|
||||
type: 'interrupt',
|
||||
icon: 'icon-zhongduan2',
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
</view>
|
||||
</picker> -->
|
||||
</view>
|
||||
<view class="content device" >
|
||||
<view class="content device">
|
||||
<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)">
|
||||
@@ -245,6 +245,8 @@ export default {
|
||||
engineeringId: this.store.params.engineerId,
|
||||
}).then((res) => {
|
||||
console.log(res)
|
||||
this.select.projectName = ''
|
||||
this.select.projectNameIndex = 0
|
||||
let arr = [
|
||||
{
|
||||
text: '全部项目',
|
||||
@@ -259,6 +261,7 @@ export default {
|
||||
}),
|
||||
]
|
||||
this.projectList = arr
|
||||
|
||||
uni.setStorageSync('projectList', arr)
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="index-zhuyonghu">
|
||||
<template v-if="devCount.engineeringListLength > 0">
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-gongcheng" size="18" color="#376cf3" />
|
||||
<text>所有工程设备统计</text>
|
||||
</view>
|
||||
@@ -33,7 +33,7 @@
|
||||
</view>
|
||||
<!-- <view class="mt20"></view> -->
|
||||
</template>
|
||||
<!-- <view class="canneng-index-title mb20">当前工程设备统计</view>
|
||||
<!-- <view class="canneng-index-title mb20 ml20">当前工程设备统计</view>
|
||||
<view class="header">
|
||||
<view class="header-item" @click="jump('nowEngineering')">
|
||||
<view class="header-item-value"
|
||||
@@ -50,7 +50,7 @@
|
||||
<view class="header-item-label">离线设备</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<view class="canneng-index-title mt20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mt20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons type="settings" size="18" color="#376cf3" />
|
||||
<text>常用功能</text>
|
||||
</view>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="index-zhuyonghu">
|
||||
<template v-if="devCount.engineeringListLength > 1">
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-gongcheng" size="18" color="#376cf3" />
|
||||
<text>所有工程设备统计</text>
|
||||
</view>
|
||||
@@ -21,7 +21,7 @@
|
||||
</view>
|
||||
<view class="mt20"></view>
|
||||
</template>
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-zaixianjianceshebei" size="18" color="#376cf3" />
|
||||
<text>当前工程设备统计</text>
|
||||
</view>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="index-zhuanzhi">
|
||||
<template v-if="devCount.engineeringListLength > 1">
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-gongcheng" size="18" color="#376cf3" />
|
||||
<text>所有工程设备统计</text>
|
||||
</view>
|
||||
@@ -35,7 +35,7 @@
|
||||
</view>
|
||||
<view class="mt20"></view>
|
||||
</template>
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-zaixianjianceshebei" size="18" color="#376cf3" />
|
||||
<text>当前工程设备统计</text>
|
||||
</view>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="index-zhuyonghu">
|
||||
<template v-if="devCount.engineeringListLength > 1">
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-gongcheng" size="18" color="#376cf3" />
|
||||
<text>所有工程设备统计</text>
|
||||
</view>
|
||||
@@ -21,7 +21,7 @@
|
||||
</view>
|
||||
<view class="mt20"></view>
|
||||
</template>
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-zaixianjianceshebei" size="18" color="#376cf3" />
|
||||
<text>当前工程设备统计</text>
|
||||
</view>
|
||||
@@ -49,7 +49,7 @@
|
||||
<view class="header-item-label">稳态事件数</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="canneng-index-title mt20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mt20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons type="settings" size="18" color="#376cf3" />
|
||||
<text>常用功能</text>
|
||||
</view>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="index-zhuanzhi">
|
||||
<template v-if="devCount.engineeringListLength > 1">
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-gongcheng" size="18" color="#376cf3" />
|
||||
<text>所有工程设备统计</text>
|
||||
</view>
|
||||
@@ -33,7 +33,7 @@
|
||||
</view>
|
||||
<view class="mt20"></view>
|
||||
</template>
|
||||
<view class="canneng-index-title mb20 canneng-index-title-with-icon">
|
||||
<view class="canneng-index-title mb20 ml20 canneng-index-title-with-icon">
|
||||
<uni-icons custom-prefix="iconfont" type="icon-zaixianjianceshebei" size="18" color="#376cf3" />
|
||||
<text>当前工程设备统计</text>
|
||||
</view>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,7 @@
|
||||
<view class="event-desc">
|
||||
<text>统计时间:{{
|
||||
curSub == 0 ? item.startTime : item.startTime + ' 至 ' + item.endTime
|
||||
}}</text>
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="event-action" v-if="!showNotGenerated(item)">
|
||||
@@ -54,7 +54,7 @@
|
||||
<view class="event-detail textBox" @touchmove.stop>
|
||||
<text v-if="!showNotGenerated(item)">{{
|
||||
item.overLimitDesc == '' ? '该监测点暂无指标越限' : item.overLimitDesc
|
||||
}}</text>
|
||||
}}</text>
|
||||
<text v-else>数据未生成,暂不支持下载</text>
|
||||
</view>
|
||||
<!-- <view class="downloadReport" @click="download">
|
||||
@@ -180,46 +180,14 @@ export default {
|
||||
timeType: this.selectValue.report,
|
||||
})
|
||||
.then((res) => {
|
||||
// 下载文件资源到本地
|
||||
const match = this.$config.static + res.data.match(/excelreport([^?]*)/)[1]
|
||||
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('下载成功')
|
||||
url: match,
|
||||
success: (downloadRes) => {
|
||||
if (downloadRes.statusCode === 200) {
|
||||
this.openReportFile(downloadRes.tempFilePath)
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
@@ -228,10 +196,19 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: function (res) { },
|
||||
fail: () => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
title: '下载失败!',
|
||||
duration: 1000,
|
||||
})
|
||||
},
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
@@ -240,6 +217,72 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
openReportFile(tempFilePath) {
|
||||
const previewFile = (filePath) => {
|
||||
uni.hideLoading()
|
||||
uni.openDocument({
|
||||
filePath,
|
||||
fileType: 'xlsx',
|
||||
showMenu: true,
|
||||
success: () => {
|
||||
console.log('成功打开文件')
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('打开文件失败', err)
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '预览失败',
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
// iOS 需保留 xlsx 后缀,saveFile 随机路径会导致 openDocument 失败
|
||||
if (plus.os.name === 'iOS') {
|
||||
const fileName = `harmonic_report_${Date.now()}.xlsx`
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
tempFilePath,
|
||||
(entry) => {
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
'_doc/',
|
||||
(docEntry) => {
|
||||
entry.copyTo(
|
||||
docEntry,
|
||||
fileName,
|
||||
(newEntry) => previewFile(newEntry.fullPath),
|
||||
() => previewFile(tempFilePath)
|
||||
)
|
||||
},
|
||||
() => previewFile(tempFilePath)
|
||||
)
|
||||
},
|
||||
() => previewFile(tempFilePath)
|
||||
)
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
|
||||
uni.saveFile({
|
||||
tempFilePath,
|
||||
success: (data) => {
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
title: '下载成功!',
|
||||
duration: 1000,
|
||||
})
|
||||
setTimeout(() => previewFile(data.savedFilePath), 500)
|
||||
},
|
||||
fail: () => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '保存失败!',
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
// 下拉
|
||||
refresherrefresh() {
|
||||
this.triggered = true
|
||||
@@ -384,6 +427,10 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/deep/ .segmented-control__text {
|
||||
line-height: 60rpx !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,307 +1,315 @@
|
||||
<template>
|
||||
<view class="target-info-page">
|
||||
<scroll-view class="target-info-scroll" scroll-y :show-scrollbar="false">
|
||||
<view class="monitor-card card">
|
||||
<view class="card-header">
|
||||
<view class="event-icon">
|
||||
<Cn-icon-transient name="监测点" />
|
||||
</view>
|
||||
<view class="card-header-info">
|
||||
<text class="point-name ellipsis">{{ pointInfo.pointName || '-' }}</text>
|
||||
<view class="meta-row">
|
||||
<text v-if="pointInfo.engineeringName" class="meta-item ellipsis">
|
||||
工程:{{ pointInfo.engineeringName }}
|
||||
</text>
|
||||
<text class="meta-item ellipsis">项目:{{ pointInfo.projectName || '-' }}</text>
|
||||
<text class="meta-item ellipsis">设备:{{ pointInfo.deviceName || '-' }}</text>
|
||||
</view>
|
||||
<text class="meta-time ellipsis">最新数据时间:{{ pointInfo.dataTime || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="legend-row">
|
||||
<view class="legend-item" v-for="phase in phaseColors" :key="phase.name">
|
||||
<view class="legend-dot" :style="{ background: phase.color }" />
|
||||
<text class="legend-text">{{ phase.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="moreChildren.length" class="params-section">
|
||||
<view
|
||||
v-for="(rowItems, rowIdx) in chunkedChildren(moreChildren)"
|
||||
:key="rowIdx"
|
||||
class="double-row"
|
||||
>
|
||||
<view v-for="(child, childIdx) in rowItems" :key="child.targetId || childIdx" class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ child.name }}{{ child.unit ? ` (${child.unit})` : '' }}</text>
|
||||
</view>
|
||||
<view v-if="hasTPhaseData(child)" class="phase-single">
|
||||
<text class="phase-value-vertical phase-value-vertical--neutral">{{ child.T }}</text>
|
||||
</view>
|
||||
<view v-else class="phase-vertical">
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[0].color }">{{ child.A }}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[1].color }">{{ child.B }}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[2].color }">{{ child.C }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="empty-wrap">
|
||||
<Cn-empty msg="暂无更多指标" :paddingTop="120"></Cn-empty>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pointInfo: {},
|
||||
phaseColors: [
|
||||
{ name: 'A相', color: '#F1B22E' },
|
||||
{ name: 'B相', color: '#2BA471' },
|
||||
{ name: 'C相', color: '#D54941' },
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
moreChildren() {
|
||||
const children = this.pointInfo.children || []
|
||||
const selected = this.getSelectedIndicators()
|
||||
return children.filter(
|
||||
(child) => !selected.some((name) => this.matchIndicator(child.name, name)),
|
||||
)
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
const point = uni.getStorageSync('monitorPointDetail')
|
||||
if (point) {
|
||||
this.pointInfo = {
|
||||
...point,
|
||||
selectedIndicators: this.getSelectedIndicatorsFromStorage(point.selectedIndicators),
|
||||
}
|
||||
if (point.pointName) {
|
||||
uni.setNavigationBarTitle({ title: point.pointName })
|
||||
}
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.removeStorageSync('monitorPointDetail')
|
||||
},
|
||||
methods: {
|
||||
getSelectedIndicatorsFromStorage(fallback = []) {
|
||||
const cached = uni.getStorageSync(this.$cacheKey.monitorSelectedIndicators)
|
||||
if (Array.isArray(cached) && cached.length) {
|
||||
return cached
|
||||
}
|
||||
return Array.isArray(fallback) ? fallback : []
|
||||
},
|
||||
getSelectedIndicators() {
|
||||
return this.getSelectedIndicatorsFromStorage(this.pointInfo.selectedIndicators)
|
||||
},
|
||||
matchIndicator(name, selected) {
|
||||
if (!name || !selected) return false
|
||||
const base = (name || '').replace(/\(.*\)/, '').trim()
|
||||
const selectedBase = (selected || '').replace(/\(.*\)/, '').trim()
|
||||
return base === selectedBase
|
||||
},
|
||||
hasTPhaseData(child) {
|
||||
return child.T !== undefined && child.T !== null && child.T !== '-'
|
||||
},
|
||||
chunkedChildren(children) {
|
||||
const result = []
|
||||
for (let i = 0; i < children.length; i += 2) {
|
||||
result.push(children.slice(i, i + 2))
|
||||
}
|
||||
return result
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.target-info-page {
|
||||
min-height: 100vh;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.target-info-scroll {
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx 0 40rpx;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #ffffff;
|
||||
border-radius: 10px;
|
||||
box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 1px 1px;
|
||||
margin: 0 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monitor-card {
|
||||
border: 1rpx solid #eef2f6;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 20rpx 20rpx 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid #eef2f6;
|
||||
}
|
||||
|
||||
.event-icon {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 20rpx;
|
||||
background-color: #376cf320;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card-header-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.point-name {
|
||||
display: block;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 6rpx 12rpx;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.meta-time {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.legend-row {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
align-items: center;
|
||||
padding: 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.legend-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.params-section {
|
||||
padding: 0 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
position: relative;
|
||||
min-height: 320rpx;
|
||||
}
|
||||
|
||||
.double-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.param-group {
|
||||
min-width: 0;
|
||||
background: #f3f3f3;
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 8rpx 12rpx;
|
||||
}
|
||||
|
||||
.param-title {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 8rpx;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
.phase-vertical {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.phase-single {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rpx;
|
||||
}
|
||||
|
||||
.phase-item-vertical {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rpx;
|
||||
}
|
||||
|
||||
.phase-value-vertical {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
|
||||
&--neutral {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.phase-divider {
|
||||
width: 1px;
|
||||
background: #d2d2d2;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<view class="target-info-page">
|
||||
<scroll-view class="target-info-scroll" scroll-y :show-scrollbar="false">
|
||||
<view class="monitor-card card">
|
||||
<view class="card-header">
|
||||
<view class="event-icon">
|
||||
<Cn-icon-transient name="监测点" />
|
||||
</view>
|
||||
<view class="card-header-info">
|
||||
<view class="point-name-row">
|
||||
<text class="point-name ellipsis">{{ pointInfo.pointName || '-' }}</text>
|
||||
<text class="event-tag ml10" :class="pointInfo.runStatus == 0 ? 'zx-tag' : 'lx-tag'">
|
||||
{{ pointInfo.runStatus == 0 ? '在线' : '离线' }}
|
||||
</text>
|
||||
</view>
|
||||
<view class="meta-row">
|
||||
<text v-if="pointInfo.engineeringName" class="meta-item ellipsis">
|
||||
工程:{{ pointInfo.engineeringName }}
|
||||
</text>
|
||||
<text class="meta-item ellipsis">项目:{{ pointInfo.projectName || '-' }}</text>
|
||||
<text class="meta-item ellipsis">设备:{{ pointInfo.deviceName || '-' }}</text>
|
||||
</view>
|
||||
<text class="meta-time ellipsis">最新数据时间:{{ pointInfo.dataTime || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="legend-row">
|
||||
<view class="legend-item" v-for="phase in phaseColors" :key="phase.name">
|
||||
<view class="legend-dot" :style="{ background: phase.color }" />
|
||||
<text class="legend-text">{{ phase.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="moreChildren.length" class="params-section">
|
||||
<view v-for="(rowItems, rowIdx) in chunkedChildren(moreChildren)" :key="rowIdx" class="double-row">
|
||||
<view v-for="(child, childIdx) in rowItems" :key="child.targetId || childIdx"
|
||||
class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ child.name }}{{ child.unit ? ` (${child.unit})` : '' }}</text>
|
||||
</view>
|
||||
<view v-if="hasTPhaseData(child)" class="phase-single">
|
||||
<text class="phase-value-vertical phase-value-vertical--neutral">{{ child.T }}</text>
|
||||
</view>
|
||||
<view v-else class="phase-vertical">
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[0].color }">{{
|
||||
child.A }}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[1].color }">{{
|
||||
child.B }}</text>
|
||||
</view>
|
||||
<view class="phase-divider" />
|
||||
<view class="phase-item-vertical">
|
||||
<text class="phase-value-vertical" :style="{ color: phaseColors[2].color }">{{
|
||||
child.C }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-else class="empty-wrap">
|
||||
<Cn-empty msg="暂无指标数据" :paddingTop="120"></Cn-empty>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pointInfo: {},
|
||||
phaseColors: [
|
||||
{ name: 'A相', color: '#DAA520' },
|
||||
{ name: 'B相', color: '#2E8B57' },
|
||||
{ name: 'C相', color: '#D54941' },
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
moreChildren() {
|
||||
return this.pointInfo.children || []
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
const point = uni.getStorageSync('monitorPointDetail')
|
||||
if (point) {
|
||||
this.pointInfo = { ...point }
|
||||
if (point.pointName) {
|
||||
uni.setNavigationBarTitle({ title: point.pointName })
|
||||
}
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.removeStorageSync('monitorPointDetail')
|
||||
},
|
||||
methods: {
|
||||
hasTPhaseData(child) {
|
||||
return child.T !== undefined && child.T !== null && child.T !== '-'
|
||||
},
|
||||
chunkedChildren(children) {
|
||||
const result = []
|
||||
for (let i = 0; i < children.length; i += 2) {
|
||||
result.push(children.slice(i, i + 2))
|
||||
}
|
||||
return result
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.target-info-page {
|
||||
min-height: 100vh;
|
||||
background: #f7f8fa;
|
||||
}
|
||||
|
||||
.target-info-scroll {
|
||||
height: 100vh;
|
||||
box-sizing: border-box;
|
||||
padding: 20rpx 0 40rpx;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #ffffff;
|
||||
border-radius: 10px;
|
||||
box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 1px 1px;
|
||||
margin: 0 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monitor-card {
|
||||
border: 1rpx solid #eef2f6;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 20rpx 20rpx 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid #eef2f6;
|
||||
}
|
||||
|
||||
.event-icon {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 16rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 20rpx;
|
||||
background-color: #376cf320;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.card-header-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.point-name-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12rpx;
|
||||
margin-bottom: 8rpx;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.point-name {
|
||||
// flex: 1;
|
||||
min-width: 0;
|
||||
font-size: 30rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.meta-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr ;
|
||||
gap: 6rpx 12rpx;
|
||||
}
|
||||
|
||||
.meta-item {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.meta-time {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.legend-row {
|
||||
display: flex;
|
||||
gap: 20rpx;
|
||||
align-items: center;
|
||||
justify-content: end;
|
||||
padding: 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.legend-dot {
|
||||
width: 16rpx;
|
||||
height: 16rpx;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.legend-text {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.params-section {
|
||||
padding: 0 16rpx 20rpx;
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
position: relative;
|
||||
min-height: 320rpx;
|
||||
}
|
||||
|
||||
.double-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.param-group {
|
||||
min-width: 0;
|
||||
background: #f3f3f3;
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 8rpx 12rpx;
|
||||
}
|
||||
|
||||
.param-title {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
margin-bottom: 8rpx;
|
||||
padding-left: 4rpx;
|
||||
}
|
||||
|
||||
.phase-vertical {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.phase-single {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rpx;
|
||||
}
|
||||
|
||||
.phase-item-vertical {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 4rpx;
|
||||
}
|
||||
|
||||
.phase-value-vertical {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
|
||||
&--neutral {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.phase-divider {
|
||||
width: 1px;
|
||||
background: #d2d2d2;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.event-tag {
|
||||
flex-shrink: 0;
|
||||
font-size: 22rpx;
|
||||
padding: 2rpx 10rpx;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
.zx-tag {
|
||||
background-color: #10b98120;
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.lx-tag {
|
||||
background-color: #ff3b3020;
|
||||
color: #ff3b30;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
<Cn-filterCriteria @select="select" :showQianTree="false"> </Cn-filterCriteria>
|
||||
</view>
|
||||
<scroll-view scroll-y="true" @scroll="onScroll" :scroll-top="scrollTop" scroll-with-animation
|
||||
@refresherrefresh="refresherrefresh" @scrolltolower="scrolltolower"
|
||||
:refresher-triggered="triggered" refresher-enabled="true" class="record event-list mt20"
|
||||
@refresherrefresh="refresherrefresh" @scrolltolower="scrolltolower" :refresher-triggered="triggered"
|
||||
refresher-enabled="true" 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">
|
||||
<!-- 头部:图标 + 信息 + 操作 -->
|
||||
@@ -67,7 +67,7 @@
|
||||
<text>报告状态:</text>
|
||||
<text :style="{ color: item.isComplete == 1 ? '#10b981' : '#FF0000' }">{{
|
||||
item.isComplete == 1 ? '已完成' : '未完成'
|
||||
}}</text>
|
||||
}}</text>
|
||||
</view>
|
||||
<view class="device-body-item">
|
||||
<text>申请时间:</text>
|
||||
@@ -192,10 +192,17 @@ export default {
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
title: '生成事件报告成功!',
|
||||
title: '生成报告成功!',
|
||||
duration: 1000,
|
||||
})
|
||||
this.store.reload()
|
||||
}).catch((err) => {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
title: err.message,
|
||||
duration: 1000,
|
||||
})
|
||||
})
|
||||
},
|
||||
// 下载报告
|
||||
@@ -208,46 +215,26 @@ export default {
|
||||
id: item.eventId,
|
||||
})
|
||||
.then((res) => {
|
||||
// 下载文件资源到本地
|
||||
const pathMatch = res.data.match(/excelreport([^?]*)/)
|
||||
if (!pathMatch) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
title: '文件地址无效',
|
||||
duration: 1000,
|
||||
})
|
||||
return
|
||||
}
|
||||
const fileMeta = this.getReportFileMeta(pathMatch[1])
|
||||
const match = this.$config.static + pathMatch[1]
|
||||
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('下载成功')
|
||||
url: match,
|
||||
success: (downloadRes) => {
|
||||
if (downloadRes.statusCode === 200) {
|
||||
this.openReportFile(downloadRes.tempFilePath, fileMeta)
|
||||
} else {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
@@ -256,10 +243,19 @@ export default {
|
||||
})
|
||||
}
|
||||
},
|
||||
fail: function (res) { },
|
||||
fail: () => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
title: '下载失败!',
|
||||
duration: 1000,
|
||||
})
|
||||
},
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
mask: true,
|
||||
@@ -268,6 +264,79 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
getReportFileMeta(filePath) {
|
||||
const lower = (filePath || '').toLowerCase()
|
||||
if (lower.endsWith('.doc')) {
|
||||
return { fileType: 'doc', ext: 'doc' }
|
||||
}
|
||||
return { fileType: 'docx', ext: 'docx' }
|
||||
},
|
||||
openReportFile(tempFilePath, fileMeta) {
|
||||
const previewFile = (filePath) => {
|
||||
uni.hideLoading()
|
||||
uni.openDocument({
|
||||
filePath,
|
||||
fileType: fileMeta.fileType,
|
||||
showMenu: true,
|
||||
success: () => {
|
||||
console.log('成功打开文件')
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('打开文件失败', err)
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '预览失败',
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
// iOS 需保留 doc/docx 后缀,saveFile 随机路径会导致 openDocument 失败
|
||||
if (plus.os.name === 'iOS') {
|
||||
const fileName = `event_report_${Date.now()}.${fileMeta.ext}`
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
tempFilePath,
|
||||
(entry) => {
|
||||
plus.io.resolveLocalFileSystemURL(
|
||||
'_doc/',
|
||||
(docEntry) => {
|
||||
entry.copyTo(
|
||||
docEntry,
|
||||
fileName,
|
||||
(newEntry) => previewFile(newEntry.fullPath),
|
||||
() => previewFile(tempFilePath)
|
||||
)
|
||||
},
|
||||
() => previewFile(tempFilePath)
|
||||
)
|
||||
},
|
||||
() => previewFile(tempFilePath)
|
||||
)
|
||||
return
|
||||
}
|
||||
// #endif
|
||||
|
||||
uni.saveFile({
|
||||
tempFilePath,
|
||||
success: (data) => {
|
||||
uni.showToast({
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
title: '下载成功!',
|
||||
duration: 1000,
|
||||
})
|
||||
setTimeout(() => previewFile(data.savedFilePath), 500)
|
||||
},
|
||||
fail: () => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '保存失败!',
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
// 刷新
|
||||
reload() {
|
||||
switch (this.curSub) {
|
||||
@@ -350,9 +419,9 @@ export default {
|
||||
font-size: 26rpx;
|
||||
color: #666666;
|
||||
line-height: 1.5;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// }
|
||||
@@ -416,6 +485,10 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/deep/ .segmented-control__text {
|
||||
line-height: 60rpx !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -72,6 +72,7 @@ import Engineering from './comp/engineering.vue'
|
||||
import list from '../../common/js/list'
|
||||
import { getDevCount } from '../../common/api/device.js'
|
||||
import { queryEngineering } from '@/common/api/engineering.js'
|
||||
import { checkAppUpdate } from '@/common/js/update.js'
|
||||
|
||||
export default {
|
||||
mixins: [list],
|
||||
@@ -252,6 +253,11 @@ export default {
|
||||
this.showBackTop = e.scrollTop > 200
|
||||
},
|
||||
onLoad() {
|
||||
// #ifdef APP-PLUS
|
||||
checkAppUpdate()
|
||||
// #endif
|
||||
|
||||
|
||||
// 页面加载时,动态配置导航栏按钮
|
||||
if (!uni.getStorageSync(this.$cacheKey.access_token)) {
|
||||
uni.reLaunch({
|
||||
@@ -289,6 +295,8 @@ export default {
|
||||
// #endif
|
||||
},
|
||||
onShow() {
|
||||
|
||||
|
||||
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
|
||||
|
||||
let access_token = uni.getStorageSync(this.$cacheKey.access_token)
|
||||
@@ -319,7 +327,7 @@ export default {
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
<style lang="scss" scoped>
|
||||
.popup-content {
|
||||
background: #fff;
|
||||
}
|
||||
@@ -355,7 +363,7 @@ export default {
|
||||
padding: 4rpx 20rpx;
|
||||
// margin-left: 20rpx;
|
||||
// margin-bottom: 20rpx;
|
||||
line-height: 38rpx;
|
||||
line-height: 40rpx;
|
||||
font-size: 24rpx;
|
||||
border-radius: 8rpx;
|
||||
background: #ebeaec;
|
||||
@@ -386,6 +394,6 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -61,7 +61,7 @@ export default {
|
||||
selectValue: {},
|
||||
devCount: [],
|
||||
sortIndex: 0,
|
||||
sortOptions: ['发生时间', '暂降深度', '持续时间'],
|
||||
sortOptions: ['发生时间', '暂降幅值', '持续时间'],
|
||||
}
|
||||
},
|
||||
onLoad() { },
|
||||
@@ -101,7 +101,7 @@ export default {
|
||||
this.getDevCount()
|
||||
this.$nextTick(() => {
|
||||
if (params.type !== '') {
|
||||
this.current = params.type - 0
|
||||
this.current = (params.type - 0)||0
|
||||
}
|
||||
if (params.engineeringName != '') {
|
||||
this.$refs.cnFilterCriteria && this.$refs.cnFilterCriteria.external(params)
|
||||
@@ -343,4 +343,5 @@ export default {
|
||||
// white-space: nowrap;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -82,11 +82,7 @@
|
||||
<view class="mine-nav-label">关注工程配置</view>
|
||||
<uni-icons type="forward" color="#aaa" size="20"></uni-icons>
|
||||
</view>
|
||||
<!-- <view class="mine-nav" @click="jump('transientSetting')" v-if="userInfo.authorities !== 'tourist'">
|
||||
<image mode="aspectFill" class="mine-nav-icon" src="/static/tongji.png" />
|
||||
<view class="mine-nav-label">暂态统计配置</view>
|
||||
<uni-icons type="forward" color="#aaa" size="20"></uni-icons>
|
||||
</view> -->
|
||||
|
||||
<view class="mine-nav" @click="jump('setup')" style="border-bottom: none">
|
||||
<image mode="aspectFill" class="mine-nav-icon" src="/static/setup.png" />
|
||||
<view class="mine-nav-label">设置</view>
|
||||
@@ -259,7 +255,7 @@ export default {
|
||||
handleScon() {
|
||||
this.$refs.message.close()
|
||||
uni.scanCode({
|
||||
onlyFromCamera: true,
|
||||
// onlyFromCamera: false,
|
||||
success: (res) => {
|
||||
console.log('条码类型:' + res.scanType)
|
||||
console.log('条码内容:' + res.result)
|
||||
|
||||
@@ -6,34 +6,33 @@
|
||||
<view class="detail-content-title mb20">{{ pageData.title }}</view>
|
||||
<view> {{ pageData.createTime }}</view>
|
||||
<view class="mt10 mb10">{{ pageData.description }}</view>
|
||||
<uni-file-picker readonly v-model="imageValue" mode="grid"/>
|
||||
<uni-file-picker readonly v-model="imageValue" mode="grid" />
|
||||
</view>
|
||||
<view class="detail-content " style="margin-bottom:0">
|
||||
<view class="detail-content-title ">
|
||||
<view class="title">进度</view>
|
||||
<!-- <template v-if="pageData.status === '1'">-->
|
||||
<!-- <view class="title-btn mr10" @click="updateFeedBackStatus('2')">解决</view>-->
|
||||
<!-- <view class="title-btn mr10" @click="updateFeedBackStatus('0')">关闭</view>-->
|
||||
<!-- </template>-->
|
||||
<!-- <template v-if="pageData.status === '2'">-->
|
||||
<!-- <view class="title-btn mr10" @click="updateFeedBackStatus('0')">关闭</view>-->
|
||||
<!-- </template>-->
|
||||
<!-- <view class="title-btn" @click="open">回复</view>-->
|
||||
<template v-if="pageData.status === '1'">
|
||||
<view class="title-btn mr10" @click="updateFeedBackStatus('2')">解决</view>
|
||||
<view class="title-btn mr10" @click="updateFeedBackStatus('0')" v-if="userInfo.authorities === 'app_vip_user'">关闭</view>
|
||||
</template>
|
||||
<template v-if="pageData.status === '2'">
|
||||
<view class="title-btn mr10" @click="updateFeedBackStatus('0')" v-if="userInfo.authorities === 'app_vip_user'">关闭</view>
|
||||
</template>
|
||||
<view class="title-btn" @click="open" v-if="pageData.status != '0'">回复</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-list>
|
||||
<uni-list-item :title="item.userName" :note="item.chatContent" :rightText="item.createTime"
|
||||
v-for="(item, index) in pageData.csFeedbackChatPOList" :key="index"/>
|
||||
v-for="(item, index) in pageData.csFeedbackChatPOList" :key="index" />
|
||||
<Cn-empty
|
||||
v-if="pageData.csFeedbackChatPOList && pageData.csFeedbackChatPOList.length == 0"></Cn-empty>
|
||||
</uni-list>
|
||||
<!-- 输入框示例 -->
|
||||
<uni-popup ref="inputDialog" type="dialog">
|
||||
<uni-popup-dialog ref="inputClose" type="info" mode="input" title="输入内容"
|
||||
value="对话框预置提示内容!"
|
||||
placeholder="请输入内容" @confirm="dialogInputConfirm">
|
||||
<uni-easyinput type="textarea" :maxlength="250" autoHeight v-model="chatContent"
|
||||
placeholder="请输入内容"></uni-easyinput>
|
||||
<uni-popup-dialog ref="inputClose" type="info" mode="input" title="输入内容" value="对话框预置提示内容!"
|
||||
placeholder="请输入内容" @confirm="dialogInputConfirm">
|
||||
<uni-easyinput type="textarea" :maxlength="250" autoHeight v-model="chatContent" clearable
|
||||
placeholder="请输入内容"></uni-easyinput>
|
||||
</uni-popup-dialog>
|
||||
</uni-popup>
|
||||
</view>
|
||||
@@ -41,7 +40,7 @@
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
import {queryFeedBackDetail, AddFeedbackChat, updateChatStatus, updateFeedBackStatus} from '../../common/api/feedback'
|
||||
import { queryFeedBackDetail, AddFeedbackChat, updateChatStatus, updateFeedBackStatus } from '../../common/api/feedback'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@@ -55,11 +54,13 @@ export default {
|
||||
"url": "/static/logo.png",
|
||||
}
|
||||
],
|
||||
userInfo: {},
|
||||
pageData: {},
|
||||
pageOption: {}
|
||||
}
|
||||
},
|
||||
onLoad(o) {
|
||||
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
|
||||
this.pageOption = o
|
||||
this.init()
|
||||
updateChatStatus({
|
||||
@@ -93,7 +94,7 @@ export default {
|
||||
})
|
||||
},
|
||||
dialogInputConfirm() {
|
||||
AddFeedbackChat({chatContent: this.chatContent, id: this.pageOption.id}).then(res => {
|
||||
AddFeedbackChat({ chatContent: this.chatContent, id: this.pageOption.id }).then(res => {
|
||||
console.log(res);
|
||||
this.$util.toast('回复成功')
|
||||
this.init()
|
||||
@@ -101,7 +102,9 @@ export default {
|
||||
})
|
||||
},
|
||||
open() {
|
||||
this.chatContent = ''
|
||||
this.$refs.inputDialog.open()
|
||||
|
||||
},
|
||||
over() {
|
||||
},
|
||||
|
||||
@@ -190,6 +190,6 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,286 +1,286 @@
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view class="detail" slot="body">
|
||||
<view class="detail-content" style="font-size: 32rpx">
|
||||
<!-- <view class="detail-content-title mb20">发生时间</view> -->
|
||||
<view>{{ detail.date }}</view>
|
||||
</view>
|
||||
<view class="detail-content" style="padding-top: 0px;padding-bottom: 0px">
|
||||
<view class="detail-content-title pb20 pt20 pl20">终端告警列表</view>
|
||||
</view>
|
||||
|
||||
<view class="event-list">
|
||||
<uni-card class="event-item" :class="item.type" v-for="(item, index) in list" :key="index">
|
||||
<!-- 头部:图标 + 信息 + 操作 -->
|
||||
<view class="event-header">
|
||||
<view class="event-icon"
|
||||
:class="item.devType == 'Direct_Connected_Device' ? 'zl-bgc' : 'jc-bgc'">
|
||||
|
||||
<Cn-icon-transient :name="item.devType == 'Direct_Connected_Device' ? '治理设备' : '监测设备'" />
|
||||
<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>
|
||||
<text class="event-tag"
|
||||
:class="item.devType == 'Direct_Connected_Device' ? 'zl-tag' : 'jc-tag'">{{
|
||||
item.devType == 'Direct_Connected_Device' ? '治理设备' : '监测设备' }}</text>
|
||||
</view>
|
||||
<view class="event-desc">
|
||||
<text>工程:{{ item.engineeringName }}</text>
|
||||
<text>项目:{{ item.projectName }}</text>
|
||||
<!-- <text v-if="item.dataDetails.onlineRate.isAbnormal">在线率:{{
|
||||
item.dataDetails.onlineRate.value }}% 限值:{{ item.dataDetails.onlineRate.threshold
|
||||
}}% </text> -->
|
||||
<!-- <text>事件时间:{{ item.startTime }}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
<view v-if="item.dataDetails.onlineRate.isAbnormal">
|
||||
<text>在线率:
|
||||
<text class="integrity-value">{{ item.dataDetails.onlineRate.value }}%</text>
|
||||
</text>
|
||||
|
||||
</view>
|
||||
<view v-if="hasIntegrityAbnormal(item)" class="mt10">
|
||||
数据完整性:
|
||||
<view class="integrity-grid">
|
||||
<view
|
||||
v-for="(rowItems, rowIdx) in chunkedPoints(getAbnormalPoints(item))"
|
||||
:key="rowIdx"
|
||||
class="grid-row">
|
||||
<view
|
||||
v-for="(point, pIdx) in rowItems"
|
||||
:key="pIdx"
|
||||
class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ point.monitorName }}</text>
|
||||
</view>
|
||||
<view class="integrity-value-row">
|
||||
<text class="integrity-value">{{ point.value }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="item.warnCounts" class="mt10 ">
|
||||
终端告警 {{ item.warnCounts }} 次,详情如下:
|
||||
<view class="textBox mt10">
|
||||
<view v-for="val in item.warnDetails" class="textBox mb5" style=" font-size: 26rpx;">
|
||||
{{ val.warnEventTime + '发生' + val.warnEventDesc }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
import { updateStatus, queryAlarmDetail } from '@/common/api/message'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
detail: {},
|
||||
limit: '',
|
||||
collapseValue: '0',
|
||||
|
||||
list: [],
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.loading = true
|
||||
this.detail = JSON.parse(decodeURIComponent(options.detail).replace(/百分比/g, '%'))
|
||||
this.init()
|
||||
if (this.detail.isRead != 1) {
|
||||
updateStatus({
|
||||
eventIds: [this.detail.eventId],
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hasIntegrityAbnormal(item) {
|
||||
const points = item?.dataDetails?.integrity?.monitorPoints
|
||||
if (!Array.isArray(points) || !points.length) return false
|
||||
return points.some((p) => p.isAbnormal === true)
|
||||
},
|
||||
getAbnormalPoints(item) {
|
||||
return item?.dataDetails?.integrity?.monitorPoints?.filter((p) => p.isAbnormal === true) || []
|
||||
},
|
||||
chunkedPoints(points) {
|
||||
const result = []
|
||||
for (let i = 0; i < points.length; i += 3) {
|
||||
result.push(points.slice(i, i + 3))
|
||||
}
|
||||
return result
|
||||
},
|
||||
init() {
|
||||
queryAlarmDetail({
|
||||
devList: this.detail.devIds,
|
||||
time: this.detail.date,
|
||||
})
|
||||
.then((res) => {
|
||||
this.list = res.data
|
||||
this.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '../index.scss';
|
||||
|
||||
.detail {
|
||||
padding: 20rpx 0;
|
||||
|
||||
.detail-content {
|
||||
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
.detail-content-title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.collapseTop {
|
||||
padding: 10rpx 0;
|
||||
margin-left: 15px;
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.frequency {
|
||||
display: flex;
|
||||
font-size: 28rpx;
|
||||
// color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.textBox {
|
||||
// border-bottom: 1px solid #eee;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
.event-list {
|
||||
// background: #fff;
|
||||
padding-bottom: 10rpx;
|
||||
|
||||
// .event-icon {
|
||||
// background-color: #376cf320;
|
||||
// }
|
||||
.zl-bgc {
|
||||
background-color: #376cf320;
|
||||
}
|
||||
|
||||
.jc-bgc {
|
||||
background-color: #376cf320;
|
||||
}
|
||||
|
||||
.zl-tag {
|
||||
background-color: #007aff20;
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
.jc-tag {
|
||||
background-color: #007aff20;
|
||||
color: #007aff;
|
||||
}
|
||||
}
|
||||
|
||||
/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;
|
||||
}
|
||||
}
|
||||
|
||||
.textBox {
|
||||
max-height: 150rpx;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.integrity-grid {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.grid-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.param-group {
|
||||
min-width: 0;
|
||||
background: #f3f3f3;
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 8rpx 12rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.param-title {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
// margin-bottom: 8rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.integrity-value-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 2rpx;
|
||||
}
|
||||
|
||||
.integrity-value {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
}
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view class="detail" slot="body">
|
||||
<view class="detail-content" style="font-size: 32rpx">
|
||||
<!-- <view class="detail-content-title mb20">发生时间</view> -->
|
||||
<view>{{ detail.date }}</view>
|
||||
</view>
|
||||
<view class="detail-content" style="padding-top: 0px;padding-bottom: 0px">
|
||||
<view class="detail-content-title pb20 pt20 pl20">终端告警列表</view>
|
||||
</view>
|
||||
|
||||
<view class="event-list">
|
||||
<uni-card class="event-item" :class="item.type" v-for="(item, index) in list" :key="index">
|
||||
<!-- 头部:图标 + 信息 + 操作 -->
|
||||
<view class="event-header">
|
||||
<view class="event-icon"
|
||||
:class="item.devType == 'Direct_Connected_Device' ? 'zl-bgc' : 'jc-bgc'">
|
||||
|
||||
<Cn-icon-transient :name="item.devType == 'Direct_Connected_Device' ? '治理设备' : '监测设备'" />
|
||||
<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>
|
||||
<text class="event-tag"
|
||||
:class="item.devType == 'Direct_Connected_Device' ? 'zl-tag' : 'jc-tag'">{{
|
||||
item.devType == 'Direct_Connected_Device' ? '治理设备' : '监测设备' }}</text>
|
||||
</view>
|
||||
<view class="event-desc">
|
||||
<text>工程:{{ item.engineeringName }}</text>
|
||||
<text>项目:{{ item.projectName }}</text>
|
||||
<!-- <text v-if="item.dataDetails.onlineRate.isAbnormal">在线率:{{
|
||||
item.dataDetails.onlineRate.value }}% 限值:{{ item.dataDetails.onlineRate.threshold
|
||||
}}% </text> -->
|
||||
<!-- <text>事件时间:{{ item.startTime }}</text> -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 详情区域 -->
|
||||
<view class="event-detail">
|
||||
<view v-if="item.dataDetails.onlineRate.isAbnormal">
|
||||
<text>在线率:
|
||||
<text class="integrity-value">{{ item.dataDetails.onlineRate.value }}%</text>
|
||||
</text>
|
||||
|
||||
</view>
|
||||
<view v-if="hasIntegrityAbnormal(item)" class="mt10">
|
||||
数据完整性:
|
||||
<view class="integrity-grid">
|
||||
<view
|
||||
v-for="(rowItems, rowIdx) in chunkedPoints(getAbnormalPoints(item))"
|
||||
:key="rowIdx"
|
||||
class="grid-row">
|
||||
<view
|
||||
v-for="(point, pIdx) in rowItems"
|
||||
:key="pIdx"
|
||||
class="param-group">
|
||||
<view class="param-title">
|
||||
<text>{{ point.monitorName }}</text>
|
||||
</view>
|
||||
<view class="integrity-value-row">
|
||||
<text class="integrity-value">{{ point.value }}%</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="item.warnCounts" class="mt10 ">
|
||||
终端告警 {{ item.warnCounts }} 次,详情如下:
|
||||
<view class="textBox mt10">
|
||||
<view v-for="val in item.warnDetails" class="textBox mb5" style=" font-size: 26rpx;">
|
||||
{{ val.warnEventTime + '发生' + val.warnEventDesc }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
import { updateStatus, queryAlarmDetail } from '@/common/api/message'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
detail: {},
|
||||
limit: '',
|
||||
collapseValue: '0',
|
||||
|
||||
list: [],
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.loading = true
|
||||
this.detail = JSON.parse(decodeURIComponent(options.detail).replace(/百分比/g, '%'))
|
||||
this.init()
|
||||
if (this.detail.isRead != 1) {
|
||||
updateStatus({
|
||||
eventIds: [this.detail.eventId],
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hasIntegrityAbnormal(item) {
|
||||
const points = item?.dataDetails?.integrity?.monitorPoints
|
||||
if (!Array.isArray(points) || !points.length) return false
|
||||
return points.some((p) => p.isAbnormal === true)
|
||||
},
|
||||
getAbnormalPoints(item) {
|
||||
return item?.dataDetails?.integrity?.monitorPoints?.filter((p) => p.isAbnormal === true) || []
|
||||
},
|
||||
chunkedPoints(points) {
|
||||
const result = []
|
||||
for (let i = 0; i < points.length; i += 3) {
|
||||
result.push(points.slice(i, i + 3))
|
||||
}
|
||||
return result
|
||||
},
|
||||
init() {
|
||||
queryAlarmDetail({
|
||||
devList: this.detail.devIds,
|
||||
time: this.detail.date,
|
||||
})
|
||||
.then((res) => {
|
||||
this.list = res.data
|
||||
this.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '../index.scss';
|
||||
|
||||
.detail {
|
||||
padding: 20rpx 0;
|
||||
|
||||
.detail-content {
|
||||
|
||||
padding: 20rpx;
|
||||
background: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
.detail-content-title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.collapseTop {
|
||||
padding: 10rpx 0;
|
||||
margin-left: 15px;
|
||||
|
||||
.name {
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
.frequency {
|
||||
display: flex;
|
||||
font-size: 28rpx;
|
||||
// color: #666666;
|
||||
}
|
||||
}
|
||||
|
||||
.textBox {
|
||||
// border-bottom: 1px solid #eee;
|
||||
font-size: 28rpx;
|
||||
color: #666666;
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
.event-list {
|
||||
// background: #fff;
|
||||
padding-bottom: 10rpx;
|
||||
|
||||
// .event-icon {
|
||||
// background-color: #376cf320;
|
||||
// }
|
||||
.zl-bgc {
|
||||
background-color: #376cf320;
|
||||
}
|
||||
|
||||
.jc-bgc {
|
||||
background-color: #376cf320;
|
||||
}
|
||||
|
||||
.zl-tag {
|
||||
background-color: #007aff20;
|
||||
color: #007aff;
|
||||
}
|
||||
|
||||
.jc-tag {
|
||||
background-color: #007aff20;
|
||||
color: #007aff;
|
||||
}
|
||||
}
|
||||
|
||||
/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;
|
||||
}
|
||||
}
|
||||
|
||||
.textBox {
|
||||
max-height: 150rpx;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.integrity-grid {
|
||||
margin-top: 16rpx;
|
||||
}
|
||||
|
||||
.grid-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.param-group {
|
||||
min-width: 0;
|
||||
background: #f3f3f3;
|
||||
border-radius: 16rpx;
|
||||
padding: 16rpx 8rpx 12rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.param-title {
|
||||
font-size: 24rpx;
|
||||
color: #666666;
|
||||
// margin-bottom: 8rpx;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.integrity-value-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 2rpx;
|
||||
}
|
||||
|
||||
.integrity-value {
|
||||
font-size: 26rpx;
|
||||
font-weight: 700;
|
||||
color: #333333;
|
||||
}
|
||||
</style>
|
||||
@@ -28,7 +28,7 @@
|
||||
<text v-if="!item.harmDetailList[0].hasT">A相</text>
|
||||
<text v-if="!item.harmDetailList[0].hasT">B相</text>
|
||||
<text v-if="!item.harmDetailList[0].hasT">C相</text>
|
||||
<text v-if="item.harmDetailList[0].hasT">总相</text>
|
||||
<text v-if="item.harmDetailList[0].hasT">总</text>
|
||||
<text>限值</text>
|
||||
</view>
|
||||
<view class="table-row" v-for="value in item.harmDetailList">
|
||||
|
||||
@@ -4,17 +4,21 @@
|
||||
<view class="detail-content" style="font-size: 32rpx">
|
||||
<view>{{ detail.startTime }}</view>
|
||||
</view>
|
||||
<view class="detail-content">
|
||||
<view class="detail-content ">
|
||||
<view class="detail-content-title mb20">基础信息</view>
|
||||
|
||||
<view class="mb5"> 工程:{{ detail.engineeringName }} </view>
|
||||
<view class="mb5"> 项目:{{ detail.projectName }} </view>
|
||||
<view class="mb5"> 设备:{{ detail.equipmentName }}</view>
|
||||
<view class="mb5"> 监测点:{{ detail.lineName }}</view>
|
||||
<view class="mb5"> 暂态类型:{{ detail.showName }}</view>
|
||||
<view class="mb5" v-if="detail.evtParamPhase"> 相别:{{ detail.evtParamPhase }}</view>
|
||||
<view class="mb5" v-if="detail.evtParamTm"> 持续时间:{{ detail.evtParamTm }}s</view>
|
||||
<view class="mb5" v-if="detail.evtParamVVaDepth"> 幅值:{{ detail.evtParamVVaDepth }}%</view>
|
||||
<view class="mb5" v-if="detail.evtParamPhase"> 相别:{{ detail.evtParamPhase }}</view>
|
||||
<view class="mb5" > 落点区域:{{ detail.landPoint != null && detail.landPoint !== '' ? detail.landPoint : '未知' }}</view>
|
||||
<view class="mb5"> 落点区域:{{ detail.landPoint != null && detail.landPoint !== '' ? detail.landPoint :
|
||||
'未知'
|
||||
}}</view>
|
||||
|
||||
</view>
|
||||
<view class="detail-tabs">
|
||||
<uni-segmented-control :current="detailTab" active-color="#376cf3" :values="['波形图', 'ITIC', 'F47']"
|
||||
@@ -60,6 +64,7 @@ import F47 from './F47.vue'
|
||||
import waveform from './waveform.vue'
|
||||
import { analyseWave } from '@/common/api/harmonic.js';
|
||||
|
||||
|
||||
export default {
|
||||
components: { ITIC, F47, waveform },
|
||||
data() {
|
||||
@@ -190,25 +195,9 @@ export default {
|
||||
font-size: 28rpx;
|
||||
|
||||
.detail-content-title {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-left: 20rpx;
|
||||
font-size: 30rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 8rpx;
|
||||
height: 28rpx;
|
||||
background: $uni-theme-color;
|
||||
border-radius: 3rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,4 +222,23 @@ export default {
|
||||
margin-right: 24rpx;
|
||||
height: 60rpx;
|
||||
}
|
||||
|
||||
/deep/ .segmented-control__text {
|
||||
line-height: 60rpx !important;
|
||||
}
|
||||
|
||||
.detail-content-info {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
// .detail-content-info {
|
||||
// display: grid;
|
||||
// grid-template-columns: 1fr 1fr;
|
||||
// }
|
||||
|
||||
.detail-content-info {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
</style>
|
||||
@@ -76,11 +76,11 @@
|
||||
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
/* 电压暂降 - 蓝色系 */
|
||||
/* 暂降 - 蓝色系 */
|
||||
.sag .event-icon {
|
||||
background-color: #2563eb20;
|
||||
}
|
||||
/* 电压暂升 - 橙色系 */
|
||||
/* 暂升 - 橙色系 */
|
||||
.swell .event-icon {
|
||||
background-color: #e6a23c20;
|
||||
}
|
||||
|
||||
@@ -186,7 +186,7 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -337,7 +337,7 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.textBox {
|
||||
@@ -371,17 +371,23 @@ export default {
|
||||
}
|
||||
|
||||
/deep/ .uni-calendar-item__weeks-box-text {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/deep/ .uni-calendar-item--isDay-text {
|
||||
color: #333 !important; /* 改成你想要的颜色 */
|
||||
/deep/ .uni-calendar-item__weeks-box-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/deep/ .uni-calendar-item__weeks-box-circle {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: 6px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 39px;
|
||||
height: 39px;
|
||||
border-radius: 50%;
|
||||
@@ -389,9 +395,13 @@ export default {
|
||||
background-color: #e6a23c;
|
||||
}
|
||||
|
||||
/* 核心:选中圆圈下的 子元素(日期数字) */
|
||||
/* 选中圆圈下的日期数字 */
|
||||
/deep/ .uni-calendar-item__weeks-box-circle + .uni-calendar-item__weeks-box-text {
|
||||
color: #fff !important; /* 改成你想要的颜色 */
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/deep/ .uni-calendar-item--isDay-text {
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
/deep/ .uni-calendar__backtoday,
|
||||
@@ -421,9 +431,9 @@ export default {
|
||||
}
|
||||
|
||||
/deep/ .uni-calendar-item__weeks-box-circle {
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 8px;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
}
|
||||
|
||||
@@ -59,8 +59,8 @@
|
||||
<text>
|
||||
{{ item.startTime ? '发生时间:' + item.startTime : '' }}
|
||||
{{
|
||||
item.evtParamVVaDepth != null && item.evtParamVVaDepth !== ''
|
||||
? ',幅值:' + item.evtParamVVaDepth + '%'
|
||||
item.evtParamPhase != null && item.evtParamPhase !== ''
|
||||
? ',相别:' + item.evtParamPhase
|
||||
: ''
|
||||
}}
|
||||
{{
|
||||
@@ -69,10 +69,12 @@
|
||||
: ''
|
||||
}}
|
||||
{{
|
||||
item.evtParamPhase != null && item.evtParamPhase !== ''
|
||||
? ',相别:' + item.evtParamPhase
|
||||
item.evtParamVVaDepth != null && item.evtParamVVaDepth !== ''
|
||||
? ',幅值:' + item.evtParamVVaDepth + '%'
|
||||
: ''
|
||||
}} {{
|
||||
}}
|
||||
|
||||
{{
|
||||
item.landPoint != null && item.landPoint !== ''
|
||||
? ',落点区域:' + item.landPoint
|
||||
: ',落点区域:未知'
|
||||
@@ -115,9 +117,9 @@ export default {
|
||||
filterValue: 0,
|
||||
dataList: [
|
||||
{ value: 0, label: '暂态数量', key: '' },
|
||||
{ value: 0, label: '暂降', key: '电压暂降' },
|
||||
{ value: 0, label: '中断', key: '电压中断' },
|
||||
{ value: 0, label: '暂升', key: '电压暂升' },
|
||||
{ value: 0, label: '暂降', key: '暂降' },
|
||||
{ value: 0, label: '中断', key: '中断' },
|
||||
{ value: 0, label: '暂升', key: '暂升' },
|
||||
],
|
||||
status: 'noMore', //more加载前 loading加载中 noMore加载后
|
||||
sort: 0,
|
||||
@@ -177,21 +179,21 @@ export default {
|
||||
},
|
||||
judgment(val, key) {
|
||||
switch (val) {
|
||||
case '电压暂降':
|
||||
case '暂降':
|
||||
return {
|
||||
type: 'sag',
|
||||
icon: 'icon-a-svg4',
|
||||
color: '#2563eb',
|
||||
size: '25',
|
||||
}
|
||||
case '电压暂升':
|
||||
case '暂升':
|
||||
return {
|
||||
type: 'swell',
|
||||
icon: 'icon-a-svg5',
|
||||
color: '#e6a23c',
|
||||
size: '25',
|
||||
}
|
||||
case '电压中断':
|
||||
case '中断':
|
||||
return {
|
||||
type: 'interrupt',
|
||||
icon: 'icon-zhongduan2',
|
||||
@@ -287,6 +289,6 @@ export default {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 4rpx 16rpx rgba(55, 108, 243, 0.35);
|
||||
z-index: 99;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,85 +1,85 @@
|
||||
<template>
|
||||
<Cn-page :loading='loading'>
|
||||
<view slot='body'>
|
||||
<view class='index'>
|
||||
<view class="content" v-for="(item, index) in formData" :key="index">
|
||||
<uni-forms>
|
||||
<uni-forms-item label="类型">
|
||||
<uni-data-select v-model="item.type" :localdata="range"></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="区域">
|
||||
<uni-easyinput type="textarea" v-model="item.title" placeholder="请输入问题简要" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="描述">
|
||||
<uni-easyinput type="textarea" v-model="item.des" placeholder="请输入详细描述" />
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item " @click="submit"> 提交 </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
formData: [
|
||||
{
|
||||
title: '',
|
||||
des: '',
|
||||
}
|
||||
],
|
||||
range: [
|
||||
{ value: 0, text: "需求" },
|
||||
{ value: 1, text: "缺陷" },
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add () {
|
||||
this.formData.push({
|
||||
type: '',
|
||||
address: '',
|
||||
})
|
||||
},
|
||||
submit () {
|
||||
console.log(this.formData)
|
||||
uni.navigateBack({ delta: 1 })
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.index {
|
||||
padding: 20rpx;
|
||||
|
||||
.content {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
<template>
|
||||
<Cn-page :loading='loading'>
|
||||
<view slot='body'>
|
||||
<view class='index'>
|
||||
<view class="content" v-for="(item, index) in formData" :key="index">
|
||||
<uni-forms>
|
||||
<uni-forms-item label="类型">
|
||||
<uni-data-select v-model="item.type" :localdata="range"></uni-data-select>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="区域">
|
||||
<uni-easyinput type="textarea" v-model="item.title" placeholder="请输入区域" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="描述">
|
||||
<uni-easyinput type="textarea" v-model="item.des" placeholder="请输入详细描述" />
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item " @click="submit"> 提交 </view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
formData: [
|
||||
{
|
||||
title: '',
|
||||
des: '',
|
||||
}
|
||||
],
|
||||
range: [
|
||||
{ value: 0, text: "需求" },
|
||||
{ value: 1, text: "缺陷" },
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
add () {
|
||||
this.formData.push({
|
||||
type: '',
|
||||
address: '',
|
||||
})
|
||||
},
|
||||
submit () {
|
||||
console.log(this.formData)
|
||||
uni.navigateBack({ delta: 1 })
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.index {
|
||||
padding: 20rpx;
|
||||
|
||||
.content {
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -48,7 +48,7 @@
|
||||
<!-- @click="jump('about')" -->
|
||||
<view class="mine-nav" style="border-bottom: none">
|
||||
<view class="mine-nav-label">版本信息</view>
|
||||
<view style="color: #828282; font-size: 14rpx">当前版本V{{ version }}</view>
|
||||
<view style="color: #828282; font-size: 24rpx">V{{ version }}</view>
|
||||
<!-- <uni-icons type="forward" color="#aaa" size="20"></uni-icons> -->
|
||||
</view>
|
||||
<view class="mine-nav" @click="jump('layout')" style="margin-top: 20rpx; border-bottom: none">
|
||||
|
||||
@@ -1,41 +1,25 @@
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<Cn-page>
|
||||
<view class="mine" slot="body">
|
||||
<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" style="border-bottom: none" v-if="flag">
|
||||
<view class="mine-nav-label">运行告警</view>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('alarmInfo')"
|
||||
:checked="config.alarmInfo === 1"
|
||||
/>
|
||||
<switch style="transform: scale(0.8)" color="#376cf3" @change="change('alarmInfo')"
|
||||
:checked="config.alarmInfo === 1" />
|
||||
</view>
|
||||
<view class="mine-nav" >
|
||||
<view class="mine-nav" v-if="flag">
|
||||
<view class="mine-nav-label">运行事件</view>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('runInfo')"
|
||||
:checked="config.runInfo === 1"
|
||||
/>
|
||||
<switch style="transform: scale(0.8)" color="#376cf3" @change="change('runInfo')"
|
||||
:checked="config.runInfo === 1" />
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
@@ -49,6 +33,7 @@ export default {
|
||||
return {
|
||||
loading: true,
|
||||
config: {},
|
||||
flag: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -100,12 +85,18 @@ export default {
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
updatePushConfig(this.config).then((res) => {
|
||||
// this.$util.toast(`配置修改成功!`)
|
||||
})
|
||||
if (this.config.eventInfo != undefined) {
|
||||
updatePushConfig(this.config).then((res) => {
|
||||
// this.$util.toast(`配置修改成功!`)
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
if (uni.getStorageSync(this.$cacheKey.userInfo).authorities === 'operation_manager') {
|
||||
this.flag = true
|
||||
}
|
||||
this.init()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view class="mine" slot="body">
|
||||
<view class="mine-nav" style="margin-top: 20rpx">
|
||||
<view class="mine-nav-label">ITIC</view>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('iticFunction')"
|
||||
:checked="config.iticFunction === 1"
|
||||
/>
|
||||
</view>
|
||||
<view class="mine-nav" style="border-bottom: none">
|
||||
<view class="mine-nav-label">F47</view>
|
||||
<switch
|
||||
style="transform: scale(0.8)"
|
||||
color="#376cf3"
|
||||
@change="change('f47Function')"
|
||||
:checked="config.f47Function === 1"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { queryUserPushConfig, updatePushConfig } from '@/common/api/mine'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
config: {},
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
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 ? '开启' : '关闭'}成功`)
|
||||
// })
|
||||
},
|
||||
},
|
||||
onLoad() {
|
||||
this.init()
|
||||
},
|
||||
onUnload() {
|
||||
updatePushConfig(this.config).then((res) => {
|
||||
// this.$util.toast(`配置修改成功!`)
|
||||
})
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.mine {
|
||||
.title {
|
||||
padding: 0 20rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.mine-header {
|
||||
padding: 200rpx 34rpx 34rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: $uni-theme-white;
|
||||
margin-bottom: 20rpx;
|
||||
box-shadow: 0 4rpx 8rpx #e7e7e74c;
|
||||
|
||||
.mine-header-head {
|
||||
margin-right: 30rpx;
|
||||
height: 128rpx;
|
||||
width: 128rpx;
|
||||
border-radius: $uni-theme-radius;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.mine-header-name {
|
||||
margin-right: 30rpx;
|
||||
flex: 1;
|
||||
font-size: 36rpx;
|
||||
color: #111;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.mine-nav {
|
||||
padding: 34rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: $uni-theme-white;
|
||||
border-bottom: 1rpx solid #e8e8e8;
|
||||
|
||||
&-icon {
|
||||
margin-right: 30rpx;
|
||||
height: 44rpx;
|
||||
width: 44rpx;
|
||||
border-radius: $uni-theme-radius;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&-label {
|
||||
margin-right: 30rpx;
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
color: #111;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,77 +1,77 @@
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view slot="body">
|
||||
<view class="index">
|
||||
<uni-card
|
||||
title="设备信息"
|
||||
sub-title="副标题"
|
||||
v-for="item in 3"
|
||||
:key="item"
|
||||
thumbnail="/static/real_time_data.png"
|
||||
>
|
||||
<view class="footer">
|
||||
<text>设备基础信息 </text>
|
||||
<view class="footer-btn" @click="del">移除</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
<uni-load-more status="nomore"></uni-load-more>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
del() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要移除该设备权限吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定')
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消')
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
newDevice() {
|
||||
uni.scanCode({
|
||||
onlyFromCamera: true,
|
||||
success: function (res) {
|
||||
console.log('条码类型:' + res.scanType)
|
||||
console.log('条码内容:' + res.result)
|
||||
uni.navigateTo({
|
||||
url: '/pages/gateway/newDevice',
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.index {
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.footer-btn {
|
||||
padding: 0 20rpx;
|
||||
height: 50rpx;
|
||||
background-color: #e47470;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 50rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view slot="body">
|
||||
<view class="index">
|
||||
<uni-card
|
||||
title="设备信息"
|
||||
sub-title="副标题"
|
||||
v-for="item in 3"
|
||||
:key="item"
|
||||
thumbnail="/static/real_time_data.png"
|
||||
>
|
||||
<view class="footer">
|
||||
<text>设备基础信息 </text>
|
||||
<view class="footer-btn" @click="del">移除</view>
|
||||
</view>
|
||||
</uni-card>
|
||||
<uni-load-more status="nomore"></uni-load-more>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
del() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要移除该设备权限吗?',
|
||||
success: function (res) {
|
||||
if (res.confirm) {
|
||||
console.log('用户点击确定')
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消')
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
newDevice() {
|
||||
uni.scanCode({
|
||||
onlyFromCamera: false,
|
||||
success: function (res) {
|
||||
console.log('条码类型:' + res.scanType)
|
||||
console.log('条码内容:' + res.result)
|
||||
uni.navigateTo({
|
||||
url: '/pages/gateway/newDevice',
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.index {
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.footer-btn {
|
||||
padding: 0 20rpx;
|
||||
height: 50rpx;
|
||||
background-color: #e47470;
|
||||
font-size: 24rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 50rpx;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,464 +1,444 @@
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view slot="body">
|
||||
<view class="new" :class="{'project-new':!this.options.project}">
|
||||
<view class="content">
|
||||
<uni-forms :label-width="80">
|
||||
<uni-forms-item label="工程名称" @click.native.stop.prevent="selectEngineering">
|
||||
<uni-easyinput
|
||||
v-model="formData.engineeringName"
|
||||
placeholder="请选择工程"
|
||||
:clearable="false"
|
||||
:disabled="true"
|
||||
/>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="项目名称">
|
||||
<uni-easyinput v-model="formData.name" placeholder="请输入项目名称"/>
|
||||
</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="描述">
|
||||
<uni-easyinput
|
||||
type="textarea"
|
||||
autoHeight
|
||||
maxlength="999"
|
||||
v-model="formData.description"
|
||||
placeholder="请输入项目描述"
|
||||
/>
|
||||
</uni-forms-item>
|
||||
<view class="temp-choose">
|
||||
<view class="temp-choose-title">从模版库选择拓扑图</view>
|
||||
<view class="temp-choose-content">
|
||||
<view class="temp-choose-content-item" v-for="(item, index) in formData.tempFiles">
|
||||
<image
|
||||
class="temp-choose-content-item-img"
|
||||
:src="item.filePath"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view class="temp-choose-content-item-close" @click="deleteImg(index)">
|
||||
<uni-icons style="font-size: 18px" type="closeempty" color="#fff" size="20"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="temp-choose-content-item" @click="openTemp">
|
||||
<uni-icons type="plusempty" size="70" color="#f1f1f1"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-file-picker
|
||||
v-model="formData.files"
|
||||
title="从本地上传拓扑图"
|
||||
:sourceType="['album']"
|
||||
:before-remove="beforeRemove"
|
||||
@select="select"
|
||||
></uni-file-picker>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="submit"> 提交</view>
|
||||
</view>
|
||||
<uni-popup ref="showTemp" type="bottom" :mask-click="false">
|
||||
<view class="popup-header">
|
||||
<view class="popup-header-title">模版库</view>
|
||||
<view class="popup-header-close" @click="closeTemp">
|
||||
<uni-icons type="closeempty" color="#111" size="20"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="temp-list">
|
||||
<view
|
||||
class="temp-list-item"
|
||||
:class="{
|
||||
'temp-list-item-active': formData.tempFiles.some(
|
||||
(item2) => item2.id === item.id || item2.topoId === item.id,
|
||||
),
|
||||
}"
|
||||
v-for="(item, index) in tempList"
|
||||
@click="chooseTempItem(item)"
|
||||
>
|
||||
<image class="temp-list-item-img" :src="item.filePath" mode="aspectFill"/>
|
||||
<view class="temp-list-item-name">{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
import {pinyin} from 'pinyin-pro'
|
||||
import {addAppProject, updateAppProject, checkCanDelete} from '../../common/api/project'
|
||||
import {getTopoTemplate} from '../../common/api/device'
|
||||
import {queryEngineering} from '@/common/api/engineering.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
formData: {
|
||||
engineeringId: '',
|
||||
engineeringName: '',
|
||||
area: '',
|
||||
files: [],
|
||||
tempFiles: [],
|
||||
topoIds: [],
|
||||
description: '',
|
||||
name: '',
|
||||
lat: '',
|
||||
lng: '',
|
||||
},
|
||||
tempList: [],
|
||||
project: null,
|
||||
options: {}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if (!this.options.project) {
|
||||
let engineering = uni.getStorageSync('onceSelectEngineering')
|
||||
if (engineering) {
|
||||
uni.removeStorageSync('onceSelectEngineering')
|
||||
this.formData.engineeringId = engineering.id
|
||||
this.formData.engineeringName = engineering.name
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.options = options
|
||||
if (options.project) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '编辑项目',
|
||||
})
|
||||
this.project = JSON.parse(decodeURIComponent(options.project))
|
||||
console.log(this.project)
|
||||
for (let key in this.formData) {
|
||||
if (this.project[key]) {
|
||||
this.formData[key] = this.project[key]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let engineering = uni.getStorageSync('engineering')
|
||||
this.formData.engineeringId = engineering.id
|
||||
this.formData.engineeringName = engineering.name
|
||||
}
|
||||
uni.getLocation({
|
||||
type: 'wgs84',
|
||||
success: function (res) {
|
||||
console.log(res)
|
||||
console.log('当前位置的经度:' + res.longitude)
|
||||
console.log('当前位置的纬度:' + res.latitude)
|
||||
},
|
||||
})
|
||||
getTopoTemplate().then((res) => {
|
||||
console.log(res)
|
||||
this.tempList = res.data.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
filePath:this.$config.static + item.filePath
|
||||
}
|
||||
})
|
||||
if (this.project) {
|
||||
this.project.topologyDiagramPaths.forEach((item) => {
|
||||
if (this.tempList.some((item2) => item2.id === item.topoId)) {
|
||||
this.formData.tempFiles.push(item)
|
||||
} else {
|
||||
this.formData.files.push({
|
||||
url: item.filePath,
|
||||
extname: item.name.split('.')[1],
|
||||
name: item.name,
|
||||
...item,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
selectEngineering() {
|
||||
console.log(123)
|
||||
if (this.options.project) return this.$util.toast('项目已经创建,不能修改工程')
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/selectEngineering?from=once',
|
||||
})
|
||||
},
|
||||
beforeRemove(e) {
|
||||
console.log(e)
|
||||
if (!e.tempFile.id) {
|
||||
return true
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
checkCanDelete(e.tempFile.id).then((res) => {
|
||||
console.log(res)
|
||||
if (res.data) {
|
||||
resolve(true)
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async deleteImg(index) {
|
||||
await this.beforeRemove({
|
||||
tempFile: this.formData.tempFiles[index],
|
||||
})
|
||||
this.formData.tempFiles.splice(index, 1)
|
||||
},
|
||||
async chooseTempItem(item) {
|
||||
console.log(item)
|
||||
console.log(this.formData.tempFiles)
|
||||
// 编辑的时候,如果已经存在就要验证topoId
|
||||
let index = this.formData.tempFiles.findIndex((item2) => item2.id === item.id || item2.topoId === item.id)
|
||||
if (index > -1) {
|
||||
await this.beforeRemove({
|
||||
tempFile: this.formData.tempFiles[index],
|
||||
})
|
||||
this.formData.tempFiles.splice(index, 1)
|
||||
} else {
|
||||
this.formData.tempFiles.push(item)
|
||||
}
|
||||
},
|
||||
closeTemp() {
|
||||
this.$refs.showTemp.close()
|
||||
},
|
||||
openTemp() {
|
||||
this.$refs.showTemp.open()
|
||||
},
|
||||
select(e) {
|
||||
console.log(e)
|
||||
this.formData.files.push(...e.tempFiles)
|
||||
console.log(this.formData.files)
|
||||
},
|
||||
// chooseLocation() {
|
||||
// uni.chooseLocation({
|
||||
// success: (res) => {
|
||||
// this.formData.area = res.name
|
||||
// this.formData.lat = res.latitudeame
|
||||
// this.formData.lng = res.longitude
|
||||
// console.log('位置名称:' + res.name)
|
||||
// console.log('详细地址:' + res.address)
|
||||
// console.log('纬度:' + res.latitude)
|
||||
// console.log('经度:' + res.longitude)
|
||||
// },
|
||||
// })
|
||||
// },
|
||||
async submit() {
|
||||
console.log(this.formData)
|
||||
if (!this.formData.name) {
|
||||
this.$util.toast('请输入项目名称')
|
||||
return
|
||||
}
|
||||
if (!this.formData.area) {
|
||||
this.$util.toast('请输入区域信息')
|
||||
return
|
||||
}
|
||||
if (!this.formData.description) {
|
||||
this.$util.toast('请输入项目描述')
|
||||
return
|
||||
}
|
||||
if (!this.formData.files.length && !this.formData.tempFiles.length) {
|
||||
this.$util.toast('请至少选择一张拓扑图')
|
||||
return
|
||||
}
|
||||
let arr = []
|
||||
for (let i = 0; i < this.formData.files.length; i++) {
|
||||
let item = this.formData.files[i]
|
||||
console.log(item)
|
||||
arr.push({
|
||||
...item,
|
||||
name: 'files',
|
||||
uri: item.url,
|
||||
})
|
||||
}
|
||||
console.log(arr)
|
||||
this.formData.topoIds = this.formData.tempFiles.map((item) => (item.id))
|
||||
let data = JSON.parse(JSON.stringify(this.formData))
|
||||
let res = {}
|
||||
console.warn(data, arr)
|
||||
if (this.project) {
|
||||
data.id = this.project.id
|
||||
data.newTopoIds = data.files.filter(item => item.id).map((item) => item.id)
|
||||
data.newTopoIds.push(...data.tempFiles.filter(item => item.id && item.topoId).map((item) => item.id))
|
||||
data.topoIds = data.tempFiles.filter(item => item.id && !item.topoId).map((item) => item.id)
|
||||
delete data.tempFiles
|
||||
delete data.files
|
||||
arr = arr.filter(item => !item.id)
|
||||
res = await updateAppProject(data, arr)
|
||||
} else {
|
||||
delete data.tempFiles
|
||||
delete data.files
|
||||
res = await addAppProject(data, arr)
|
||||
}
|
||||
let result = {}
|
||||
if (res.code === 'A0000') {
|
||||
result = res
|
||||
} else {
|
||||
console.warn(res)
|
||||
if (res.length === 1) {
|
||||
this.$util.toast(res[0].message)
|
||||
return
|
||||
}
|
||||
result = JSON.parse(res[1].data)
|
||||
}
|
||||
if (result.code === 'A0000') {
|
||||
if (this.project) {
|
||||
this.$util.toast('项目修改成功')
|
||||
this.$util.refreshPrePage(2)
|
||||
} else {
|
||||
if (this.options.from === 'newDevice') {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
this.$util.toast('项目创建成功')
|
||||
this.$util.refreshPrePage()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.$util.toast(result.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.project-new /deep/ .is-disabled {
|
||||
background: #fff !important;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.new {
|
||||
padding: 34rpx;
|
||||
|
||||
.project-new {
|
||||
|
||||
}
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.temp-choose {
|
||||
margin-bottom: 44rpx;
|
||||
|
||||
.temp-choose-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.temp-choose-content {
|
||||
margin-top: 20rpx;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 198rpx);
|
||||
grid-gap: 10rpx;
|
||||
|
||||
.temp-choose-content-item {
|
||||
box-sizing: border-box;
|
||||
border: 1px #eee solid;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 198rpx;
|
||||
|
||||
.temp-choose-content-item-img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: skyblue;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.temp-choose-content-item-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 2;
|
||||
height: 52rpx;
|
||||
width: 52rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.temp-list {
|
||||
box-sizing: border-box;
|
||||
width: 750rpx;
|
||||
height: 80vh;
|
||||
padding: 20rpx;
|
||||
overflow-y: scroll;
|
||||
background: #fff;
|
||||
|
||||
.temp-list-item {
|
||||
margin-bottom: 10rpx;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
border: 4px solid #f1f1f1;
|
||||
|
||||
.temp-list-item-img {
|
||||
height: 280rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.temp-list-item-name {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background: #fff;
|
||||
padding: 4rpx 8rpx;
|
||||
}
|
||||
|
||||
&-active {
|
||||
border: 4rpx solid $uni-theme-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<Cn-page :loading="loading">
|
||||
<view slot="body">
|
||||
<view class="new" :class="{ 'project-new': !this.options.project }">
|
||||
<view class="content">
|
||||
<uni-forms :label-width="80">
|
||||
<uni-forms-item label="工程名称">
|
||||
<view class="engineering-select" @click="selectEngineering">
|
||||
<uni-easyinput
|
||||
v-model="formData.engineeringName"
|
||||
disabled
|
||||
maxlength="50"
|
||||
placeholder="请选择工程"
|
||||
:clearable="false"
|
||||
/>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="项目名称">
|
||||
<uni-easyinput v-model="formData.name" maxlength="50" placeholder="请输入项目名称" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="区域">
|
||||
<view style="display: flex">
|
||||
<uni-easyinput :clearable="false" type="textarea" maxlength="250" 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="描述">
|
||||
<uni-easyinput type="textarea" autoHeight maxlength="999" v-model="formData.description"
|
||||
placeholder="请输入项目描述" />
|
||||
</uni-forms-item>
|
||||
<view class="temp-choose">
|
||||
<view class="temp-choose-title">从模版库选择拓扑图</view>
|
||||
<view class="temp-choose-content">
|
||||
<view class="temp-choose-content-item" v-for="(item, index) in formData.tempFiles">
|
||||
<image class="temp-choose-content-item-img" :src="item.filePath"
|
||||
mode="aspectFill" />
|
||||
<view class="temp-choose-content-item-close" @click="deleteImg(index)">
|
||||
<uni-icons style="font-size: 18px" type="closeempty" color="#fff" size="20" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="temp-choose-content-item" @click="openTemp">
|
||||
<uni-icons type="plusempty" size="70" color="#f1f1f1"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<uni-file-picker v-model="formData.files" title="从本地上传拓扑图" :sourceType="['album']"
|
||||
:before-remove="beforeRemove" @select="select"></uni-file-picker>
|
||||
</uni-forms>
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="submit"> 提交</view>
|
||||
</view>
|
||||
<uni-popup ref="showTemp" type="bottom" :mask-click="false">
|
||||
<view class="popup-header">
|
||||
<view class="popup-header-title">模版库</view>
|
||||
<view class="popup-header-close" @click="closeTemp">
|
||||
<uni-icons type="closeempty" color="#111" size="20" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="temp-list">
|
||||
<view class="temp-list-item" :class="{
|
||||
'temp-list-item-active': formData.tempFiles.some(
|
||||
(item2) => item2.id === item.id || item2.topoId === item.id,
|
||||
),
|
||||
}" v-for="(item, index) in tempList" @click="chooseTempItem(item)">
|
||||
<image class="temp-list-item-img" :src="item.filePath" mode="aspectFill" />
|
||||
<view class="temp-list-item-name">{{ item.name }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</view>
|
||||
</Cn-page>
|
||||
</template>
|
||||
<script>
|
||||
import { pinyin } from 'pinyin-pro'
|
||||
import { addAppProject, updateAppProject, checkCanDelete } from '../../common/api/project'
|
||||
import { getTopoTemplate } from '../../common/api/device'
|
||||
import { queryEngineering } from '@/common/api/engineering.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
formData: {
|
||||
engineeringId: '',
|
||||
engineeringName: '',
|
||||
area: '',
|
||||
files: [],
|
||||
tempFiles: [],
|
||||
topoIds: [],
|
||||
description: '',
|
||||
name: '',
|
||||
lat: '',
|
||||
lng: '',
|
||||
},
|
||||
tempList: [],
|
||||
project: null,
|
||||
options: {}
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
if (!this.options.project) {
|
||||
let engineering = uni.getStorageSync('onceSelectEngineering')
|
||||
if (engineering) {
|
||||
uni.removeStorageSync('onceSelectEngineering')
|
||||
this.formData.engineeringId = engineering.id
|
||||
this.formData.engineeringName = engineering.name
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
this.options = options
|
||||
if (options.project) {
|
||||
uni.setNavigationBarTitle({
|
||||
title: '编辑项目',
|
||||
})
|
||||
this.project = JSON.parse(decodeURIComponent(options.project))
|
||||
console.log(this.project)
|
||||
for (let key in this.formData) {
|
||||
if (this.project[key]) {
|
||||
this.formData[key] = this.project[key]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let engineering = uni.getStorageSync('engineering')
|
||||
this.formData.engineeringId = engineering.id
|
||||
this.formData.engineeringName = engineering.name
|
||||
}
|
||||
|
||||
getTopoTemplate().then((res) => {
|
||||
console.log(res)
|
||||
this.tempList = res.data.map((item) => {
|
||||
return {
|
||||
...item,
|
||||
filePath: this.$config.static + item.filePath
|
||||
}
|
||||
})
|
||||
if (this.project) {
|
||||
this.project.topologyDiagramPaths.forEach((item) => {
|
||||
if (this.tempList.some((item2) => item2.id === item.topoId)) {
|
||||
this.formData.tempFiles.push(item)
|
||||
} else {
|
||||
this.formData.files.push({
|
||||
url: item.filePath,
|
||||
extname: item.name.split('.')[1],
|
||||
name: item.name,
|
||||
...item,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
selectEngineering() {
|
||||
console.log(123)
|
||||
if (this.options.project) return this.$util.toast('项目已经创建,不能修改工程')
|
||||
uni.navigateTo({
|
||||
url: '/pages/home/selectEngineering?from=once',
|
||||
})
|
||||
},
|
||||
beforeRemove(e) {
|
||||
console.log(e)
|
||||
if (!e.tempFile.id) {
|
||||
return true
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
checkCanDelete(e.tempFile.id).then((res) => {
|
||||
console.log(res)
|
||||
if (res.data) {
|
||||
resolve(true)
|
||||
} else {
|
||||
reject()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async deleteImg(index) {
|
||||
await this.beforeRemove({
|
||||
tempFile: this.formData.tempFiles[index],
|
||||
})
|
||||
this.formData.tempFiles.splice(index, 1)
|
||||
},
|
||||
async chooseTempItem(item) {
|
||||
console.log(item)
|
||||
console.log(this.formData.tempFiles)
|
||||
// 编辑的时候,如果已经存在就要验证topoId
|
||||
let index = this.formData.tempFiles.findIndex((item2) => item2.id === item.id || item2.topoId === item.id)
|
||||
if (index > -1) {
|
||||
await this.beforeRemove({
|
||||
tempFile: this.formData.tempFiles[index],
|
||||
})
|
||||
this.formData.tempFiles.splice(index, 1)
|
||||
} else {
|
||||
this.formData.tempFiles.push(item)
|
||||
}
|
||||
},
|
||||
closeTemp() {
|
||||
this.$refs.showTemp.close()
|
||||
},
|
||||
openTemp() {
|
||||
this.$refs.showTemp.open()
|
||||
},
|
||||
select(e) {
|
||||
console.log(e)
|
||||
this.formData.files.push(...e.tempFiles)
|
||||
console.log(this.formData.files)
|
||||
},
|
||||
// chooseLocation() {
|
||||
// uni.chooseLocation({
|
||||
// success: (res) => {
|
||||
// this.formData.area = res.name
|
||||
// this.formData.lat = res.latitudeame
|
||||
// this.formData.lng = res.longitude
|
||||
// console.log('位置名称:' + res.name)
|
||||
// console.log('详细地址:' + res.address)
|
||||
// console.log('纬度:' + res.latitude)
|
||||
// console.log('经度:' + res.longitude)
|
||||
// },
|
||||
// })
|
||||
// },
|
||||
async submit() {
|
||||
console.log(this.formData)
|
||||
if (!this.formData.name) {
|
||||
this.$util.toast('请输入项目名称')
|
||||
return
|
||||
}
|
||||
if (!this.formData.area) {
|
||||
this.$util.toast('请输入区域信息')
|
||||
return
|
||||
}
|
||||
if (!this.formData.description) {
|
||||
this.$util.toast('请输入项目描述')
|
||||
return
|
||||
}
|
||||
if (!this.formData.files.length && !this.formData.tempFiles.length) {
|
||||
this.$util.toast('请至少选择一张拓扑图')
|
||||
return
|
||||
}
|
||||
let arr = []
|
||||
for (let i = 0; i < this.formData.files.length; i++) {
|
||||
let item = this.formData.files[i]
|
||||
console.log(item)
|
||||
arr.push({
|
||||
...item,
|
||||
name: 'files',
|
||||
uri: item.url,
|
||||
})
|
||||
}
|
||||
console.log(arr)
|
||||
this.formData.topoIds = this.formData.tempFiles.map((item) => (item.id))
|
||||
let data = JSON.parse(JSON.stringify(this.formData))
|
||||
let res = {}
|
||||
console.warn(data, arr)
|
||||
if (this.project) {
|
||||
data.id = this.project.id
|
||||
data.newTopoIds = data.files.filter(item => item.id).map((item) => item.id)
|
||||
data.newTopoIds.push(...data.tempFiles.filter(item => item.id && item.topoId).map((item) => item.id))
|
||||
data.topoIds = data.tempFiles.filter(item => item.id && !item.topoId).map((item) => item.id)
|
||||
delete data.tempFiles
|
||||
delete data.files
|
||||
arr = arr.filter(item => !item.id)
|
||||
res = await updateAppProject(data, arr)
|
||||
} else {
|
||||
delete data.tempFiles
|
||||
delete data.files
|
||||
res = await addAppProject(data, arr)
|
||||
}
|
||||
let result = {}
|
||||
if (res.code === 'A0000') {
|
||||
result = res
|
||||
} else {
|
||||
console.warn(res)
|
||||
if (res.length === 1) {
|
||||
this.$util.toast(res[0].message)
|
||||
return
|
||||
}
|
||||
result = JSON.parse(res[1].data)
|
||||
}
|
||||
if (result.code === 'A0000') {
|
||||
if (this.project) {
|
||||
this.$util.toast('项目修改成功')
|
||||
this.$util.refreshPrePage(2)
|
||||
} else {
|
||||
if (this.options.from === 'newDevice') {
|
||||
uni.navigateBack()
|
||||
} else {
|
||||
this.$util.toast('项目创建成功')
|
||||
this.$util.refreshPrePage()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.$util.toast(result.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.project-new /deep/ .is-disabled {
|
||||
background: #fff !important;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.engineering-select {
|
||||
width: 100%;
|
||||
|
||||
/deep/ .uni-easyinput,
|
||||
/deep/ .uni-easyinput__content {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.new {
|
||||
padding: 34rpx;
|
||||
|
||||
.project-new {}
|
||||
|
||||
.content {
|
||||
.content-des {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
margin-bottom: 20rpx;
|
||||
padding: 34rpx;
|
||||
background: $uni-theme-white;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
.btn-wrap {
|
||||
margin-top: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.btn-wrap-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 1;
|
||||
background: $uni-theme-color;
|
||||
color: #fff;
|
||||
height: 80rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.temp-choose {
|
||||
margin-bottom: 44rpx;
|
||||
|
||||
.temp-choose-title {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.temp-choose-content {
|
||||
margin-top: 20rpx;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 198rpx);
|
||||
grid-gap: 10rpx;
|
||||
|
||||
.temp-choose-content-item {
|
||||
box-sizing: border-box;
|
||||
border: 1px #eee solid;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 198rpx;
|
||||
|
||||
.temp-choose-content-item-img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: skyblue;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.temp-choose-content-item-close {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 2;
|
||||
height: 52rpx;
|
||||
width: 52rpx;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.temp-list {
|
||||
box-sizing: border-box;
|
||||
width: 750rpx;
|
||||
height: 80vh;
|
||||
padding: 20rpx;
|
||||
overflow-y: scroll;
|
||||
background: #fff;
|
||||
|
||||
.temp-list-item {
|
||||
margin-bottom: 10rpx;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
border: 4px solid #f1f1f1;
|
||||
|
||||
.temp-list-item-img {
|
||||
height: 280rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.temp-list-item-name {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
background: #fff;
|
||||
padding: 4rpx 8rpx;
|
||||
}
|
||||
|
||||
&-active {
|
||||
border: 4rpx solid $uni-theme-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .uni-drawer__content {
|
||||
width: 100vw !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<view slot="body">
|
||||
<view class="change-name">
|
||||
<view class="content">
|
||||
<uni-easyinput type="text" v-model="name" placeholder="请输入昵称" />
|
||||
<uni-easyinput type="text" maxlength="24" v-model="name" placeholder="请输入昵称" />
|
||||
</view>
|
||||
<view class="btn-wrap">
|
||||
<view class="btn-wrap-item" @click="submit"> 提交 </view>
|
||||
|
||||
@@ -4,33 +4,18 @@
|
||||
<view class="index">
|
||||
<uni-forms ref="form" :modelValue="formData" :rules="rules">
|
||||
<uni-forms-item name="phone">
|
||||
<uni-easyinput
|
||||
type="number"
|
||||
maxlength="11"
|
||||
v-model="formData.phone"
|
||||
placeholder="请输入手机号"
|
||||
/>
|
||||
<uni-easyinput type="number" maxlength="11" v-model="formData.phone" placeholder="请输入手机号" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item name="code">
|
||||
<view class="login-box-input">
|
||||
<uni-easyinput
|
||||
type="text"
|
||||
v-model="formData.code"
|
||||
placeholder="请输入验证码"
|
||||
maxlength="6"
|
||||
/>
|
||||
<view
|
||||
class="ml40"
|
||||
style="
|
||||
<uni-easyinput type="text" v-model="formData.code" placeholder="请输入验证码" maxlength="6" />
|
||||
<view class="ml40" style="
|
||||
margin-left: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
width: 200rpx;
|
||||
text-align: center;
|
||||
"
|
||||
v-if="waitTime > 0"
|
||||
>{{ waitTime + 's后重新获取' }}</view
|
||||
>
|
||||
" v-if="waitTime > 0">{{ waitTime + 's后重新获取' }}</view>
|
||||
<button class="login-box-input-btn" v-else @click="getCode" size="mini">获取验证码</button>
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
@@ -41,7 +26,8 @@
|
||||
<uni-easyinput type="password" v-model="formData.password2" placeholder="请再次确认密码" />
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
<button type="default" class="submit-btn" @click="submit">提交</button>
|
||||
<button type="default" class="submit-btn" :loading="loadingButton" :disabled="loadingButton"
|
||||
@click="submit">提交</button>
|
||||
<view class="login-box-tips">
|
||||
<view style="color: #999">说明:密码长度为6-18位</view>
|
||||
</view>
|
||||
@@ -71,6 +57,7 @@ export default {
|
||||
password: '',
|
||||
password2: '',
|
||||
},
|
||||
loadingButton: false,
|
||||
rules: {
|
||||
phone: {
|
||||
rules: [
|
||||
@@ -107,7 +94,7 @@ export default {
|
||||
},
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onLoad() { },
|
||||
methods: {
|
||||
getCode() {
|
||||
if (!this.formData.phone) {
|
||||
@@ -151,6 +138,7 @@ export default {
|
||||
})
|
||||
return
|
||||
}
|
||||
this.loadingButton = true
|
||||
let loginName = encrypt(this.formData.phone)
|
||||
gongkey({ loginName }).then((response) => {
|
||||
let publicKey = response.data
|
||||
@@ -169,9 +157,13 @@ export default {
|
||||
}, 1000)
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.hideLoading()
|
||||
console.log(err)
|
||||
})
|
||||
.finally(() => {
|
||||
this.loadingButton = false
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loadingButton = false
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
@@ -5,32 +5,18 @@
|
||||
<template v-if="step == 1">
|
||||
<uni-forms ref="form" :rules="rules" :modelValue="formData">
|
||||
<uni-forms-item name="phone">
|
||||
<uni-easyinput
|
||||
type="number"
|
||||
v-model="formData.phone"
|
||||
maxlength="11"
|
||||
placeholder="请输入手机号"
|
||||
/>
|
||||
<uni-easyinput type="number" v-model="formData.phone" maxlength="11" placeholder="请输入手机号" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item name="code">
|
||||
<view class="login-box-input">
|
||||
<uni-easyinput
|
||||
type="text"
|
||||
v-model="formData.code"
|
||||
placeholder="请输入验证码"
|
||||
maxlength="6"
|
||||
/>
|
||||
<view
|
||||
class="ml40"
|
||||
style="
|
||||
<uni-easyinput type="text" v-model="formData.code" placeholder="请输入验证码" maxlength="6" />
|
||||
<view class="ml40" style="
|
||||
margin-left: 40rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
width: 200rpx;
|
||||
text-align: center;
|
||||
"
|
||||
v-if="waitTime > 0"
|
||||
>{{ waitTime + 's后重新获取' }}
|
||||
" v-if="waitTime > 0">{{ waitTime + 's后重新获取' }}
|
||||
</view>
|
||||
<button class="login-box-input-btn" v-else @click="getCode" size="mini">
|
||||
获取验证码
|
||||
@@ -38,16 +24,13 @@
|
||||
</view>
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
<button type="default" class="submit-btn" @click="firstSubmit">注册</button>
|
||||
<button type="default" class="submit-btn" :loading="loadingButton" :disabled="loadingButton"
|
||||
@click="firstSubmit">注册</button>
|
||||
<view class="login-box-tips">
|
||||
<view style="color: #999"
|
||||
><checkbox
|
||||
style="transform: scale(0.7)"
|
||||
:checked="checkbox"
|
||||
@click="checkbox = !checkbox"
|
||||
/>
|
||||
我已阅读并同意</view
|
||||
>
|
||||
<view style="color: #999">
|
||||
<checkbox style="transform: scale(0.7)" :checked="checkbox" @click="checkbox = !checkbox" />
|
||||
我已阅读并同意
|
||||
</view>
|
||||
<navigator url="/pages/mine/agreement" hover-class="none">《用户协议》</navigator>
|
||||
<navigator url="/pages/mine/policy" hover-class="none">《隐私政策》</navigator>
|
||||
</view>
|
||||
@@ -61,7 +44,8 @@
|
||||
<uni-easyinput type="text" v-model="formData.password2" placeholder="请再次确认密码" />
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
<button type="default" class="submit-btn" @click="secondSubmit">提交</button>
|
||||
<button type="default" class="submit-btn" :loading="loadingButton" :disabled="loadingButton"
|
||||
@click="secondSubmit">提交</button>
|
||||
<view class="login-box-tips">
|
||||
<view style="color: #999">说明:密码长度为6-18位</view>
|
||||
</view>
|
||||
@@ -82,6 +66,7 @@ export default {
|
||||
loading: false,
|
||||
waitTime: 0,
|
||||
inter: null,
|
||||
loadingButton: false,
|
||||
// 表单数据
|
||||
formData: {
|
||||
phone: '',
|
||||
@@ -125,7 +110,7 @@ export default {
|
||||
},
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onLoad() { },
|
||||
methods: {
|
||||
getCode() {
|
||||
if (!this.checkbox) {
|
||||
@@ -163,7 +148,9 @@ export default {
|
||||
if (!this.checkbox) {
|
||||
return this.$util.toast('请先阅读并同意用户协议和隐私政策!')
|
||||
}
|
||||
|
||||
this.$refs.form.validate().then((valid, errors) => {
|
||||
this.loadingButton = true
|
||||
apiRegister({
|
||||
phone: this.formData.phone,
|
||||
code: this.formData.code,
|
||||
@@ -176,11 +163,14 @@ export default {
|
||||
autoLogin(this.formData.phone).then((res) => {
|
||||
this.$util.loginSuccess(res.data)
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loadingButton = false
|
||||
})
|
||||
})
|
||||
},
|
||||
secondSubmit() {
|
||||
this.$refs.form.validate().then((valid, errors) => {
|
||||
this.loadingButton = true
|
||||
console.log(this.formData.password.length)
|
||||
if (this.formData.password.length < 6 || this.formData.password.length > 18) {
|
||||
return this.$util.toast('密码长度为6-18位')
|
||||
@@ -197,6 +187,8 @@ export default {
|
||||
uni.reLaunch({
|
||||
url: '/pages/user/login',
|
||||
})
|
||||
}).finally(() => {
|
||||
this.loadingButton = false
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
Binary file not shown.
BIN
static/user_manual1.docx
Normal file
BIN
static/user_manual1.docx
Normal file
Binary file not shown.
@@ -221,4 +221,4 @@ function chooseAndUploadFile(opts = {
|
||||
export {
|
||||
chooseAndUploadFile,
|
||||
uploadCloudFiles
|
||||
};
|
||||
};
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
@delFile="delFile"
|
||||
>
|
||||
<slot><button type="primary" size="mini">选择文件</button></slot>
|
||||
</upload-file>
|
||||
</upload-file>
|
||||
|
||||
</view>
|
||||
</template>
|
||||
@@ -354,7 +354,7 @@ export default {
|
||||
icon: 'none',
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.chooseFiles(type)
|
||||
},
|
||||
@@ -363,13 +363,13 @@ export default {
|
||||
* 选择文件并上传
|
||||
*/
|
||||
chooseFiles(type) {
|
||||
const _extname = get_extname(this.fileExtname)
|
||||
const _extname = get_extname(this.fileExtname)
|
||||
|
||||
// 获取后缀
|
||||
uniCloud
|
||||
.chooseAndUploadFile({
|
||||
type: this.fileMediatype,
|
||||
compressed: false,
|
||||
compressed: false,
|
||||
sourceType: [type],//type? :this.sourceType ,
|
||||
sizeType: this.sizeType,
|
||||
// TODO 如果为空,video 有问题
|
||||
@@ -380,12 +380,13 @@ export default {
|
||||
this.setProgress(progressEvent, progressEvent.index)
|
||||
},
|
||||
})
|
||||
.then((result) => {
|
||||
console.log('选择失败', result)
|
||||
this.setSuccessAndError(result.tempFiles)
|
||||
.then((result) => {
|
||||
if (this.autoUpload && !this.noSpace) {
|
||||
this.setSuccessAndError(result.tempFiles)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log('选择失败', err)
|
||||
console.log('选择文件失败', err)
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
@@ -1,109 +1,109 @@
|
||||
/**
|
||||
* 获取文件名和后缀
|
||||
* @param {String} name
|
||||
*/
|
||||
export const get_file_ext = (name) => {
|
||||
const last_len = name.lastIndexOf('.')
|
||||
const len = name.length
|
||||
return {
|
||||
name: name.substring(0, last_len),
|
||||
ext: name.substring(last_len + 1, len)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扩展名
|
||||
* @param {Array} fileExtname
|
||||
*/
|
||||
export const get_extname = (fileExtname) => {
|
||||
if (!Array.isArray(fileExtname)) {
|
||||
let extname = fileExtname.replace(/(\[|\])/g, '')
|
||||
return extname.split(',')
|
||||
} else {
|
||||
return fileExtname
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件和检测是否可选
|
||||
*/
|
||||
export const get_files_and_is_max = (res, _extname) => {
|
||||
let filePaths = []
|
||||
let files = []
|
||||
if(!_extname || _extname.length === 0){
|
||||
return {
|
||||
filePaths,
|
||||
files
|
||||
}
|
||||
}
|
||||
res.tempFiles.forEach(v => {
|
||||
let fileFullName = get_file_ext(v.name)
|
||||
const extname = fileFullName.ext.toLowerCase()
|
||||
if (_extname.indexOf(extname) !== -1) {
|
||||
files.push(v)
|
||||
filePaths.push(v.path)
|
||||
}
|
||||
})
|
||||
if (files.length !== res.tempFiles.length) {
|
||||
uni.showToast({
|
||||
title: `当前选择了${res.tempFiles.length}个文件 ,${res.tempFiles.length - files.length} 个文件格式不正确`,
|
||||
icon: 'none',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
filePaths,
|
||||
files
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取图片信息
|
||||
* @param {Object} filepath
|
||||
*/
|
||||
export const get_file_info = (filepath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getImageInfo({
|
||||
src: filepath,
|
||||
success(res) {
|
||||
resolve(res)
|
||||
},
|
||||
fail(err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取封装数据
|
||||
*/
|
||||
export const get_file_data = async (files, type = 'image') => {
|
||||
// 最终需要上传数据库的数据
|
||||
let fileFullName = get_file_ext(files.name)
|
||||
const extname = fileFullName.ext.toLowerCase()
|
||||
let filedata = {
|
||||
name: files.name,
|
||||
uuid: files.uuid,
|
||||
extname: extname || '',
|
||||
cloudPath: files.cloudPath,
|
||||
fileType: files.fileType,
|
||||
url: files.path || files.path,
|
||||
size: files.size, //单位是字节
|
||||
image: {},
|
||||
path: files.path,
|
||||
video: {}
|
||||
}
|
||||
if (type === 'image') {
|
||||
const imageinfo = await get_file_info(files.path)
|
||||
delete filedata.video
|
||||
filedata.image.width = imageinfo.width
|
||||
filedata.image.height = imageinfo.height
|
||||
filedata.image.location = imageinfo.path
|
||||
} else {
|
||||
delete filedata.image
|
||||
}
|
||||
return filedata
|
||||
}
|
||||
/**
|
||||
* 获取文件名和后缀
|
||||
* @param {String} name
|
||||
*/
|
||||
export const get_file_ext = (name) => {
|
||||
const last_len = name.lastIndexOf('.')
|
||||
const len = name.length
|
||||
return {
|
||||
name: name.substring(0, last_len),
|
||||
ext: name.substring(last_len + 1, len)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取扩展名
|
||||
* @param {Array} fileExtname
|
||||
*/
|
||||
export const get_extname = (fileExtname) => {
|
||||
if (!Array.isArray(fileExtname)) {
|
||||
let extname = fileExtname.replace(/(\[|\])/g, '')
|
||||
return extname.split(',')
|
||||
} else {
|
||||
return fileExtname
|
||||
}
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件和检测是否可选
|
||||
*/
|
||||
export const get_files_and_is_max = (res, _extname) => {
|
||||
let filePaths = []
|
||||
let files = []
|
||||
if(!_extname || _extname.length === 0){
|
||||
return {
|
||||
filePaths,
|
||||
files
|
||||
}
|
||||
}
|
||||
res.tempFiles.forEach(v => {
|
||||
let fileFullName = get_file_ext(v.name)
|
||||
const extname = fileFullName.ext.toLowerCase()
|
||||
if (_extname.indexOf(extname) !== -1) {
|
||||
files.push(v)
|
||||
filePaths.push(v.path)
|
||||
}
|
||||
})
|
||||
if (files.length !== res.tempFiles.length) {
|
||||
uni.showToast({
|
||||
title: `当前选择了${res.tempFiles.length}个文件 ,${res.tempFiles.length - files.length} 个文件格式不正确`,
|
||||
icon: 'none',
|
||||
duration: 5000
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
filePaths,
|
||||
files
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取图片信息
|
||||
* @param {Object} filepath
|
||||
*/
|
||||
export const get_file_info = (filepath) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getImageInfo({
|
||||
src: filepath,
|
||||
success(res) {
|
||||
resolve(res)
|
||||
},
|
||||
fail(err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 获取封装数据
|
||||
*/
|
||||
export const get_file_data = async (files, type = 'image') => {
|
||||
// 最终需要上传数据库的数据
|
||||
let fileFullName = get_file_ext(files.name)
|
||||
const extname = fileFullName.ext.toLowerCase()
|
||||
let filedata = {
|
||||
name: files.name,
|
||||
uuid: files.uuid,
|
||||
extname: extname || '',
|
||||
cloudPath: files.cloudPath,
|
||||
fileType: files.fileType,
|
||||
url: files.path || files.path,
|
||||
size: files.size, //单位是字节
|
||||
image: {},
|
||||
path: files.path,
|
||||
video: {}
|
||||
}
|
||||
if (type === 'image') {
|
||||
const imageinfo = await get_file_info(files.path)
|
||||
delete filedata.video
|
||||
filedata.image.width = imageinfo.width
|
||||
filedata.image.height = imageinfo.height
|
||||
filedata.image.location = imageinfo.path
|
||||
} else {
|
||||
delete filedata.image
|
||||
}
|
||||
return filedata
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user