From 66cee2922dc949032c2778a707a09014fde93a98 Mon Sep 17 00:00:00 2001 From: guanj Date: Mon, 30 Mar 2026 08:43:13 +0800 Subject: [PATCH] =?UTF-8?q?=E8=81=94=E8=B0=83app?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/api/device.js | 22 +- common/api/harmonic.js | 2 +- common/api/report.js | 40 + common/js/config.js | 2 +- components/Cn-device-card/Cn-device-card.vue | 58 +- .../Cn-filterCriteria/Cn-filterCriteria.vue | 100 +- components/Cn-qianTree/Cn-qianTree.vue | 20 +- components/Cn-qianTree/style.css | 2 +- manifest.json | 2 +- pages.json | 7 +- pages/device/APF/report.vue | 2 +- pages/device/list.vue | 152 +- pages/device/new.vue | 1282 +++++++++-------- pages/device/realTime/index.vue | 29 +- pages/engineering/detail.vue | 546 +++---- pages/engineering/list.vue | 376 ++--- pages/home/selectEngineering.vue | 13 +- pages/index/comp/apply.vue | 134 +- pages/index/comp/device.vue | 66 +- pages/index/comp/engineering.vue | 132 +- pages/index/comp/indexGongCheng.vue | 32 +- pages/index/comp/indexZhuYongHu.vue | 267 ++-- pages/index/comp/steadyState.vue | 215 ++- pages/index/comp/transient.vue | 327 +++-- pages/index/index.vue | 4 +- pages/index/message1.vue | 26 +- pages/index/report.vue | 6 +- pages/message/feedbackDetail.vue | 292 ++-- pages/message/message.vue | 2 +- pages/message/messageDetail.vue | 2 +- pages/message1/alarm.vue | 28 +- pages/message1/comp/F47.vue | 35 +- pages/message1/comp/ITIC.vue | 117 +- pages/message1/comp/alarmDetails.vue | 99 +- pages/message1/comp/preview.vue | 353 +++-- pages/message1/comp/steadyStateDetails.vue | 19 +- pages/message1/comp/transientDetails.vue | 4 +- pages/message1/index.scss | 31 +- pages/message1/run.vue | 36 +- pages/message1/steadyState.vue | 34 +- pages/message1/transient.vue | 104 +- pages/mine/serverSetting.vue | 246 ++-- pages/mine/setupMessage.vue | 317 ++-- pages/mine/transientSetting.vue | 30 +- pages/project/list.vue | 366 ++--- pages/user/changePhone.vue | 499 +++---- pages/user/changePwd.vue | 485 +++---- pages/user/forget.vue | 3 +- pages/user/login.vue | 3 +- pages/user/register.vue | 3 +- static/iconfont/iconfont.css | 44 + static/iconfont/iconfont.ttf | Bin 4124 -> 6392 bytes uni_modules/uni-swipe-action/changelog.md | 60 + .../uni-swipe-action-item/bindingx.js | 302 ++++ .../components/uni-swipe-action-item/isPC.js | 22 + .../uni-swipe-action-item/mpalipay.js | 195 +++ .../uni-swipe-action-item/mpother.js | 260 ++++ .../components/uni-swipe-action-item/mpwxs.js | 84 ++ .../uni-swipe-action-item/render.js | 277 ++++ .../uni-swipe-action-item.vue | 354 +++++ .../components/uni-swipe-action-item/wx.wxs | 346 +++++ .../uni-swipe-action/uni-swipe-action.vue | 60 + uni_modules/uni-swipe-action/package.json | 113 ++ uni_modules/uni-swipe-action/readme.md | 10 + 64 files changed, 6112 insertions(+), 2987 deletions(-) create mode 100644 common/api/report.js create mode 100644 uni_modules/uni-swipe-action/changelog.md create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/bindingx.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs create mode 100644 uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue create mode 100644 uni_modules/uni-swipe-action/package.json create mode 100644 uni_modules/uni-swipe-action/readme.md diff --git a/common/api/device.js b/common/api/device.js index 5985eb4..65ac574 100644 --- a/common/api/device.js +++ b/common/api/device.js @@ -212,10 +212,30 @@ export const lineTree = (params) => { url: '/cs-device-boot/csLedger/lineTree', method: 'POST', data: { - type:'engineering' + type: 'engineering', }, // header: { // 'Content-Type': 'application/json', // }, }) } +// 查询工程 +export const queryEngineeringPage = (params) => { + return request({ + url: '/cs-device-boot/engineering/queryEngineeringPage', + method: 'POST', + data: params, + header: { + 'Content-Type': 'application/json', + }, + }) +} +// 通过ndid查询出厂设备 +export const queryEquipmentByndid = (params) => { + return request({ + url: '/cs-device-boot/EquipmentDelivery/queryEquipmentByndid', + method: 'POST', + data: params, + + }) +} diff --git a/common/api/harmonic.js b/common/api/harmonic.js index c07ce8c..8f25680 100644 --- a/common/api/harmonic.js +++ b/common/api/harmonic.js @@ -10,7 +10,7 @@ export function getModuleState(params) { } export function getBaseRealData(id) { return request({ - url: 'cs-harmonic-boot/realData/getBaseRealData?lineId='+id, + url: '/cs-harmonic-boot/realData/getBaseRealData?lineId='+id, method: 'post', }) } \ No newline at end of file diff --git a/common/api/report.js b/common/api/report.js new file mode 100644 index 0000000..bd7233a --- /dev/null +++ b/common/api/report.js @@ -0,0 +1,40 @@ +import request from '../js/request' + +// 下载稳态报告 +export function downloadHarmonicReport(data) { + return request({ + url: '/cs-report-boot/csAppReport/downloadHarmonicReport', + method: 'post', + data, + header: { + 'Content-Type': 'application/json', + }, + }) +} +// 申请暂态报告 +export function applicationReport(data) { + return request({ + url: '/cs-report-boot/csAppReport/applicationReport', + method: 'post', + data, + header: { + 'Content-Type': 'application/json', + }, + }) +} +// 生成暂态报告 +export function createEventReport(params) { + return request({ + url: '/cs-report-boot/csAppReport/createEventReport', + method: 'post', + params, + }) +} +// 下载暂态报告 +export function downloadEventReport(params) { + return request({ + url: '/cs-report-boot/csAppReport/downloadEventReport', + method: 'post', + params, + }) +} diff --git a/common/js/config.js b/common/js/config.js index f346d07..ad3033a 100644 --- a/common/js/config.js +++ b/common/js/config.js @@ -1,7 +1,7 @@ const debug = true // true 是连地服务端本地,false 是连接线上 const development = { - domain: 'http://192.168.2.126:10215', + domain: 'http://192.168.1.103:10215', } const production = { diff --git a/components/Cn-device-card/Cn-device-card.vue b/components/Cn-device-card/Cn-device-card.vue index e82c983..4608369 100644 --- a/components/Cn-device-card/Cn-device-card.vue +++ b/components/Cn-device-card/Cn-device-card.vue @@ -12,13 +12,20 @@ - + @@ -66,6 +73,7 @@ {{ device.process == 2 ? '功能调试' : '出厂调试' }} + 置顶 diff --git a/components/Cn-filterCriteria/Cn-filterCriteria.vue b/components/Cn-filterCriteria/Cn-filterCriteria.vue index c792244..f8e217b 100644 --- a/components/Cn-filterCriteria/Cn-filterCriteria.vue +++ b/components/Cn-filterCriteria/Cn-filterCriteria.vue @@ -1,6 +1,6 @@ @@ -52,6 +59,9 @@ export default { props: { level: { type: Number, default: 3 }, showDatetime: { type: Boolean, default: true }, + report: { type: Boolean, default: false }, + singleChoice: { type: Boolean, default: false }, + showQianTree: { type: Boolean, default: true }, }, data() { const currentDate = this.getDate({ @@ -69,8 +79,10 @@ export default { lineId: '', //测点ID date: currentDate, range: ['', ''], + report: 0, }, list: [], + reportList: ['日报', '月报'], } }, created() { @@ -86,29 +98,44 @@ export default { getTree() { this.clear() lineTree().then((res) => { - let list = { - id: '', - pid: '0', - pids: '0', - name: '全部项目', - path: null, - provinceId: null, - cityId: null, - area: null, - remark: null, - sort: 0, - level: 0, - comFlag: null, - type: null, - lineType: null, - conType: null, - process: null, - isTop: 0, - children: [], - ndid: null, + let list = {} + if (this.singleChoice) { + let result = this.findFirstLevel(res.data) + console.log('🚀 ~ result:', result) + this.select.engineeringName = result.parents[0].name + this.select.engineeringId = result.parents[0].id //工程ID + this.select.projectName = result.parents[1].name + this.select.projectId = result.parents[1].id //項目ID + this.select.deviceName = result.parents[2].name + this.select.deviceId = result.parents[2].id //设备ID + this.select.lineName = result.node.name + this.select.lineId = result.node.id //测点ID + } else { + list = { + id: '', + pid: '0', + pids: '0', + name: '全部项目', + path: null, + provinceId: null, + cityId: null, + area: null, + remark: null, + sort: 0, + level: 0, + comFlag: null, + type: null, + lineType: null, + conType: null, + process: null, + isTop: 0, + children: [], + ndid: null, + } } - this.list = this.filterTreeByLevel([list, ...res.data]) + this.list = this.filterTreeByLevel(this.singleChoice ? res.data : [list, ...res.data]) + // this.findFirstLevel( this.list) }) }, // 递归过滤函数:去除level > 2的节点 @@ -147,11 +174,13 @@ export default { bindDateChange(e) { this.select.date = e.detail.value }, + bindReport(e) { + this.select.report = e.detail.value + }, selectEngineering() { this.$refs.qiantree._show() }, - getProjectList() {}, // 确定回调事件 treeConfirm(e) { this.clear() @@ -192,10 +221,33 @@ export default { break } }, + external(name, id) { + this.getTree() + this.select.engineeringId = id + this.select.engineeringName = name + }, // 取消回调事件 treeCancel(e) { console.log(e) }, + findFirstLevel(list, parents = []) { + for (const item of list) { + // 当前就是 level=3 + if (item.level === 3) { + return { + node: item, // 第一个 level=3 + parents: parents, // 它的所有上级 + } + } + + // 递归子节点 + if (item.children && item.children.length) { + const res = this.findFirstLevel(item.children, [...parents, item]) + if (res) return res // 找到直接返回,不再循环 + } + } + return null + }, }, computed: { diff --git a/components/Cn-qianTree/Cn-qianTree.vue b/components/Cn-qianTree/Cn-qianTree.vue index 9c6bcd2..e1af55b 100644 --- a/components/Cn-qianTree/Cn-qianTree.vue +++ b/components/Cn-qianTree/Cn-qianTree.vue @@ -20,10 +20,17 @@ class="uni-input" radius="5" placeholder="请输入关键字搜索" - clearButton="auto" - cancelButton="none" + clearButton="none" @input="input" /> + + @@ -59,7 +66,7 @@ > @@ -70,7 +77,7 @@ @@ -101,6 +108,7 @@ export default { type: String, default: 'id', }, + singleChoice: { type: Boolean, default: false }, rangeKey: { type: String, default: 'name', @@ -416,6 +424,10 @@ export default { }) }, _treeItemSelect(item, index) { + if (item.rank != 3) { + if (this.singleChoice) return + } + // if(this.singleChoice) this.treeList[index].checked = !this.treeList[index].checked // 选父级, 子级自动全选 this.syncChecked(this.treeList, item.id, this.treeList[index].checked) diff --git a/components/Cn-qianTree/style.css b/components/Cn-qianTree/style.css index 3bdc759..0a00fb0 100644 --- a/components/Cn-qianTree/style.css +++ b/components/Cn-qianTree/style.css @@ -21,7 +21,7 @@ bottom: 0rpx; left: 0rpx; z-index: 9999; - top: 160rpx; + top: 40%; transition: all 0.3s ease; transform: translateY(100%); } diff --git a/manifest.json b/manifest.json index 035779c..22e47f8 100644 --- a/manifest.json +++ b/manifest.json @@ -139,7 +139,7 @@ "/api" : { "https" : true, // "target" : "https://pqmcn.com:8092/api", - "target" : "http://192.168.2.126:10215", + "target" : "http://192.168.1.103:10215", "changOrigin" : true, "pathRewrite" : { "/api" : "" diff --git a/pages.json b/pages.json index ea74649..1adc2a6 100644 --- a/pages.json +++ b/pages.json @@ -17,7 +17,12 @@ "path": "pages/index/message1", "style": { "navigationBarTitleText": "消息", - + "enablePullDownRefresh": true, // 开启下拉刷新 + "pullToRefresh": { + "support":true, + "style": "circle", + "color":"#007aff" + }, "app-plus": { "bounce": "none", //关闭窗口回弹效果 diff --git a/pages/device/APF/report.vue b/pages/device/APF/report.vue index d3996de..87b6d95 100644 --- a/pages/device/APF/report.vue +++ b/pages/device/APF/report.vue @@ -24,7 +24,7 @@ - 🔍 + {{ item.subTitle }} diff --git a/pages/device/list.vue b/pages/device/list.vue index b219892..2229bd9 100644 --- a/pages/device/list.vue +++ b/pages/device/list.vue @@ -3,16 +3,9 @@ diff --git a/pages/index/comp/steadyState.vue b/pages/index/comp/steadyState.vue index f5cfc73..57f84ce 100644 --- a/pages/index/comp/steadyState.vue +++ b/pages/index/comp/steadyState.vue @@ -1,6 +1,6 @@ diff --git a/pages/index/index.vue b/pages/index/index.vue index f3b2c7a..296b77b 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -33,11 +33,11 @@ - + - + diff --git a/pages/index/message1.vue b/pages/index/message1.vue index 243ff75..b28bb88 100644 --- a/pages/index/message1.vue +++ b/pages/index/message1.vue @@ -117,13 +117,24 @@ export default { }, onShow() { + const params = uni.getStorageSync('messageParams') + console.log('🚀 ~ params:', params) this.getDevCount() this.$nextTick(() => { - this.refresh() - this.$refs.cnFilterCriteria.getProjectList() + if (params.name != '') { + this.$refs.cnFilterCriteria && this.$refs.cnFilterCriteria.external(params.name, params.id) + } + // this.refresh() + this.$refs.TransientRef && this.$refs.TransientRef.getConfig() + }) + }, + // 页面销毁 + onHide() { + uni.setStorageSync('messageParams', { + name: '', + id: '', }) }, - methods: { setHeight() { uni.createSelectorQuery() @@ -132,7 +143,7 @@ export default { this.width = rect.width // // #ifdef H5 - this.navHeight = rect.height + 70 + this.navHeight = rect.height + 75 // #endif // #ifdef APP-PLUS this.navHeight = rect.height + 20 @@ -144,10 +155,7 @@ export default { refresh() { switch (this.current) { case 0: - // this.$refs.TransientRef.getConfig() - // this.$refs.TransientRef.filterValue = '' this.$refs.TransientRef.store.reload() - break case 1: this.$refs.SteadyStateRef.store.reload() @@ -171,7 +179,7 @@ export default { this.setHeight() }, 100) }, - + // 设置角标 getDevCount() { if (uni.getStorageSync('projectList')[1] != undefined) { getDevCount(uni.getStorageSync('projectList')[1].engineeringId).then((res) => { @@ -242,7 +250,7 @@ export default { } .segmented-control__text { - font-size: 27rpx !important; + font-size: 30rpx !important; color: rgb(96, 98, 102); } .segmented-control__item--text { diff --git a/pages/index/report.vue b/pages/index/report.vue index eb757f6..90bd953 100644 --- a/pages/index/report.vue +++ b/pages/index/report.vue @@ -47,7 +47,7 @@ export default { total: 6, loading: false, - items: ['稳态报表', '暂态报表'], + items: ['稳态报表', '暂降报告'], status: 'more', //more加载前 loading加载中 noMore加载后 navHeight: 0, @@ -99,7 +99,7 @@ export default { .boundingClientRect((rect) => { // // #ifdef H5 - this.navHeight = rect.height + 60 + this.navHeight = rect.height + 65 // #endif // #ifdef APP-PLUS this.navHeight = rect.height + 10 @@ -160,7 +160,7 @@ export default { } .segmented-control__text { - font-size: 27rpx !important; + font-size: 30rpx !important; color: rgb(96, 98, 102); } .segmented-control__item--text { diff --git a/pages/message/feedbackDetail.vue b/pages/message/feedbackDetail.vue index c6ed00a..cbd5e19 100644 --- a/pages/message/feedbackDetail.vue +++ b/pages/message/feedbackDetail.vue @@ -1,147 +1,147 @@ - - - \ No newline at end of file diff --git a/pages/message/message.vue b/pages/message/message.vue index 86749bc..b9eaa1e 100644 --- a/pages/message/message.vue +++ b/pages/message/message.vue @@ -28,7 +28,7 @@ > - 🔍 + {{ item.subTitle }} diff --git a/pages/message/messageDetail.vue b/pages/message/messageDetail.vue index d7caac5..9bb456a 100644 --- a/pages/message/messageDetail.vue +++ b/pages/message/messageDetail.vue @@ -82,7 +82,7 @@ export default { font-size: 26rpx; .detail-content-title { - font-size: 32rpx; + font-size: 28rpx; color: #111; font-weight: 700; } diff --git a/pages/message1/alarm.vue b/pages/message1/alarm.vue index 0d1b28e..71b8dbf 100644 --- a/pages/message1/alarm.vue +++ b/pages/message1/alarm.vue @@ -3,7 +3,14 @@ - + @@ -29,7 +36,7 @@ {{ item.date }}发生告警终端{{ item.warnNums }}台 - 🔍 + - + diff --git a/pages/message1/comp/ITIC.vue b/pages/message1/comp/ITIC.vue index 8e8402d..34cff78 100644 --- a/pages/message1/comp/ITIC.vue +++ b/pages/message1/comp/ITIC.vue @@ -13,6 +13,9 @@ export default { store: { type: [Object], }, + filterValue: { + type: [String], + }, }, data() { return { @@ -35,7 +38,7 @@ export default { itemWidth: 10, itemHeight: 10, itemGap: 8, - padding: [5, 5 ,5 ,10], + padding: [5, 5, 5, 10], }, color: ['#FF8C00', '#00BFFF', 'green', 'red'], @@ -141,108 +144,6 @@ export default { } }, - // gongfunction() { - // var standI = 0 - // var unstandI = 0 - // this.pointI = [] - // this.pointIun = [] - // var total = 0 - // total = this.data.length - // if (total == 0) { - // } else { - // for (var i = 0; i < this.data.length; i++) { - // var point = [] - // var xx = this.data[i].evtParamTm.replace(/s/g, '') - // var yy = this.data[i].evtParamVVaDepth.replace(/%/g, '') - // var time = this.data[i].startTime.replace('T', ' ') - - // point = [yy, xx, time, this.data[i]] - - // if (xx <= 0.003) { - // var line = 0 - // line = 230 - 30000 * xx - // if (yy > line) { - // unstandI++ - // this.pointIun.push({ - // value: point, - // itemStyle: { normal: { color: 'red' } }, - // }) - // } else { - // standI++ - // this.pointI.push({ - // value: point, - // itemStyle: { normal: { color: 'green' } }, - // }) - // } - // } else if (xx <= 0.02) { - // if (yy > 120) { - // unstandI++ - // this.pointIun.push({ - // value: point, - // itemStyle: { normal: { color: 'red' } }, - // }) - // } else { - // standI++ - // this.pointI.push({ - // value: point, - // itemStyle: { normal: { color: 'green' } }, - // }) - // } - // } else if (xx <= 0.5) { - // if (yy > 120 || yy < 70) { - // unstandI++ - // this.pointIun.push({ - // value: point, - // itemStyle: { normal: { color: 'red' } }, - // }) - // } else { - // standI++ - // this.pointI.push({ - // value: point, - // itemStyle: { normal: { color: 'green' } }, - // }) - // } - // } else if (xx <= 10) { - // if (yy > 110 || yy < 80) { - // unstandI++ - // this.pointIun.push({ - // value: point, - // itemStyle: { normal: { color: 'red' } }, - // }) - // } else { - // standI++ - // this.pointI.push({ - // value: point, - // itemStyle: { normal: { color: 'green' } }, - // }) - // } - // } else { - // if (yy > 110 || yy < 90) { - // unstandI++ - // this.pointIun.push({ - // value: point, - // itemStyle: { normal: { color: 'red' } }, - // }) - // } else { - // standI++ - // this.pointI.push({ - // value: point, - // itemStyle: { normal: { color: 'green' } }, - // }) - // } - // } - // } - // } - // this.option.series[2].data = this.pointI - // this.option.series[3].data = this.pointIun - - // if (this.echartRef) { - // this.echartRef.setOption(this.option, true) - // } else { - // this.initChart() - // } - // }, - gongfunction() { // 初始化计数与数据数组 let normalCount = 0 @@ -329,12 +230,20 @@ export default { store: { handler(val, oldVal) { this.status = val.status - this.data = val.data + this.data = (val.data || []).filter((k) => + this.filterValue == '' ? k : k.showName == this.filterValue, + ) this.gongfunction() }, deep: true, immediate: true, }, + filterValue: { + handler(val, oldVal) { + this.data = (this.store.data || []).filter((k) => (val == '' ? k : k.showName == val)) + this.gongfunction() + }, + }, }, } diff --git a/pages/message1/comp/alarmDetails.vue b/pages/message1/comp/alarmDetails.vue index f55b963..e86ed0e 100644 --- a/pages/message1/comp/alarmDetails.vue +++ b/pages/message1/comp/alarmDetails.vue @@ -5,10 +5,10 @@ {{ detail.date }} - - 终端告警列表 + + 终端告警列表 - + + + + + + + + + + + + + {{ item.devName }} + + + 工程名称:{{ item.engineeringName }} + 项目名称:{{ item.projectName }} + + + + + + + + + {{ date }} + + + + {{ val.warnEventTime + '发生' + val.warnEventDesc }} + + + + + + @@ -64,13 +117,13 @@ export default { loading: true, detail: {}, limit: '', - accordionVal: '1', + collapseValue: '0', list: [], } }, onLoad(options) { - this.loading = false + this.loading = true this.detail = JSON.parse(decodeURIComponent(options.detail).replace(/百分比/g, '%')) this.init() if (this.detail.isRead != 1) { @@ -81,7 +134,6 @@ export default { }, methods: { init() { - this.loading = false queryAlarmDetail({ devList: this.detail.devIds, time: this.detail.date, @@ -97,7 +149,8 @@ export default { }, } - diff --git a/pages/message1/comp/preview.vue b/pages/message1/comp/preview.vue index 71b5a45..4707664 100644 --- a/pages/message1/comp/preview.vue +++ b/pages/message1/comp/preview.vue @@ -1,15 +1,23 @@ @@ -62,12 +71,12 @@ export default { onLoad(options) { this.imageUrl = decodeURIComponent(options.url) // 接收传递的图片URL,需要解码 }, - + data() { return { imageUrl: '', - // 缩放相关 - scaleValue: 1, + // 缩放相关 - 默认0.5 + scaleValue: 0.6, x: 0, y: 0, // 图片原始尺寸 @@ -81,70 +90,132 @@ export default { tipTimer: null, // 屏幕尺寸 windowWidth: 0, - windowHeight: 0 + windowHeight: 0, + // 缩放步长 + zoomStep: 0.2, + // 动画控制 + isTouching: false, + animationTimer: null } }, - + mounted() { // 获取屏幕尺寸 - const systemInfo = uni.getSystemInfoSync(); - this.windowWidth = systemInfo.windowWidth; - this.windowHeight = systemInfo.windowHeight; + const systemInfo = uni.getSystemInfoSync() + this.windowWidth = systemInfo.windowWidth + this.windowHeight = systemInfo.windowHeight }, - + methods: { // 图片加载完成后获取尺寸 onImageLoad(e) { - const { width, height } = e.detail; - + const { width, height } = e.detail + // 保存原始尺寸 - this.imgWidth = width; - this.imgHeight = height; - + this.imgWidth = width + this.imgHeight = height + // 旋转90度后,宽度和高度互换 - this.rotatedWidth = height; // 旋转后宽度 = 原高度 - this.rotatedHeight = width; // 旋转后高度 = 原宽度 - - // 计算初始位置居中 - this.resetPosition(); - - console.log('图片加载:', {width, height}, '旋转后:', {rotatedWidth: this.rotatedWidth, rotatedHeight: this.rotatedHeight}); + this.rotatedWidth = height // 旋转后宽度 = 原高度 + this.rotatedHeight = width // 旋转后高度 = 原宽度 + + // 计算初始位置居中(考虑0.5缩放) + this.resetPosition() }, - - // 重置位置到中心 + + // 重置位置到中心(考虑当前缩放比例) resetPosition() { - // 计算居中的偏移量 - this.x = (this.windowWidth - this.rotatedWidth) / 2; - this.y = (this.windowHeight - this.rotatedHeight) / 2; - - console.log('重置位置:', {x: this.x, y: this.y, windowWidth: this.windowWidth, windowHeight: this.windowHeight}); + // 计算居中的偏移量,考虑缩放比例 + const displayWidth = this.rotatedWidth * this.scaleValue + const displayHeight = this.rotatedHeight * this.scaleValue + + this.x = (this.windowWidth - displayWidth) / 2 + this.y = (this.windowHeight - displayHeight) / 2 }, - + + // 触摸开始 + onTouchStart() { + this.isTouching = true + }, + + // 触摸结束 + onTouchEnd() { + this.isTouching = false + }, + // 缩放事件处理 onScale(e) { - this.scaleValue = e.detail.scale; - + this.scaleValue = e.detail.scale + // 显示缩放提示 - this.showScaleTip = true; + this.showScaleTip = true if (this.tipTimer) { - clearTimeout(this.tipTimer); + clearTimeout(this.tipTimer) } this.tipTimer = setTimeout(() => { - this.showScaleTip = false; - }, 1500); + this.showScaleTip = false + }, 1500) }, - - // 关闭预览 - close() { - uni.navigateBack(); + + // 放大 + zoomIn() { + // 计算新的缩放值,不超过最大值 + const newScale = Math.min(this.scaleValue + this.zoomStep, 3) + this.setScaleWithAnimation(newScale) }, - + + // 缩小 + zoomOut() { + // 计算新的缩放值,不低于最小值 + const newScale = Math.max(this.scaleValue - this.zoomStep, 0.5) + this.setScaleWithAnimation(newScale) + }, + + // 带动画的设置缩放值 + setScaleWithAnimation(newScale) { + // 保存旧的缩放值用于动画 + const oldScale = this.scaleValue + + // 计算缩放中心点(屏幕中心) + const centerX = this.windowWidth / 2 + const centerY = this.windowHeight / 2 + + // 计算当前图片中心点 + const oldDisplayWidth = this.rotatedWidth * oldScale + const oldDisplayHeight = this.rotatedHeight * oldScale + const oldCenterX = this.x + oldDisplayWidth / 2 + const oldCenterY = this.y + oldDisplayHeight / 2 + + // 计算偏移量,使缩放后图片中心保持在屏幕中心 + const newDisplayWidth = this.rotatedWidth * newScale + const newDisplayHeight = this.rotatedHeight * newScale + const newX = centerX - newDisplayWidth / 2 + const newY = centerY - newDisplayHeight / 2 + + // 更新缩放值和位置 + this.scaleValue = newScale + this.x = newX + this.y = newY + + // 显示缩放提示 + this.showScaleTip = true + if (this.tipTimer) { + clearTimeout(this.tipTimer) + } + this.tipTimer = setTimeout(() => { + this.showScaleTip = false + }, 1500) + + console.log('缩放:', {oldScale, newScale, x: this.x, y: this.y}) + }, + // 下载图片 downloadImage() { uni.showLoading({ - title: '下载中...' - }); - + title: '下载中,请稍等...', + mask: true, + }) + // 先获取图片信息(如果是网络图片需要先下载) uni.downloadFile({ url: this.imageUrl, @@ -154,16 +225,16 @@ export default { uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: () => { - uni.hideLoading(); + uni.hideLoading() uni.showToast({ title: '保存成功', - icon: 'success' - }); + icon: 'success', + }) }, fail: (err) => { - uni.hideLoading(); - console.error('保存失败', err); - + uni.hideLoading() + console.error('保存失败', err) + // 处理用户拒绝权限的情况 if (err.errMsg.includes('auth deny')) { uni.showModal({ @@ -173,52 +244,49 @@ export default { if (res.confirm) { uni.openSetting({ success: (settingRes) => { - console.log('打开设置页面', settingRes); - } - }); + console.log('打开设置页面', settingRes) + }, + }) } - } - }); + }, + }) } else { uni.showToast({ title: '保存失败', - icon: 'none' - }); + icon: 'none', + }) } - } - }); + }, + }) } else { - uni.hideLoading(); + uni.hideLoading() uni.showToast({ title: '下载失败', - icon: 'none' - }); + icon: 'none', + }) } }, fail: (err) => { - uni.hideLoading(); - console.error('下载失败', err); + uni.hideLoading() + console.error('下载失败', err) uni.showToast({ title: '下载失败', - icon: 'none' - }); - } - }); + icon: 'none', + }) + }, + }) }, - - // 双击重置缩放和位置(可选功能) - onDoubleTap() { - this.scaleValue = 1; - this.resetPosition(); - } }, - + // 页面返回前清理定时器 onUnload() { if (this.tipTimer) { - clearTimeout(this.tipTimer); + clearTimeout(this.tipTimer) } - } + if (this.animationTimer) { + cancelAnimationFrame(this.animationTimer) + } + }, } @@ -241,62 +309,89 @@ export default { display: flex; align-items: center; justify-content: center; + // 添加硬件加速 + transform: translateZ(0); + will-change: transform; } .image-wrapper { display: flex; align-items: center; justify-content: center; - transition: transform 0.1s ease; + // 添加硬件加速 + transform: translateZ(0) rotate(90deg); + will-change: transform; + backface-visibility: hidden; + -webkit-backface-visibility: hidden; + transition: transform 0.3s cubic-bezier(0.25, 0.1, 0.25, 1); } .preview-img { display: block; + // 添加硬件加速 + transform: translateZ(0); + will-change: transform; + backface-visibility: hidden; + -webkit-backface-visibility: hidden; } -// 关闭按钮 -.close-btn { +// 按钮组 +.btn-group { position: fixed; top: 30rpx; right: 30rpx; - width: 60rpx; - height: 60rpx; + display: flex; + flex-direction: row; + gap: 20rpx; + z-index: 1000; +} + +// 通用按钮样式 +.btn { + width: 70rpx; + height: 70rpx; background: rgba(0, 0, 0, 0.5); border-radius: 50%; display: flex; align-items: center; justify-content: center; - z-index: 1000; backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.2); + // 按钮不参与动画 + transform: translateZ(0); + transition: background-color 0.2s ease; - .close-icon { + &:active { + background: rgba(0, 0, 0, 0.8); + transform: scale(0.95); + } + + .btn-icon { color: #fff; font-size: 40rpx; line-height: 1; + font-weight: bold; + } +} + +// 缩小按钮 +.zoom-out-btn { + .btn-icon { + font-size: 50rpx; + } +} + +// 放大按钮 +.zoom-in-btn { + .btn-icon { + font-size: 40rpx; } } // 下载按钮 .download-btn { - position: fixed; - top: 30rpx; - right: 110rpx; - width: 60rpx; - height: 60rpx; - background: rgba(0, 0, 0, 0.5); - border-radius: 50%; - display: flex; - align-items: center; - justify-content: center; - z-index: 1000; - backdrop-filter: blur(10px); - border: 1px solid rgba(255, 255, 255, 0.2); - - .download-icon { - color: #fff; - font-size: 40rpx; - line-height: 1; + .btn-icon { + font-size: 35rpx; } } @@ -305,7 +400,7 @@ export default { position: fixed; bottom: 100rpx; left: 50%; - transform: translateX(-50%); + transform: translateX(-50%) translateZ(0); background: rgba(0, 0, 0, 0.6); color: #fff; padding: 10rpx 30rpx; @@ -315,12 +410,22 @@ export default { backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.2); animation: fadeInOut 1.5s ease; + // 提示不参与动画 + will-change: opacity; } @keyframes fadeInOut { - 0% { opacity: 0; } - 15% { opacity: 1; } - 85% { opacity: 1; } - 100% { opacity: 0; } + 0% { + opacity: 0; + } + 15% { + opacity: 1; + } + 85% { + opacity: 1; + } + 100% { + opacity: 0; + } } \ No newline at end of file diff --git a/pages/message1/comp/steadyStateDetails.vue b/pages/message1/comp/steadyStateDetails.vue index 764bd79..a0e6869 100644 --- a/pages/message1/comp/steadyStateDetails.vue +++ b/pages/message1/comp/steadyStateDetails.vue @@ -21,7 +21,7 @@ >指标越限详情(仅显示较为严重的10次) - + @@ -57,6 +57,7 @@ export default { loading: true, detail: {}, list: [], + collapseValue: '0', } }, onLoad(options) { @@ -96,10 +97,10 @@ export default { padding: 20rpx; background: #fff; margin-bottom: 20rpx; - font-size: 28rpx; + font-size: 26rpx; .detail-content-title { - font-size: 32rpx; + font-size: 30rpx; color: #111; font-weight: 700; } @@ -130,7 +131,7 @@ export default { text { flex: 1; text-align: center; - font-size: 24rpx; + font-size: 26rpx; // color: #333; &:first-child { // text-align: left; @@ -139,10 +140,14 @@ export default { } } .table-header { - padding: 0rpx; + padding: 0rpx; + padding-bottom: 10rpx; } } -/deep/ .uni-collapse-item__title-text{ - font-weight: 700; +/deep/ .uni-collapse-item__title-text { + font-weight: 700; + span { + font-size: 28rpx; + } } diff --git a/pages/message1/comp/transientDetails.vue b/pages/message1/comp/transientDetails.vue index c5b9ab2..b02304a 100644 --- a/pages/message1/comp/transientDetails.vue +++ b/pages/message1/comp/transientDetails.vue @@ -83,10 +83,10 @@ export default { padding: 20rpx; background: #fff; margin-bottom: 20rpx; - font-size: 28rpx; + font-size: 26rpx; .detail-content-title { - font-size: 32rpx; + font-size: 30rpx; color: #111; font-weight: 700; } diff --git a/pages/message1/index.scss b/pages/message1/index.scss index 98e2315..82771d8 100644 --- a/pages/message1/index.scss +++ b/pages/message1/index.scss @@ -17,6 +17,8 @@ /* 第一个盒子的特殊样式(蓝色背景) */ .box:first-child { flex: 1.7; + } + .boxClick { background-color: $uni-theme-color; color: #ffffff; } @@ -83,7 +85,13 @@ background-color: #e6a23c20; } .interrupt .event-icon { - background-color: #90939920; + background-color: #00000020; + } + .transient .event-icon { + background-color: #8b5cf620; + } + .unknown .event-icon { + background-color: #6b728020; } .event-icon image { width: 48rpx; @@ -101,7 +109,7 @@ flex-wrap: wrap; /* 适配小屏,防止文字溢出 */ } .event-id { - font-size: 15px; + font-size: 28rpx; font-weight: 700; color: #333333; margin-right: 16rpx; @@ -115,16 +123,24 @@ height: 38rpx; } .sag-tag { - background-color: #ecf5ff; + background-color: #2563eb20; color: #2563eb; } .swell-tag { - background-color: #fdf6ec; + background-color: #e6a23c20; color: #e6a23c; } .interrupt-tag { - background-color: #f4f4f5; - color: #909399; + background-color: #6b728020; + color: #6b7280; + } + .transient-tag { + background-color: #8b5cf620; + color: #8b5cf6; + } + .unknown-tag { + background-color: #6b728020; + color: #6b7280; } /* 描述文本 */ .event-desc { @@ -155,7 +171,7 @@ /* 详情文本 */ .event-detail { - font-size: 24rpx; + font-size: 26rpx; color: #666666; line-height: 1.5; padding-top: 10rpx; @@ -174,7 +190,6 @@ height: 58rpx; } .uni-input { - font-size: 24rpx; color: #2563eb; margin-right: 10rpx; diff --git a/pages/message1/run.vue b/pages/message1/run.vue index e7c9977..0645242 100644 --- a/pages/message1/run.vue +++ b/pages/message1/run.vue @@ -3,8 +3,14 @@ - + - + @@ -27,12 +33,13 @@ 工程名称:{{ item.engineeringName }} 项目名称:{{ item.projectName }} + 事件时间:{{ item.startTime }} - 于{{ item.startTime }}发生{{ item.showName }} + {{ item.showName }} - + - - + + + + + diff --git a/pages/mine/setupMessage.vue b/pages/mine/setupMessage.vue index a3fa480..f159d2d 100644 --- a/pages/mine/setupMessage.vue +++ b/pages/mine/setupMessage.vue @@ -1,147 +1,170 @@ - - - - - + + + + + diff --git a/pages/mine/transientSetting.vue b/pages/mine/transientSetting.vue index 599eb76..eb3a999 100644 --- a/pages/mine/transientSetting.vue +++ b/pages/mine/transientSetting.vue @@ -40,29 +40,33 @@ export default { init() { queryUserPushConfig().then((res) => { this.config = res.data - this.loading = false }) }, change(type) { this.config[type] = this.config[type] === 1 ? 0 : 1 - updatePushConfig(this.config).then((res) => { - let str = '' - switch (type) { - case 'iticFunction': - str = 'ITIC' - break - case 'f47Function': - str = 'F47' - break - } - this.$util.toast(`${str}配置${this.config[type] === 1 ? '开启' : '关闭'}成功`) - }) + // updatePushConfig(this.config).then((res) => { + // let str = '' + // switch (type) { + // case 'iticFunction': + // str = 'ITIC' + // break + // case 'f47Function': + // str = 'F47' + // break + // } + // this.$util.toast(`${str}配置${this.config[type] === 1 ? '开启' : '关闭'}成功`) + // }) }, }, onLoad() { this.init() }, + onUnload() { + updatePushConfig(this.config).then((res) => { + // this.$util.toast(`配置修改成功!`) + }) + }, } diff --git a/pages/project/list.vue b/pages/project/list.vue index b1c89ce..941f881 100644 --- a/pages/project/list.vue +++ b/pages/project/list.vue @@ -1,183 +1,183 @@ - - - - - + + + + + diff --git a/pages/user/changePhone.vue b/pages/user/changePhone.vue index 265a074..fb7e22f 100644 --- a/pages/user/changePhone.vue +++ b/pages/user/changePhone.vue @@ -1,249 +1,250 @@ - - - + + + diff --git a/pages/user/changePwd.vue b/pages/user/changePwd.vue index 19e07b4..e6c4669 100644 --- a/pages/user/changePwd.vue +++ b/pages/user/changePwd.vue @@ -1,242 +1,243 @@ - - - + + + diff --git a/pages/user/forget.vue b/pages/user/forget.vue index 5df800c..67ce0a5 100644 --- a/pages/user/forget.vue +++ b/pages/user/forget.vue @@ -114,7 +114,8 @@ export default { return this.$util.toast('请输入手机号!') } uni.showLoading({ - title: '请稍等', + title: '请稍等...', + mask: true, }) apiGetYms({ phone: this.formData.phone, diff --git a/pages/user/login.vue b/pages/user/login.vue index b71462d..9385bc3 100644 --- a/pages/user/login.vue +++ b/pages/user/login.vue @@ -121,7 +121,8 @@ export default { return this.$util.toast('请输入手机号!') } uni.showLoading({ - title: '请稍等', + title: '请稍等...', + mask: true, }) apiGetYms({ phone: this.phone, diff --git a/pages/user/register.vue b/pages/user/register.vue index cdcc0d1..5317d44 100644 --- a/pages/user/register.vue +++ b/pages/user/register.vue @@ -135,7 +135,8 @@ export default { return this.$util.toast('请输入手机号!') } uni.showLoading({ - title: '请稍等', + title: '请稍等...', + mask: true, }) apiGetYms({ phone: this.formData.phone, diff --git a/static/iconfont/iconfont.css b/static/iconfont/iconfont.css index fda8fc6..5df24ba 100644 --- a/static/iconfont/iconfont.css +++ b/static/iconfont/iconfont.css @@ -11,6 +11,50 @@ -moz-osx-font-smoothing: grayscale; } +.icon-baogaoguanli:before { + content: "\e663"; +} + +.icon-a-svg5:before { + content: "\e601"; +} + +.icon-a-svg4:before { + content: "\e600"; +} + +.icon-shebei4:before { + content: "\e719"; +} + +.icon-shebeizhuangtai:before { + content: "\ec23"; +} + +.icon-shebei3:before { + content: "\e62e"; +} + +.icon-zj:before { + content: "\e79a"; +} + +.icon-zs:before { + content: "\e79b"; +} + +.icon-zhongduan2:before { + content: "\e6c8"; +} + +.icon-wenhao:before { + content: "\e637"; +} + +.icon-shuntaishijian:before { + content: "\e6ff"; +} + .icon-zaixianjianceshebei:before { content: "\e683"; } diff --git a/static/iconfont/iconfont.ttf b/static/iconfont/iconfont.ttf index 98406869a619c043682398fbaa19318906f39f08..fcc4501886738115f40a6bc7cfda2fe48c8e04c9 100644 GIT binary patch delta 2952 zcmcImYitzP6+Y+AlYNh8W*=S~dv@{K#bAeh@>rX-luAiKv5TsRm;zpmW1INZm=HjL zr9q@ku_%@44@g=eXo)JM5Qu3>6%_)hpphb~NJVLbDjKO{RiYJrL_)mW+(=+&$&9sSodxJTNvnSngy?$zJ$2 z$?5U(?kQXbhp9hGa`Qxad?-{oU3?2b@1sSBrzWR&o;xDE0T8)FM%{qq#)0Yq__{n; z-Bm5g{f_28o@h-&+R;@{3~UV+KLamcGx+15zR~V9oSMe&l>52wk|+bKb<^}zN1?*N zGn>G1JUe?7yZmrBSz8de+b}cxJFHL1Wg0YCHJw@ijZ*axU#jlnp<1o!UYz|4K3-w2 zGk|r#)uvxYwTA+W(nyoWFNJ1mc}z5YW~13*7R*6&$b8;BXwH~d%^T*2=1sFYADdq{ zzia-ryUA)5XxJC9Jzle&{gkzBMp|Uq7x+C!?r_9K5JDi5lL#6_zy|?PU=h@T4qkHA z4`EP2BGv>VOnmzfjA4bW=)omUNl(Oa(gn>3Ch_XP;n^fh2eb;9jV@?CFgsk(%3u~; zI7FF)E*$dAAs6Hqn9sYYtyMWl0>N>^oN+;JgL%~j1pwv^7ZeJZAG)BRz`W^#!UNM` zmq3BSe9Q%f4D;(;Q1CFn%LUN@^T%COh!L1S;exn<`PW-xAC`xsPK~Trtl9jExs)NUh+vFkUfp69^%e&--JfUK@ar7*NExG zsAtlPF`{SzOd6F$2evBNZd`-ee8xx%$%H5=T9}&of|5@Sgu5ch{6ums!T3rA4}!&MqPZl zeN3&y<0_8T#Tyh7YHj-%j&Y-YBh*w#Sbd3AiKcvloi|n|5}C7M#p+ceG}n10oXBMC zzL=iy^0DTa@KH=tA~8J_6|nE=TI4^Fd+CgF#Hp7uhFBJioKb_4Q3L{#ELVE1E$q}k z2b_{w7ayFs$X$4Ff`4|~+*@;DcFNi!It4p9N8_tz?cnc!bW)CjZ*ia`6$eP|dUnBj zO1R3-TfGbSF7XH6St#%?KiJRhyEJzxY(2#;h)!Yk(XGT)Xpb&)?{PiQ1Yd#-?T?WV z_1XsLv=#0~INOk;4aw1l2nMmQ7)mz(aA&&E;0CNx+sc(~Si0j^RX+o#yn~L;in1$y z)dH3MS@l~bzsdnuTG?h@Xs7TDjhyYCe@5zvoFGurGOomGB@8A{M&i8uQx2!$v zD|p%N>FUA9OX#=%j(*m2qz8jei}DY^Q>|7H@IV&@Pe(lfnSHaSv9Gxr>}o$Z7u59N#ek-_ z20Z&cs5N@`dGyJEj-1};6t{vJuQw9zJ<`ARA{pp`TFJ86PoB7K&?;(WQ(aEAuf1a5 zs;TU2b#k2APBSPrX+O-e*b3?gN!Cbm~Fk?L|TRZ7!rDw&W(NlX%l9azZIHO-Kc znNpY%m{OZFv}ic$OVuYrp6`47UrjG*UY%-d&^l$WEDy_^u>JCip$!>(s-d&c8IM!Z zz#_@jEvhDkgV~Tri+LNen#`?Cpz$&lMD^@h=OsZ$V_QX5l@s7Mx)c%=JKJ4ZW zz+=!2>){#aXtj2b%aWHoqlzP`9i97W4XTT=8w+vzu+S$%jf4x%nM+|flcu1YNCFrU zNLq{e4y3@vu$0bI%&COfh!ri&589uu%?al7d$9M% z%p35q{i`GoE|q=gTX;wG3A`-u!+aK>f+3#Dt29*c`7pMFx@5uL!eWw) zizIvGx1vNn_I*(z5nr|bCa#cW34gv}5&9HAKI3J4Ncun$<&gXl^Ztq|k;IVblmF_t zLj}OwC;8uaDp6#}A&&xzC?U;`9`vFQ{S<8wL#SXKs;HrkVT@oDW8m9Xo*bt4h4RGM zs90V;y=yqD-cxQR^p+3X*?qGYTJ$pwcCx*9EUs}{(9GVy@ YPX?w(UYH=m>5*oP`6G+`J75(SK*KXeB+G8?SVjx{`UeewnL#3dy zGVy>G)KC6K=ND%D%-3_*S^u8?#lT-Fs~pytAE2Lqel2Zz-57+EiWup3WfD8 zp!X3Me1QV2TDOMB&UgB7=Hkey;Uy79JNuW0p7c)sLdH%OblShK#DADlVs4c!!U zlI9*bd#GwS;h+lCyRe~ddv4TB1YsSb79OZ { + // if (item === this) { + // this.swipeaction.children.splice(index, 1) + // } + // }) + // }, + methods: { + init() { + this.$nextTick(() => { + this.x = 0 + this.button = { + show: false + } + setTimeout(() => { + this.getSelectorQuery() + }, 200) + }) + }, + onClick(index, item, position) { + this.$emit('click', { + content: item, + index, + position + }) + }, + touchstart(e) { + // fix by mehaotian 禁止滑动 + if (this.disabled) return + // 每次只触发一次,避免多次监听造成闪烁 + if (this.stop) return + this.stop = true + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + let expression = this.range(this.x, -rightWidth, leftWidth) + let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0) + let rightExpression = this.range(this.x + rightWidth, 0, rightWidth) + + this.eventpan = BindingX.bind({ + anchor: this.box, + eventType: 'pan', + props: [{ + element: this.selector, + property: 'transform.translateX', + expression + }, { + element: this.leftButton, + property: 'transform.translateX', + expression: leftExpression + }, { + element: this.rightButton, + property: 'transform.translateX', + expression: rightExpression + }, ] + }, (e) => { + // nope + if (e.state === 'end') { + this.x = e.deltaX + this.x; + this.isclick = true + this.bindTiming(e.deltaX) + } + }); + }, + touchend(e) { + if (this.isopen !== 'none' && !this.isclick) { + this.open('none') + } + }, + bindTiming(x) { + const left = this.x + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + const threshold = this.threshold + if (!this.isopen || this.isopen === 'none') { + if (left > threshold) { + this.open('left') + } else if (left < -threshold) { + this.open('right') + } else { + this.open('none') + } + } else { + if ((x > -leftWidth && x < 0) || x > rightWidth) { + if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) { + this.open('left') + } else { + this.open('none') + } + } else { + if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) { + this.open('right') + } else { + this.open('none') + } + } + } + }, + + /** + * 移动范围 + * @param {Object} num + * @param {Object} mix + * @param {Object} max + */ + range(num, mix, max) { + return `min(max(x+${num}, ${mix}), ${max})` + }, + + /** + * 开启swipe + */ + open(type) { + this.animation(type) + }, + + /** + * 关闭swipe + */ + close() { + this.animation('none') + }, + + /** + * 开启关闭动画 + * @param {Object} type + */ + animation(type) { + const time = 300 + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + if (this.eventpan && this.eventpan.token) { + BindingX.unbind({ + token: this.eventpan.token, + eventType: 'pan' + }) + } + + switch (type) { + case 'left': + Promise.all([ + this.move(this.selector, leftWidth), + this.move(this.leftButton, 0), + this.move(this.rightButton, rightWidth * 2) + ]).then(() => { + this.setEmit(leftWidth, type) + }) + break + case 'right': + Promise.all([ + this.move(this.selector, -rightWidth), + this.move(this.leftButton, -leftWidth * 2), + this.move(this.rightButton, 0) + ]).then(() => { + this.setEmit(-rightWidth, type) + }) + break + default: + Promise.all([ + this.move(this.selector, 0), + this.move(this.leftButton, -leftWidth), + this.move(this.rightButton, rightWidth) + ]).then(() => { + this.setEmit(0, type) + }) + + } + }, + setEmit(x, type) { + const leftWidth = this.button.left.width + const rightWidth = this.button.right.width + this.isopen = this.isopen || 'none' + this.stop = false + this.isclick = false + // 只有状态不一致才会返回结果 + if (this.isopen !== type && this.x !== x) { + if (type === 'left' && leftWidth > 0) { + this.$emit('change', 'left') + } + if (type === 'right' && rightWidth > 0) { + this.$emit('change', 'right') + } + if (type === 'none') { + this.$emit('change', 'none') + } + } + this.x = x + this.isopen = type + }, + move(ref, value) { + return new Promise((resolve, reject) => { + animation.transition(ref, { + styles: { + transform: `translateX(${value})`, + }, + duration: 150, //ms + timingFunction: 'linear', + needLayout: false, + delay: 0 //ms + }, function(res) { + resolve(res) + }) + }) + + }, + + /** + * 获取ref + * @param {Object} el + */ + getEl(el) { + return el.ref + }, + /** + * 获取节点信息 + */ + getSelectorQuery() { + Promise.all([ + this.getDom('left'), + this.getDom('right'), + ]).then((data) => { + let show = 'none' + if (this.autoClose) { + show = 'none' + } else { + show = this.show + } + + if (show === 'none') { + // this.close() + } else { + this.open(show) + } + + }) + + }, + getDom(str) { + return new Promise((resolve, reject) => { + dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => { + if (data) { + this.button[str] = data.size + resolve(data) + } else { + reject() + } + }) + }) + } + } +} + +// #endif + +export default bindIngXMixins diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js new file mode 100644 index 0000000..7dd4a20 --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/isPC.js @@ -0,0 +1,22 @@ +export function isPC() { + var userAgentInfo = navigator.userAgent || ''; + var info = typeof uni !== 'undefined' && uni.getSystemInfoSync ? uni.getSystemInfoSync() : null; + if (info && info.deviceType) { + if (info.deviceType === 'pc') return true; + if (info.deviceType === 'phone' || info.deviceType === 'pad') return false; + } + var isMobileUA = /Android|iPhone|SymbianOS|Windows Phone|iPad|iPod|Mobile|Harmony|HarmonyOS/i.test(userAgentInfo); + if (isMobileUA) return false; + var hasTouch = false; + if (typeof navigator.maxTouchPoints === 'number') { + hasTouch = navigator.maxTouchPoints > 0; + } else if (typeof window !== 'undefined') { + hasTouch = 'ontouchstart' in window; + } + if (hasTouch && typeof window !== 'undefined' && window.matchMedia) { + var finePointer = window.matchMedia('(pointer: fine)').matches; + var canHover = window.matchMedia('(hover: hover)').matches; + return finePointer || canHover; + } + return !hasTouch; +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js new file mode 100644 index 0000000..6e5ad7c --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpalipay.js @@ -0,0 +1,195 @@ +export default { + data() { + return { + x: 0, + transition: false, + width: 0, + viewWidth: 0, + swipeShow: 0 + } + }, + watch: { + show(newVal) { + if (this.autoClose) return + if (newVal && newVal !== 'none') { + this.transition = true + this.open(newVal) + } else { + this.close() + } + } + }, + created() { + this.swipeaction = this.getSwipeAction() + if (this.swipeaction && Array.isArray(this.swipeaction.children)) { + this.swipeaction.children.push(this) + } + }, + mounted() { + this.isopen = false + setTimeout(() => { + this.getQuerySelect() + }, 50) + }, + methods: { + appTouchStart(e) { + const { + clientX + } = e.changedTouches[0] + this.clientX = clientX + this.timestamp = new Date().getTime() + }, + appTouchEnd(e, index, item, position) { + const { + clientX + } = e.changedTouches[0] + // fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题 + let diff = Math.abs(this.clientX - clientX) + let time = (new Date().getTime()) - this.timestamp + if (diff < 40 && time < 300) { + this.$emit('click', { + content: item, + index, + position + }) + } + }, + /** + * 移动触发 + * @param {Object} e + */ + onChange(e) { + this.moveX = e.detail.x + this.isclose = false + }, + touchstart(e) { + this.transition = false + this.isclose = true + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + }, + touchmove(e) {}, + touchend(e) { + // 0的位置什么都不执行 + if (this.isclose && this.isopen === 'none') return + if (this.isclose && this.isopen !== 'none') { + this.transition = true + this.close() + } else { + this.move(this.moveX + this.leftWidth) + } + }, + + /** + * 移动 + * @param {Object} moveX + */ + move(moveX) { + // 打开关闭的处理逻辑不太一样 + this.transition = true + // 未打开状态 + if (!this.isopen || this.isopen === 'none') { + if (moveX > this.threshold) { + this.open('left') + } else if (moveX < -this.threshold) { + this.open('right') + } else { + this.close() + } + } else { + if (moveX < 0 && moveX < this.rightWidth) { + const rightX = this.rightWidth + moveX + if (rightX < this.threshold) { + this.open('right') + } else { + this.close() + } + } else if (moveX > 0 && moveX < this.leftWidth) { + const leftX = this.leftWidth - moveX + if (leftX < this.threshold) { + this.open('left') + } else { + this.close() + } + } + + } + + }, + + /** + * 打开 + */ + open(type) { + this.x = this.moveX + this.animation(type) + }, + + /** + * 关闭 + */ + close() { + this.x = this.moveX + // TODO 解决 x 值不更新的问题,所以会多触发一次 nextTick ,待优化 + this.$nextTick(() => { + this.x = -this.leftWidth + if (this.isopen !== 'none') { + this.$emit('change', 'none') + } + this.isopen = 'none' + }) + }, + + /** + * 执行结束动画 + * @param {Object} type + */ + animation(type) { + this.$nextTick(() => { + if (type === 'left') { + this.x = 0 + } else { + this.x = -this.rightWidth - this.leftWidth + } + + if (this.isopen !== type) { + this.$emit('change', type) + } + this.isopen = type + }) + + }, + getSlide(x) {}, + getQuerySelect() { + const query = uni.createSelectorQuery().in(this); + query.selectAll('.movable-view--hock').boundingClientRect(data => { + this.leftWidth = data[1].width + this.rightWidth = data[2].width + this.width = data[0].width + this.viewWidth = this.width + this.rightWidth + this.leftWidth + if (this.leftWidth === 0) { + // TODO 疑似bug ,初始化的时候如果x 是0,会导致移动位置错误,所以让元素超出一点 + this.x = -0.1 + } else { + this.x = -this.leftWidth + } + this.moveX = this.x + this.$nextTick(() => { + this.swipeShow = 1 + }) + + if (!this.buttonWidth) { + this.disabledView = true + } + + if (this.autoClose) return + if (this.show !== 'none') { + this.transition = true + this.open(this.shows) + } + }).exec(); + + } + } +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js new file mode 100644 index 0000000..7d1702e --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpother.js @@ -0,0 +1,260 @@ +let otherMixins = {} + +// #ifndef APP-PLUS|| MP-WEIXIN || H5 +const MIN_DISTANCE = 10; +otherMixins = { + data() { + // TODO 随机生生元素ID,解决百度小程序获取同一个元素位置信息的bug + const elClass = `Uni_${Math.ceil(Math.random() * 10e5).toString(36)}` + return { + uniShow: false, + left: 0, + buttonShow: 'none', + ani: false, + moveLeft: '', + elClass + } + }, + watch: { + show(newVal) { + if (this.autoClose) return + this.openState(newVal) + }, + left() { + this.moveLeft = `translateX(${this.left}px)` + }, + buttonShow(newVal) { + if (this.autoClose) return + this.openState(newVal) + }, + leftOptions() { + this.init() + }, + rightOptions() { + this.init() + } + }, + mounted() { + this.swipeaction = this.getSwipeAction() + if (this.swipeaction && Array.isArray(this.swipeaction.children)) { + this.swipeaction.children.push(this) + } + this.init() + }, + methods: { + init() { + clearTimeout(this.timer) + this.timer = setTimeout(() => { + this.getSelectorQuery() + }, 100) + // 移动距离 + this.left = 0 + this.x = 0 + }, + + closeSwipe(e) { + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + }, + appTouchStart(e) { + const { + clientX + } = e.changedTouches[0] + this.clientX = clientX + this.timestamp = new Date().getTime() + }, + appTouchEnd(e, index, item, position) { + const { + clientX + } = e.changedTouches[0] + // fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题 + let diff = Math.abs(this.clientX - clientX) + let time = (new Date().getTime()) - this.timestamp + if (diff < 40 && time < 300) { + this.$emit('click', { + content: item, + index, + position + }) + } + }, + touchstart(e) { + if (this.disabled) return + this.ani = false + this.x = this.left || 0 + this.stopTouchStart(e) + this.autoClose && this.closeSwipe() + }, + touchmove(e) { + if (this.disabled) return + // 是否可以滑动页面 + this.stopTouchMove(e); + if (this.direction !== 'horizontal') { + return; + } + this.move(this.x + this.deltaX) + return false + }, + touchend() { + if (this.disabled) return + this.moveDirection(this.left) + }, + /** + * 设置移动距离 + * @param {Object} value + */ + move(value) { + value = value || 0 + const leftWidth = this.leftWidth + const rightWidth = this.rightWidth + // 获取可滑动范围 + this.left = this.range(value, -rightWidth, leftWidth); + }, + + /** + * 获取范围 + * @param {Object} num + * @param {Object} min + * @param {Object} max + */ + range(num, min, max) { + return Math.min(Math.max(num, min), max); + }, + /** + * 移动方向判断 + * @param {Object} left + * @param {Object} value + */ + moveDirection(left) { + const threshold = this.threshold + const isopen = this.isopen || 'none' + const leftWidth = this.leftWidth + const rightWidth = this.rightWidth + if (this.deltaX === 0) { + this.openState('none') + return + } + if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > + 0 && rightWidth + + left < threshold)) { + // right + this.openState('right') + } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > + 0 && + leftWidth - left < threshold)) { + // left + this.openState('left') + } else { + // default + this.openState('none') + } + }, + + /** + * 开启状态 + * @param {Boolean} type + */ + openState(type) { + const leftWidth = this.leftWidth + const rightWidth = this.rightWidth + let left = '' + this.isopen = this.isopen ? this.isopen : 'none' + switch (type) { + case "left": + left = leftWidth + break + case "right": + left = -rightWidth + break + default: + left = 0 + } + + + if (this.isopen !== type) { + this.throttle = true + this.$emit('change', type) + } + + this.isopen = type + // 添加动画类 + this.ani = true + this.$nextTick(() => { + this.move(left) + }) + // 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的 + }, + close() { + this.openState('none') + }, + getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal'; + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical'; + } + return ''; + }, + + /** + * 重置滑动状态 + * @param {Object} event + */ + resetTouchStatus() { + this.direction = ''; + this.deltaX = 0; + this.deltaY = 0; + this.offsetX = 0; + this.offsetY = 0; + }, + + /** + * 设置滑动开始位置 + * @param {Object} event + */ + stopTouchStart(event) { + this.resetTouchStatus(); + const touch = event.touches[0]; + this.startX = touch.clientX; + this.startY = touch.clientY; + }, + + /** + * 滑动中,是否禁止打开 + * @param {Object} event + */ + stopTouchMove(event) { + const touch = event.touches[0]; + this.deltaX = touch.clientX - this.startX; + this.deltaY = touch.clientY - this.startY; + this.offsetX = Math.abs(this.deltaX); + this.offsetY = Math.abs(this.deltaY); + this.direction = this.direction || this.getDirection(this.offsetX, this.offsetY); + }, + + getSelectorQuery() { + const views = uni.createSelectorQuery().in(this) + views + .selectAll('.' + this.elClass) + .boundingClientRect(data => { + if (data.length === 0) return + let show = 'none' + if (this.autoClose) { + show = 'none' + } else { + show = this.show + } + this.leftWidth = data[0].width || 0 + this.rightWidth = data[1].width || 0 + this.buttonShow = show + }) + .exec() + } + } +} + +// #endif + +export default otherMixins diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js new file mode 100644 index 0000000..bfea96e --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/mpwxs.js @@ -0,0 +1,84 @@ +let mpMixins = {} +let is_pc = null +// #ifdef H5 +import { + isPC +} from "./isPC" +is_pc = isPC() +// #endif +// #ifdef APP-VUE || APP-HARMONY || MP-WEIXIN || H5 + +mpMixins = { + data() { + return { + is_show: 'none' + } + }, + watch: { + show(newVal) { + this.is_show = this.show + } + }, + created() { + this.swipeaction = this.getSwipeAction() + if (this.swipeaction && Array.isArray(this.swipeaction.children)) { + this.swipeaction.children.push(this) + } + }, + mounted() { + this.is_show = this.show + }, + methods: { + // wxs 中调用 + closeSwipe(e) { + if (this.autoClose && this.swipeaction) { + this.swipeaction.closeOther(this) + } + }, + + change(e) { + this.$emit('change', e.open) + if (this.is_show !== e.open) { + this.is_show = e.open + } + }, + + appTouchStart(e) { + if (is_pc) return + const { + clientX + } = e.changedTouches[0] + this.clientX = clientX + this.timestamp = new Date().getTime() + }, + appTouchEnd(e, index, item, position) { + if (is_pc) return + const { + clientX + } = e.changedTouches[0] + // fixed by xxxx 模拟点击事件,解决 ios 13 点击区域错位的问题 + let diff = Math.abs(this.clientX - clientX) + let time = (new Date().getTime()) - this.timestamp + if (diff < 40 && time < 300) { + this.$emit('click', { + content: item, + index, + position + }) + } + }, + onClickForPC(index, item, position) { + if (!is_pc) return + // #ifdef H5 + this.$emit('click', { + content: item, + index, + position + }) + // #endif + } + } +} + +// #endif +export default mpMixins diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js new file mode 100644 index 0000000..2fb81a4 --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/render.js @@ -0,0 +1,277 @@ +const MIN_DISTANCE = 10; +export default { + showWatch(newVal, oldVal, ownerInstance, instance, self) { + var state = self.state || {} + var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el + if (!$el) return + this.getDom(instance, ownerInstance, self) + if (newVal && newVal !== 'none') { + this.openState(newVal, instance, ownerInstance, self) + return + } + + if (state.left) { + this.openState('none', instance, ownerInstance, self) + } + this.resetTouchStatus(instance, self) + }, + + /** + * 开始触摸操作 + * @param {Object} e + * @param {Object} ins + */ + touchstart(e, ownerInstance, self) { + let instance = e.instance; + let disabled = instance.getDataset().disabled + let state = self.state || {}; + this.getDom(instance, ownerInstance, self) + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = this.getDisabledType(disabled) + if (disabled) return + // 开始触摸时移除动画类 + instance.requestAnimationFrame(function() { + instance.removeClass('ani'); + ownerInstance.callMethod('closeSwipe'); + }) + + // 记录上次的位置 + state.x = state.left || 0 + // 计算滑动开始位置 + this.stopTouchStart(e, ownerInstance, self) + }, + + /** + * 开始滑动操作 + * @param {Object} e + * @param {Object} ownerInstance + */ + touchmove(e, ownerInstance, self) { + let instance = e.instance; + // 删除之后已经那不到实例了 + if (!instance) return; + let disabled = instance.getDataset().disabled + let state = self.state || {} + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = this.getDisabledType(disabled) + if (disabled) return + // 是否可以滑动页面 + this.stopTouchMove(e, self); + if (state.direction !== 'horizontal') { + return; + } + if (e.preventDefault) { + // 阻止页面滚动 + e.preventDefault() + } + let x = state.x + state.deltaX + this.move(x, instance, ownerInstance, self) + }, + + /** + * 结束触摸操作 + * @param {Object} e + * @param {Object} ownerInstance + */ + touchend(e, ownerInstance, self) { + let instance = e.instance; + let disabled = instance.getDataset().disabled + let state = self.state || {} + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = this.getDisabledType(disabled) + + if (disabled) return + // 滑动过程中触摸结束,通过阙值判断是开启还是关闭 + // fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13 + this.moveDirection(state.left, instance, ownerInstance, self) + + }, + + /** + * 设置移动距离 + * @param {Object} value + * @param {Object} instance + * @param {Object} ownerInstance + */ + move(value, instance, ownerInstance, self) { + value = value || 0 + let state = self.state || {} + let leftWidth = state.leftWidth + let rightWidth = state.rightWidth + // 获取可滑动范围 + state.left = this.range(value, -rightWidth, leftWidth); + instance.requestAnimationFrame(function() { + instance.setStyle({ + transform: 'translateX(' + state.left + 'px)', + '-webkit-transform': 'translateX(' + state.left + 'px)' + }) + }) + + }, + + /** + * 获取元素信息 + * @param {Object} instance + * @param {Object} ownerInstance + */ + getDom(instance, ownerInstance, self) { + var state = self.state || {} + var $el = ownerInstance.$el || ownerInstance.$vm && ownerInstance.$vm.$el + var leftDom = $el.querySelector('.button-group--left') + var rightDom = $el.querySelector('.button-group--right') + if (leftDom && leftDom.offsetWidth) { + state.leftWidth = leftDom.offsetWidth || 0 + } else { + state.leftWidth = 0 + } + if (rightDom && rightDom.offsetWidth) { + state.rightWidth = rightDom.offsetWidth || 0 + } else { + state.rightWidth = 0 + } + state.threshold = instance.getDataset().threshold + }, + + getDisabledType(value) { + return (typeof(value) === 'string' ? JSON.parse(value) : value) || false; + }, + + /** + * 获取范围 + * @param {Object} num + * @param {Object} min + * @param {Object} max + */ + range(num, min, max) { + return Math.min(Math.max(num, min), max); + }, + + + /** + * 移动方向判断 + * @param {Object} left + * @param {Object} value + * @param {Object} ownerInstance + * @param {Object} ins + */ + moveDirection(left, ins, ownerInstance, self) { + var state = self.state || {} + var threshold = state.threshold + var position = state.position + var isopen = state.isopen || 'none' + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + if (state.deltaX === 0) { + this.openState('none', ins, ownerInstance, self) + return + } + if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 && + rightWidth + + left < threshold)) { + // right + this.openState('right', ins, ownerInstance, self) + } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 && + leftWidth - left < threshold)) { + // left + this.openState('left', ins, ownerInstance, self) + } else { + // default + this.openState('none', ins, ownerInstance, self) + } + }, + + + /** + * 开启状态 + * @param {Boolean} type + * @param {Object} ins + * @param {Object} ownerInstance + */ + openState(type, ins, ownerInstance, self) { + let state = self.state || {} + let leftWidth = state.leftWidth + let rightWidth = state.rightWidth + let left = '' + state.isopen = state.isopen ? state.isopen : 'none' + switch (type) { + case "left": + left = leftWidth + break + case "right": + left = -rightWidth + break + default: + left = 0 + } + + // && !state.throttle + + if (state.isopen !== type) { + state.throttle = true + ownerInstance.callMethod('change', { + open: type + }) + + } + + state.isopen = type + // 添加动画类 + ins.requestAnimationFrame(() => { + ins.addClass('ani'); + this.move(left, ins, ownerInstance, self) + }) + }, + + + getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal'; + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical'; + } + return ''; + }, + + /** + * 重置滑动状态 + * @param {Object} event + */ + resetTouchStatus(instance, self) { + let state = self.state || {}; + state.direction = ''; + state.deltaX = 0; + state.deltaY = 0; + state.offsetX = 0; + state.offsetY = 0; + }, + + /** + * 设置滑动开始位置 + * @param {Object} event + */ + stopTouchStart(event, ownerInstance, self) { + let instance = event.instance; + let state = self.state || {} + this.resetTouchStatus(instance, self); + var touch = event.touches[0]; + state.startX = touch.clientX; + state.startY = touch.clientY; + }, + + /** + * 滑动中,是否禁止打开 + * @param {Object} event + */ + stopTouchMove(event, self) { + let instance = event.instance; + let state = self.state || {}; + let touch = event.touches[0]; + + state.deltaX = touch.clientX - state.startX; + state.deltaY = touch.clientY - state.startY; + state.offsetY = Math.abs(state.deltaY); + state.offsetX = Math.abs(state.deltaX); + state.direction = state.direction || this.getDirection(state.offsetX, state.offsetY); + } +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue new file mode 100644 index 0000000..851918c --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/uni-swipe-action-item.vue @@ -0,0 +1,354 @@ + + + + + + diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs new file mode 100644 index 0000000..39466fd --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action-item/wx.wxs @@ -0,0 +1,346 @@ +var MIN_DISTANCE = 10; + +/** + * 判断当前是否为H5、app-vue + */ +var IS_HTML5 = false +if (typeof window === 'object') IS_HTML5 = true + +/** + * 监听页面内值的变化,主要用于动态开关swipe-action + * @param {Object} newValue + * @param {Object} oldValue + * @param {Object} ownerInstance + * @param {Object} instance + */ +function showWatch(newVal, oldVal, ownerInstance, instance) { + var state = instance.getState() + getDom(instance, ownerInstance) + if (newVal && newVal !== 'none') { + openState(newVal, instance, ownerInstance) + return + } + + if (state.left) { + openState('none', instance, ownerInstance) + } + resetTouchStatus(instance) +} + +/** + * 开始触摸操作 + * @param {Object} e + * @param {Object} ins + */ +function touchstart(e, ownerInstance) { + var instance = e.instance; + var disabled = instance.getDataset().disabled + var state = instance.getState(); + getDom(instance, ownerInstance) + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false; + if (disabled) return + // 开始触摸时移除动画类 + instance.requestAnimationFrame(function() { + instance.removeClass('ani'); + ownerInstance.callMethod('closeSwipe'); + }) + + // 记录上次的位置 + state.x = state.left || 0 + // 计算滑动开始位置 + stopTouchStart(e, ownerInstance) +} + +/** + * 开始滑动操作 + * @param {Object} e + * @param {Object} ownerInstance + */ +function touchmove(e, ownerInstance) { + var instance = e.instance; + var disabled = instance.getDataset().disabled + var state = instance.getState() + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false; + if (disabled) return + // 是否可以滑动页面 + stopTouchMove(e); + if (state.direction !== 'horizontal') { + return; + } + + if (e.preventDefault) { + // 阻止页面滚动 + e.preventDefault() + } + + move(state.x + state.deltaX, instance, ownerInstance) +} + +/** + * 结束触摸操作 + * @param {Object} e + * @param {Object} ownerInstance + */ +function touchend(e, ownerInstance) { + var instance = e.instance; + var disabled = instance.getDataset().disabled + var state = instance.getState() + // fix by mehaotian, TODO 兼容 app-vue 获取dataset为字符串 , h5 获取 为 undefined 的问题,待框架修复 + disabled = (typeof(disabled) === 'string' ? JSON.parse(disabled) : disabled) || false; + + if (disabled) return + // 滑动过程中触摸结束,通过阙值判断是开启还是关闭 + // fixed by mehaotian 定时器解决点击按钮,touchend 触发比 click 事件时机早的问题 ,主要是 ios13 + moveDirection(state.left, instance, ownerInstance) + +} + +/** + * 设置移动距离 + * @param {Object} value + * @param {Object} instance + * @param {Object} ownerInstance + */ +function move(value, instance, ownerInstance) { + value = value || 0 + var state = instance.getState() + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + // 获取可滑动范围 + state.left = range(value, -rightWidth, leftWidth); + instance.requestAnimationFrame(function() { + instance.setStyle({ + transform: 'translateX(' + state.left + 'px)', + '-webkit-transform': 'translateX(' + state.left + 'px)' + }) + }) + +} + +/** + * 获取元素信息 + * @param {Object} instance + * @param {Object} ownerInstance + */ +function getDom(instance, ownerInstance) { + var state = instance.getState() + var leftDom = ownerInstance.selectComponent('.button-group--left') + var rightDom = ownerInstance.selectComponent('.button-group--right') + var leftStyles = { + width: 0 + } + var rightStyles = { + width: 0 + } + + if (leftDom) { + leftStyles = leftDom.getBoundingClientRect() + } + + if (rightDom) { + rightStyles = rightDom.getBoundingClientRect() + } + state.leftWidth = leftStyles.width || 0 + state.rightWidth = rightStyles.width || 0 + state.threshold = instance.getDataset().threshold +} + +/** + * 获取范围 + * @param {Object} num + * @param {Object} min + * @param {Object} max + */ +function range(num, min, max) { + return Math.min(Math.max(num, min), max); +} + + +/** + * 移动方向判断 + * @param {Object} left + * @param {Object} value + * @param {Object} ownerInstance + * @param {Object} ins + */ +function moveDirection(left, ins, ownerInstance) { + var state = ins.getState() + var threshold = state.threshold + var position = state.position + var isopen = state.isopen || 'none' + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + if (state.deltaX === 0) { + openState('none', ins, ownerInstance) + return + } + if ((isopen === 'none' && rightWidth > 0 && -left > threshold) || (isopen !== 'none' && rightWidth > 0 && + rightWidth + + left < threshold)) { + // right + openState('right', ins, ownerInstance) + } else if ((isopen === 'none' && leftWidth > 0 && left > threshold) || (isopen !== 'none' && leftWidth > 0 && + leftWidth - left < threshold)) { + // left + openState('left', ins, ownerInstance) + } else { + // default + openState('none', ins, ownerInstance) + } +} + + +/** + * 开启状态 + * @param {Boolean} type + * @param {Object} ins + * @param {Object} ownerInstance + */ +function openState(type, ins, ownerInstance) { + var state = ins.getState() + var leftWidth = state.leftWidth + var rightWidth = state.rightWidth + var left = '' + state.isopen = state.isopen ? state.isopen : 'none' + switch (type) { + case "left": + left = leftWidth + break + case "right": + left = -rightWidth + break + default: + left = 0 + } + + // && !state.throttle + + if (state.isopen !== type) { + state.throttle = true + ownerInstance.callMethod('change', { + open: type + }) + + } + + state.isopen = type + // 添加动画类 + ins.requestAnimationFrame(function() { + ins.addClass('ani'); + move(left, ins, ownerInstance) + }) + // 设置最终移动位置,理论上只要进入到这个函数,肯定是要打开的 +} + + +function getDirection(x, y) { + if (x > y && x > MIN_DISTANCE) { + return 'horizontal'; + } + if (y > x && y > MIN_DISTANCE) { + return 'vertical'; + } + return ''; +} + +/** + * 重置滑动状态 + * @param {Object} event + */ +function resetTouchStatus(instance) { + var state = instance.getState(); + state.direction = ''; + state.deltaX = 0; + state.deltaY = 0; + state.offsetX = 0; + state.offsetY = 0; +} + +/** + * 设置滑动开始位置 + * @param {Object} event + */ +function stopTouchStart(event) { + var instance = event.instance; + var state = instance.getState(); + resetTouchStatus(instance); + var touch = event.touches[0]; + if (IS_HTML5 && isPC()) { + touch = event; + } + state.startX = touch.clientX; + state.startY = touch.clientY; +} + +/** + * 滑动中,是否禁止打开 + * @param {Object} event + */ +function stopTouchMove(event) { + var instance = event.instance; + var state = instance.getState(); + var touch = event.touches[0]; + if (IS_HTML5 && isPC()) { + touch = event; + } + state.deltaX = touch.clientX - state.startX; + state.deltaY = touch.clientY - state.startY; + state.offsetY = Math.abs(state.deltaY); + state.offsetX = Math.abs(state.deltaX); + state.direction = state.direction || getDirection(state.offsetX, state.offsetY); +} + +function isPC() { + var userAgentInfo = navigator.userAgent; + var Agents = ["Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod", "Mobile", "Harmony", "HarmonyOS"]; + var flag = true; + for (var v = 0; v < Agents.length; v++) { + if (userAgentInfo.indexOf(Agents[v]) > 0) { + flag = false; + break; + } + } + return flag; +} + +var movable = false + +function mousedown(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + touchstart(e, ins) + movable = true +} + +function mousemove(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + if (!movable) return + touchmove(e, ins) +} + +function mouseup(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + touchend(e, ins) + movable = false +} + +function mouseleave(e, ins) { + if (!IS_HTML5) return + if (!isPC()) return + movable = false +} + +module.exports = { + showWatch: showWatch, + touchstart: touchstart, + touchmove: touchmove, + touchend: touchend, + mousedown: mousedown, + mousemove: mousemove, + mouseup: mouseup, + mouseleave: mouseleave +} diff --git a/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue b/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue new file mode 100644 index 0000000..9b32b3d --- /dev/null +++ b/uni_modules/uni-swipe-action/components/uni-swipe-action/uni-swipe-action.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/uni_modules/uni-swipe-action/package.json b/uni_modules/uni-swipe-action/package.json new file mode 100644 index 0000000..2165ae1 --- /dev/null +++ b/uni_modules/uni-swipe-action/package.json @@ -0,0 +1,113 @@ +{ + "id": "uni-swipe-action", + "displayName": "uni-swipe-action 滑动操作", + "version": "1.3.17", + "description": "SwipeAction 滑动操作操作组件", + "keywords": [ + "", + "uni-ui", + "uniui", + "滑动删除", + "侧滑删除" +], + "repository": "https://github.com/dcloudio/uni-ui", + "engines": { + "HBuilderX": "", + "uni-app": "^4.27", + "uni-app-x": "" + }, + "directories": { + "example": "../../temps/example_temps" + }, + "dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui", + "type": "component-vue", + "darkmode": "x", + "i18n": "x", + "widescreen": "x" + }, + "uni_modules": { + "dependencies": [ + "uni-scss" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "x", + "aliyun": "x", + "alipay": "x" + }, + "client": { + "uni-app": { + "vue": { + "vue2": { + "extVersion": "1.3.14", + "minVersion": "" + }, + "vue3": { + "extVersion": "1.3.14", + "minVersion": "" + } + }, + "web": { + "safari": "√", + "chrome": "√" + }, + "app": { + "vue": "√", + "nvue": "√", + "android": "√", + "ios": "√", + "harmony": "√" + }, + "mp": { + "weixin": "√", + "alipay": "√", + "toutiao": "√", + "baidu": "√", + "kuaishou": "-", + "jd": "-", + "harmony": "-", + "qq": "√", + "lark": "-", + "xhs": "-" + }, + "quickapp": { + "huawei": "√", + "union": "√" + } + }, + "uni-app-x": { + "web": { + "safari": "-", + "chrome": "-" + }, + "app": { + "android": "-", + "ios": "-", + "harmony": "-" + }, + "mp": { + "weixin": "-" + } + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/uni-swipe-action/readme.md b/uni_modules/uni-swipe-action/readme.md new file mode 100644 index 0000000..284066a --- /dev/null +++ b/uni_modules/uni-swipe-action/readme.md @@ -0,0 +1,10 @@ + + +## SwipeAction 滑动操作 +> **组件名:uni-swipe-action** +> 代码块: `uSwipeAction`、`uSwipeActionItem` + + +通过滑动触发选项的容器 + +### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-swipe-action) \ No newline at end of file