点位管理

This commit is contained in:
2023-10-12 17:00:46 +08:00
parent 8c9bf09057
commit 428a6a695f
12 changed files with 1278 additions and 408 deletions

View File

@@ -107,7 +107,7 @@ uni-button:after {
.zd_content {
width: 100%;
height: auto;
padding: 92rpx 15rpx 82rpx 14rpx;
padding: 92rpx 14rpx 82rpx 14rpx;
}
.zd_wrapper {
width: 100%;
@@ -288,72 +288,3 @@ uni-button:after {
z-index: 300 !important;
}
/** 弹窗 */
.msg_wrapper {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
text-align: center;
z-index: 201;
display: flex;
justify-content: center;
align-items: center;
}
.msg_wrapper_1 {
text-align: left;
}
.msg_box {
width: 90%;
padding: 20rpx;
background-color: #fff;
border-radius: 4px;
border: 1px solid #ebeef5;
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
backface-visibility: hidden;
}
.msg_mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: .7;
background: #000;
z-index: 200;
}
.msg_btns {
width: 100%;
max-width: 300px;
margin: 40rpx auto 0;
display: flex;
justify-content: space-between;
align-items: center;
}
.msg_btn {
border-radius: 10rpx;
}
.msg_btn:disabled {
background-color: #c9c9c9;
}
.uni-select__input-placeholder,.uni-select__selector-empty, .uni-select__selector-item {
font-size: 28rpx !important
}
.sin_input {
width: 150rpx;
font-size: 28rpx;
line-height: 150rpx;
height: 68rpx;
color: #323232;
padding: 0 .1rem;
border: 1px solid #a1a1a1;
border-radius: 3px;
}
.layout-t tr.checked td .sin_input {
color: #8a8a8a;
border: 1px solid #ffffff;
}

View File

@@ -25,7 +25,7 @@
}
},
{
"path": "pages/modules/callmanage",
"path": "pages/modules/pointmanage",
"style" :
{
"navigationStyle": "custom"

View File

@@ -35,24 +35,18 @@
</template>
<script>
import {authority} from '@/utils/getData2.js'
export default {
data() {
return {
menuList: [],
menuList: [
{menu_id: '1', imgsrc: 'RF05', name: '任务管理', path: '/pages/modules/taskmanage'},
{menu_id: '2', imgsrc: 'RF03', name: '指令管理', path: '/pages/modules/zlmanage'},
{menu_id: '3', imgsrc: 'RF04', name: '点位管理', path: '/pages/modules/pointmanage'}],
show: false,
secM: []
};
},
created () {
this._authority()
},
methods: {
async _authority () {
let res = await authority()
this.menuList = [...res.sonTree]
},
toPage1 (e) {
// if (e.sonTree.length > 0) {
// this.show = true

View File

@@ -1,235 +0,0 @@
<template>
<view class="zd_container">
<nav-bar title="呼叫管理"></nav-bar>
<view class="zd_content">
<view class="zd_wrapper grid-wraper">
<view class="locate_block" v-for="e in areaArr" :key="e.region_code">
<view class="locate_name" @click="getPonit (e)">
<view class="title_1">{{e.region_name}}</view>
<view class="iconfont open_icon" :class="{'is_reverse': e.checked === true}"></view>
</view>
<view v-show="e.checked === true" class="site_block" ref="liCon">
<view class="site_item" v-for="(el, i) in e.pointArr" :key="i">
<view class="site_item_box">
<text class="title_2">站点</text>
<view class="site_item_box_inner_r" @click="setcode(el)">
<text>{{el.device_name}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="submit-bar">
<view class="dot_item">
<view class="p1">起始点</view>
<view class="p2">设备号{{sObj.device_name}}</view>
</view>
<view class="dot_item">
<view class="p1">目标点</view>
<view class="p2">设备号{{nObj.device_name}}</view>
</view>
<view class="btn_block">
<button class="submit-button" :class="{'btn-disabled': JSON.stringify(sObj) === '{}' && JSON.stringify(nObj) === '{}'}" @click="cancle">清空</button>
<button class="submit-button" :class="{'btn-disabled': JSON.stringify(sObj) === '{}' || JSON.stringify(nObj) === '{}'}" :disabled="disabled1" @click="toSure">确认</button>
</view>
</view>
</view>
</template>
<script>
import NavBar from '@/components/NavBar.vue'
import {queryArea, queryPointByArea, callTask} from '@/utils/getData2.js'
export default {
components: {
NavBar
},
data() {
return {
// interTime: this.$store.getters.setTime,
// timer: null,
areaArr: [],
pointArr: [],
regobj: {},
disabled1: false,
sObj: {},
nObj: {},
isS: false
};
},
created () {
this.initArea()
},
// beforeDestroy () {
// clearInterval(this.timer)
// },
methods: {
// refresh (e) {
// this.timer = setInterval(() => {
// this.initPonit(e)
// }, this.interTime)
// },
async initArea () {
let res = await queryArea()
this.areaArr = [...res.result]
this.areaArr.map(el => {
this.$set(el, 'checked', false)
this.$set(el, 'pointArr', [])
})
if (this.areaArr.length > 0) {
this.getPonit(this.areaArr[0])
}
},
async initPonit (e) {
let res = await queryPointByArea(e.region_code)
this.regobj = e
this.areaArr.map(el => {
if (el.region_code === e.region_code) {
this.$set(el, 'pointArr', [...res.result])
}
})
},
getPonit (e) {
// clearInterval(this.timer)
this.areaArr.map(el => {
if (el.region_code !== e.region_code) {
el.checked = false
}
if (el.region_code === e.region_code) {
e.checked = !e.checked
}
})
if (e.checked) {
this.initPonit(e)
// this.refresh(e)
}
},
setcode (el) {
if (this.isS === false) {
this.sObj = el
this.isS = true
} else if (this.isS) {
this.nObj = el
this.isS = false
}
},
/** 清空点位选择 */
cancle () {
this.sObj = {}
this.nObj = {}
this.disabled1 = false
},
toSure () {
this.disabled1 = true
if (JSON.stringify(this.sObj) === '{}' || JSON.stringify(this.nObj) === '{}') {
this.disabled1 = false
return
}
this._callTask()
},
async _callTask () {
try {
let res = await callTask(this.sObj.device_code, this.nObj.device_code)
this.cancle()
uni.showToast({
title: res.desc,
icon: 'none'
})
// clearInterval(this.timer)
// this.timer = null
// setTimeout(() => {
// this.refresh()
// this.cancle()
// }, 2000)
} catch (err) {
this.disabled1 = false
}
}
}
}
</script>
<style lang="stylus">
@import '../../common/style/mixin.styl';
.zd_content
padding-bottom 152rpx
.locate_block
width 100%
.locate_name
position relative
_wh(100%,48rpx)
.title_1
_font(32rpx,48rpx,#000,500)
.open_icon
position absolute
right 0
top 0
_wh(48rpx,48rpx)
_font(40rpx,48rpx,$red,,right)
transition all .3s
transform rotateZ(-90deg)
&:before
content: "\e6db";
.is_reverse
transform rotateZ(90deg)
.site_block
_wh(100%,auto)
overflow hidden
transition height .3s
_fj(flex-start,,,wrap)
padding-bottom 10rpx
.site_item
_wh(32%,100rpx)
padding 0 10rpx
margin-top 12rpx
background-color #e5e5e5
border-radius 5px
overflow hidden
_fj(center)
&:nth-child(3n+2)
margin-left 2%
margin-right 2%
.site_item_box
_wh(100%, 80rpx)
_fj()
.title_2
width 36rpx
_font(28rpx,40rpx,#000,500)
.site_item_box_inner_r
_fj(center)
_wh(calc(100% - 36rpx), 100%)
background-color #fff
border-radius 3px
padding 0 5rpx
overflow hidden
text
_font(28rpx,40rpx,#999,,center)
.submit-bar
justify-content space-between
padding 10rpx
.dot_item
width 35%
background-color #e5e5e5
_fj(center,,column)
.p1
_wh(100%, 52rpx)
_font(30rpx,52rpx,,,center)
border-bottom 1rpx solid #fff
overflow hidden
.p2
_wh(100%, 80rpx)
_fj(center)
padding 0 5rpx
_font(30rpx,40rpx,,,center)
overflow hidden
word-break break-all
.btn_block
_fj(,,column)
align-content: flex-end
.submit-button
line-height 56rpx
margin 0
&:nth-child(1)
margin-bottom 10rpx
</style>

View File

@@ -0,0 +1,342 @@
<template>
<view class="zd_container">
<nav-bar title="点位管理"></nav-bar>
<view class="zd_content">
<view class="state-wrap">
<view class="state-item-wrap" v-for="e in state">
<view class="state-color" :class="e.color"></view>
<view class="state-name">{{e.name}}</view>
</view>
</view>
<view v-show="areaArr.length > 0" class="zd_wrapper grid-wraper">
<view class="locate_block" v-for="e in areaArr" :key="e.value">
<view class="locate_name" @click="getPonit (e)">
<view class="title_1">{{e.label}}</view>
<view class="iconfont open_icon" :class="{'is_reverse': e.checked === true}"></view>
</view>
<view v-show="e.checked === true" class="site_block" ref="liCon">
<view class="site_item" v-for="(el, i) in e.pointArr" :key="i">
<view class="site_item_box">
<text class="title_2">站点</text>
<view class="site_item_box_inner_r" @click="setcode(el)">
<text>{{el.device_name}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-if="active" class="msg_wrapper">
<view class="msg_box">
<view class="msg_item">
<view class="label_item">当前设备</view>
<view class="from_item">
{{obj.device_name}}
</view>
</view>
<view class="msg_item">
<view class="label_item">当前物料</view>
<view class="from_item">
<zxz-uni-data-select v-model="index" filterable :localdata="options" @inputChange="inputChange" @change="change"></zxz-uni-data-select>
</view>
</view>
<view class="msg_item">
<view class="label_item">数量</view>
<view class="from_item">
<input type="number" class="input_item" v-model="qty" @input="handleInput">
</view>
</view>
<view class="msg_btns">
<button class="msg_btn" :disabled="disabled1" @click="cleanUp">清空</button>
<button class="msg_btn" :disabled="disabled2" @click="msgSure">确认</button>
<button class="msg_btn" @click="msgCancle">取消</button>
</view>
</view>
</view>
<view v-if="active" class="mask"></view>
</view>
</template>
<script>
import NavBar from '@/components/NavBar.vue'
import {queryArea, queryPointByArea, handMaterial, handPointOpt} from '@/utils/getData2.js'
export default {
components: {
NavBar
},
data() {
return {
// interTime: this.$store.getters.setTime,
// timer: null,
state: [{color: 'bggray', name: '空位'}, {color: 'bggreen', name: '有货'}, {color: 'bgyellow', name: '有任务'}],
areaArr: [],
pointArr: [],
regobj: {},
disabled1: false,
disabled2: false,
options: [],
index: '',
qty: '',
obj: {},
active: false
};
},
created () {
this.initArea()
this._handMaterial()
},
// beforeDestroy () {
// clearInterval(this.timer)
// },
methods: {
// refresh (e) {
// this.timer = setInterval(() => {
// this.initPonit(e)
// }, this.interTime)
// },
async initArea () {
let res = await queryArea()
this.areaArr = [...res.result]
this.areaArr.map(el => {
this.$set(el, 'checked', false)
this.$set(el, 'pointArr', [])
})
if (this.areaArr.length > 0) {
this.getPonit(this.areaArr[0])
}
},
async initPonit (e) {
let res = await queryPointByArea(e.value)
this.regobj = e
this.areaArr.map(el => {
if (el.value === e.value) {
this.$set(el, 'pointArr', [...res.result])
}
})
},
getPonit (e) {
// clearInterval(this.timer)
this.areaArr.map(el => {
if (el.value !== e.value) {
el.checked = false
}
if (el.value === e.value) {
e.checked = !e.checked
}
})
if (e.checked) {
this.initPonit(e)
// this.refresh(e)
}
},
async _handMaterial () {
let res = await handMaterial()
res.result.map(el => {
this.$set(el, 'text', el.label)
})
this.options = res.result
},
change(e) {
// console.log('e:', e);
},
inputChange(e) {
// console.log(e);
},
handleInput (event) {
let value = event.target.value
value = value.replace(/[^\d]/g, '').replace(/^[eE]/, '').replace(/[eE][+\-]?[0-9]*/, '')
this.qty = value
},
setcode (el) {
this.active = true
this.obj = el.device_name
this.index = el.material_type
this.qty = el.qty
},
cleanUp () {
this.disabled1 = true
this._handPointOpt('2', this.index, this.qty)
this.active = false
},
msgSure () {
this.disabled2 = true
this._handPointOpt('1', this.index, this.qty)
this.active = false
},
msgCancle () {
this.active = false
this.obj = {}
this.index = ''
this.qty = ''
},
async _handPointOpt (type, mtype, qty) {
try {
let res = await handPointOpt(type, mtype, qty)
uni.showToast({
title: '操作成功',
icon: 'none'
})
that.initPonit(this.regobj)
this.index = ''
this.qty = ''
this.obj = {}
this.disabled1 = false
this.disabled2 = false
} catch (err) {
this.index = ''
this.qty = ''
this.obj = {}
this.disabled1 = false
this.disabled2 = false
}
}
}
}
</script>
<style lang="stylus">
@import '../../common/style/mixin.styl';
.zd_content
padding-bottom 22rpx
.locate_block
width 100%
.locate_name
position relative
_wh(100%,48rpx)
.title_1
_font(32rpx,48rpx,#000,500)
.open_icon
position absolute
right 0
top 0
_wh(48rpx,48rpx)
_font(40rpx,48rpx,$red,,right)
transition all .3s
transform rotateZ(-90deg)
&:before
content: "\e6db";
.is_reverse
transform rotateZ(90deg)
.site_block
_wh(100%,auto)
overflow hidden
transition height .3s
_fj(flex-start,,,wrap)
padding-bottom 10rpx
.site_item
_wh(32%,100rpx)
padding 0 10rpx
margin-top 12rpx
background-color #e5e5e5
border-radius 5px
overflow hidden
_fj(center)
&:nth-child(3n+2)
margin-left 2%
margin-right 2%
.site_item_box
_wh(100%, 80rpx)
_fj()
.title_2
width 36rpx
_font(28rpx,40rpx,#000,500)
.site_item_box_inner_r
_fj(center)
_wh(calc(100% - 36rpx), 100%)
background-color #fff
border-radius 3px
padding 0 5rpx
overflow hidden
text
_font(28rpx,40rpx,#999,,center)
.msg_wrapper
position fixed
top 0
bottom 0
left 0
right 0
text-align center
z-index 100
&::after
content ""
display inline-block
height 100%
width 0
vertical-align middle
.msg_box
display inline-block
width 90%
max-width 420px
padding 20rpx
vertical-align middle
background-color #fff
border-radius 4px
border 1px solid #ebeef5
box-shadow 0 2px 12px 0 rgb(0 0 0 / 10%)
overflow hidden
backface-visibility hidden
.input_item
width 100%
height 70rpx
border-radius 4px
border 1px solid #DCDFE6
_font(28rpx,70rpx,#606266)
padding 0 10px
.mask
position fixed
top 0
left 0
width 100%
height 100%
opacity .2
background #000
z-index 99
.msg_item
_fj()
height 70rpx
line-height 70rpx
margin-bottom 30rpx
.msg_txt
_font(32rpx,70rpx,#333)
.label_item
width 150rpx
_font(32rpx,70rpx,#333)
.from_item
width calc(100% - 160rpx)
_font(28rpx,70rpx,#606266)
.msg_btns
height 70rpx
line-height 70rpx
width 100%
max-width 300px
margin 40rpx auto 0
_fj()
.msg_btn
width 160rpx
height 70rpx
line-height 70rpx
font-size 28rpx
color #fff
background-color #d7592f
border-radius 5px
text-align center
&:disabled
background-color $gray
.uni-select__input-placeholder,.uni-select__selector-empty, .uni-select__selector-item
font-size 28rpx !important
.state-wrap
_wh(100%, 60rpx)
margin-bottom 10rpx
_fj(flex-start)
.state-item-wrap
height 60rpx
margin-right 20rpx
_fj()
.state-color
_wh(30rpx, 30rpx)
border-radius 50%
margin-right 10rpx
.state-name
_font(28rpx, 60rpx, #333)
</style>

BIN
static/image/menu/RF04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
static/image/menu/RF05.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,35 @@
## 1.0.122023-09-27
修复搜索输入内容的时候下拉框的箭头会跑到文本框前面去
优化当有选中项时不显示清除按钮
## 1.0.112023-09-05
更换change事件执行顺序
修复多选更改值时未即时更改下拉框选项
修复单选搜索框选中了
修复多选筛选输入时点击其他未清空筛选值
## 1.0.102023-08-29
修复单选搜索回显问题
## 1.0.92023-08-28
更新文档
## 1.0.82023-08-28
更新文档
## 1.0.72023-08-16
修复组件禁用bug
修复数据回显问题
添加多选搜索功能
## 1.0.62023-08-05
修复清空值多选下拉列表还是被选中bug
## 1.0.52023-07-10
修复多选初始化异步数据不显示问题
## 1.0.42023-07-07
修复微信小程序多选显示兼容问题
## 1.0.32023-07-06
修复bug
多选情况下 初始化之后重新选择第一个不显示
## 1.0.22023-07-06
更新VUE3兼容
## 1.0.12023-06-30
添加多选合并功能
## 1.0.02023-06-16
添加下拉框检索,多选功能,自定义数据
## 1.0.42023-06-16
添加下拉框检索,多选功能,自定义数据

View File

@@ -0,0 +1,759 @@
<template>
<view class="uni-stat__select">
<!-- hide-on-phone -->
<span v-if="label" class="uni-label-text">{{label + ''}}</span>
<view class="uni-stat-box" :class="{'uni-stat__actived': current}">
<view class="uni-select" :style="{height:multiple?'100%':' 35px;'}"
:class="{'uni-select--disabled':disabled}">
<view class="uni-select__input-box" :style="{height:multiple?'100%':'35px;'}" @click="toggleSelector">
<view class="" style="display: flex;flex-wrap: wrap;width: 100%;" v-if="multiple&&current.length>0">
<view class="tag-calss"
v-for="(item,index) in collapseTags?current.slice(0,collapseTagsNum):current"
:key="item[dataValue]">
<span class="text">{{item[dataKey]}}</span>
<view class="" @click.stop="delItem(item)">
<uni-icons type="clear" style="margin-left: 4px;" color="#c0c4cc" />
</view>
</view>
<view v-if="current.length>collapseTagsNum&&collapseTags" class="tag-calss">
<span class="text">+{{current.length-collapseTagsNum}}</span>
</view>
<input v-if="filterable&&!disabled" @input="inputChange" class="uni-select__input-text"
type="text" style="font-size: 12px;height: 52rpx;margin-left: 6px;width: auto;"
placeholder="请输入" v-model="filterInput">
</view>
<view v-else-if="current&&current.length>0&&!showSelector" class="uni-select__input-text">
{{current}}
</view>
<input v-else-if="filterable&&showSelector" :focus="isFocus" @input="inputChange"
:disabled="disabled" @click.stop="" class="uni-select__input-text" type="text"
style="font-size: 12px;position: absolute;z-index: 1;" :placeholder="placeholderOld"
v-model="filterInput">
<view v-else class="uni-select__input-text uni-select__input-placeholder">{{typePlaceholder}}</view>
<uni-icons v-if="(current.length>0 && clear&&!disabled)||(currentArr.length>0&&clear&&!disabled)" type="clear" color="#c0c4cc" size="24"
style="position: absolute;right: 0;" @click="clearVal" />
<uni-icons style="right: 0;position: absolute;" v-else :type="showSelector? 'top' : 'bottom'" size="14" color="#999" />
</view>
<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
<view class="uni-select__selector" v-if="showSelector">
<view class="uni-popper__arrow"></view>
<scroll-view scroll-y="true" class="uni-select__selector-scroll">
<view class="uni-select__selector-empty" v-if="filterMixinDatacomResData.length === 0">
<span>{{emptyTips}}</span>
</view>
<view v-else class="uni-select__selector-item"
style="display: flex;justify-content: space-between;align-items: center;"
v-for="(item,index) in filterMixinDatacomResData" :key="index" @click="change(item)">
<span
:class="{'uni-select__selector__disabled': item.disable}">{{formatItemName(item)}}</span>
<uni-icons v-if="multiple&&currentArr.includes(item[dataValue])" type="checkmarkempty"
color="#007aff" />
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
/**
* DataChecklist 数据选择器
* @description 通过数据渲染的下拉框组件
* @tutorial https://uniapp.dcloud.io/component/uniui/uni-data-select
* @property {String} value 默认值
* @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
* @property {Boolean} clear 是否可以清空已选项
* @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
* @property {String} label 左侧标题
* @property {String} placeholder 输入框的提示文字
* @property {Boolean} disabled 是否禁用
* @event {Function} change 选中发生变化触发
*/
export default {
name: "uni-stat-select",
mixins: [uniCloud.mixinDatacom || {}],
props: {
collapseTagsNum: {
type: Number,
default: 1
},
collapseTags: {
type: Boolean,
default: false
},
dataKey: {
type: [String],
default: 'text'
},
dataValue: {
type: [String],
default: 'value'
},
multiple: {
type: Boolean,
default: false
},
filterable: {
type: Boolean,
default: false
},
localdata: {
type: Array,
default () {
return []
}
},
// #ifndef VUE3
value: {
type: [String, Number, Array],
default: ''
},
// #endif
// #ifdef VUE3
modelValue: {
type: [String, Number, Array],
default: ''
},
// #endif
label: {
type: String,
default: ''
},
placeholder: {
type: String,
default: '请选择'
},
emptyTips: {
type: String,
default: '无选项'
},
clear: {
type: Boolean,
default: true
},
defItem: {
type: Number,
default: 0
},
disabled: {
type: Boolean,
default: false
},
// 格式化输出 用法 field="_id as value, version as text, uni_platform as label" format="{label} - {text}"
format: {
type: String,
default: ''
},
},
data() {
return {
showSelector: false,
current: [],
mixinDatacomResData: [],
apps: [],
channels: [],
cacheKey: "uni-data-select-lastSelectedValue",
placeholderOld: "",
currentArr: [],
filterInput: "",
isFocus: false
};
},
created() {
if (this.multiple) {
// #ifndef VUE3
this.currentArr = this.value || []
// #endif
// #ifdef VUE3
this.currentArr = this.modelValue || []
// #endif
if (this.current.length > 0) {
this.current = []
}
// #ifndef VUE3
if (this.value && this.value.length > 0 && this.filterMixinDatacomResData.length > 0) {
this.current = this.value.map(item => {
let current = this.mixinDatacomResData.find(e =>
e[this.dataValue] == item
)
return {
...current
}
})
}
// #endif
// #ifdef VUE3
if (this.modelValue && this.modelValue.length > 0 && this.filterMixinDatacomResData.length > 0) {
this.current = this.modelValue.map(item => {
let current = this.mixinDatacomResData.find(e =>
e[this.dataValue] == item
)
return {
...current
}
})
}
// #endif
} else {
// #ifndef VUE3
if (this.value || this.value == 0) {
this.current = this.formatItemName(this.filterMixinDatacomResData.find(e =>
e[this.dataValue] == this.value
))
}
// #endif
// #ifdef VUE3
if (this.modelValue || this.value == 0) {
this.current = this.formatItemName(this.filterMixinDatacomResData.find(e =>
e[this.dataValue] == this.modelValue
))
}
// #endif
}
this.placeholderOld = this.placeholder
this.debounceGet = this.debounce(() => {
this.query();
}, 300);
if (this.collection && !this.localdata.length) {
this.debounceGet();
}
},
computed: {
filterMixinDatacomResData() {
if (this.filterable && this.filterInput) {
return this.mixinDatacomResData.filter(e => e[this.dataKey].includes(this.filterInput))
} else {
return this.mixinDatacomResData
}
},
typePlaceholder() {
const text = {
'opendb-stat-app-versions': '版本',
'opendb-app-channels': '渠道',
'opendb-app-list': '应用'
}
const common = this.placeholder
const placeholder = text[this.collection]
return placeholder ?
common + placeholder :
common
},
valueCom() {
// #ifdef VUE3
return this.modelValue;
// #endif
// #ifndef VUE3
return this.value;
// #endif
}
},
watch: {
localdata: {
immediate: true,
handler(val, old) {
if (Array.isArray(val) && old !== val) {
this.mixinDatacomResData = val
}
}
},
valueCom(val, old) {
this.initDefVal()
},
mixinDatacomResData: {
immediate: true,
handler(val) {
if (val.length) {
this.initDefVal()
}
}
},
},
methods: {
debounce(fn, time = 100) {
let timer = null
return function(...args) {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, args)
}, time)
}
},
// 执行数据库查询
query() {
this.mixinDatacomEasyGet();
},
// 监听查询条件变更事件
onMixinDatacomPropsChange() {
if (this.collection) {
this.debounceGet();
}
},
initDefVal() {
let defValue = ''
if ((this.valueCom || this.valueCom === 0) && !this.isDisabled(this.valueCom)) {
defValue = this.valueCom
} else {
let strogeValue
if (this.collection) {
strogeValue = this.getCache()
}
if (strogeValue || strogeValue === 0) {
defValue = strogeValue
} else {
let defItem = ''
if (this.defItem > 0 && this.defItem <= this.mixinDatacomResData.length) {
defItem = this.mixinDatacomResData[this.defItem - 1][this.dataValue]
}
defValue = defItem
}
if (defValue || defValue === 0) {
this.emit(defValue)
}
}
if (this.multiple) {
const mixinDatacomResData = this.mixinDatacomResData
this.current = defValue.map(item => {
const current = mixinDatacomResData.find(e => {
return e[this.dataValue] == item
})
return {
...current
}
})
this.currentArr = this.current.map(e => e[this.dataValue])
if (this.valueCom.length < 1) {
this.currentArr = []
}
} else {
const def = this.mixinDatacomResData.find(item => item[this.dataValue] === defValue)
this.current = def ? this.formatItemName(def) : ''
}
},
/**
* @param {[String, Number]} value
* 判断用户给的 value 是否同时为禁用状态
*/
isDisabled(value) {
let isDisabled = false;
this.mixinDatacomResData.forEach(item => {
if (item[this.dataValue] === value) {
isDisabled = item.disable
}
})
return isDisabled;
},
inputChange(e) {
this.$emit('inputChange', e.detail.value)
},
clearVal() {
if (this.disabled) {
return
}
if (this.multiple) {
this.current = []
this.currentArr = []
this.emit([])
} else {
this.current = ""
this.currentArr = []
this.emit('')
}
if (this.collection) {
this.removeCache()
}
this.placeholderOld = this.placeholder
this.filterInput = ""
},
change(item) {
if (!item.disable) {
this.showSelector = false
if (this.multiple) {
if (!this.current) {
this.current = []
}
if (!this.currentArr) {
this.currentArr = []
}
if (this.currentArr.includes(item[this.dataValue])) {
let index = this.current.findIndex(e => {
return e[this.dataValue] == item[this.dataValue]
})
this.current.splice(index, 1)
this.currentArr.splice(index, 1)
this.emit(this.current)
} else {
this.current.push(item)
this.currentArr.push(item[this.dataValue])
this.emit(this.current)
}
this.filterInput = ""
} else {
this.current = this.formatItemName(item)
if (this.filterable) {
this.filterInput = item[this.dataKey]
}
this.emit(item[this.dataValue])
}
}
},
delItem(item) {
if (this.disabled) {
return
}
if (this.currentArr.includes(item[this.dataValue])) {
let index = this.current.findIndex(e => {
return e[this.dataValue] == item[this.dataValue]
})
this.current.splice(index, 1)
this.currentArr.splice(index, 1)
this.emit(this.current)
}
},
emit(val) {
if (this.multiple) {
this.$emit('input', this.currentArr)
this.$emit('update:modelValue', this.currentArr)
} else {
this.$emit('input', val)
this.$emit('update:modelValue', val)
}
if (this.collection) {
this.setCache(val);
}
this.$emit('change', val)
},
toggleSelector() {
if (this.disabled) {
return
}
// if (this.filterable && this.filterInput && this.mixinDatacomResData.findIndex(e => {
// return e[this.dataKey] == this
// .filterInput
// }) < 0) {
// if (!this.multiple) {
// this.filterInput = ""
// }
// }
this.showSelector = !this.showSelector
this.isFocus = this.showSelector
if (this.filterable && this.current && this.showSelector) {
if (!this.multiple) {
this.placeholderOld = this.current
// this.filterInput = ""
}
} else if (this.filterable && !this.current && !this.showSelector) {
if (this.placeholderOld != this.placeholder) {
if (!this.multiple) {
this.current = this.placeholderOld
}
}
}
this.filterInput = ""
},
formatItemName(item) {
if (!item) {
return ""
}
let text = item[this.dataKey]
let value = item[this.dataValue]
let {
channel_code
} = item
channel_code = channel_code ? `(${channel_code})` : ''
if (this.format) {
// 格式化输出
let str = "";
str = this.format;
for (let key in item) {
str = str.replace(new RegExp(`{${key}}`, "g"), item[key]);
}
return str;
} else {
return this.collection.indexOf('app-list') > 0 ?
`${text}(${value})` :
(
text ?
text :
`未命名${channel_code}`
)
}
},
// 获取当前加载的数据
getLoadData() {
return this.mixinDatacomResData;
},
// 获取当前缓存key
getCurrentCacheKey() {
return this.collection;
},
// 获取缓存
getCache(name = this.getCurrentCacheKey()) {
let cacheData = uni.getStorageSync(this.cacheKey) || {};
return cacheData[name];
},
// 设置缓存
setCache(value, name = this.getCurrentCacheKey()) {
let cacheData = uni.getStorageSync(this.cacheKey) || {};
cacheData[name] = value;
uni.setStorageSync(this.cacheKey, cacheData);
},
// 删除缓存
removeCache(name = this.getCurrentCacheKey()) {
let cacheData = uni.getStorageSync(this.cacheKey) || {};
delete cacheData[name];
uni.setStorageSync(this.cacheKey, cacheData);
},
}
}
</script>
<style lang="scss">
$uni-base-color: #6a6a6a !default;
$uni-main-color: #333 !default;
$uni-secondary-color: #909399 !default;
$uni-border-3: #e5e5e5;
/* #ifndef APP-NVUE */
@media screen and (max-width: 500px) {
.hide-on-phone {
display: none;
}
}
/* #endif */
.uni-stat__select {
display: flex;
align-items: center;
// padding: 15px;
cursor: pointer;
width: 100%;
flex: 1;
box-sizing: border-box;
}
.uni-stat-box {
width: 100%;
flex: 1;
}
.uni-stat__actived {
width: 100%;
flex: 1;
// outline: 1px solid #2979ff;
}
.uni-label-text {
font-size: 14px;
font-weight: bold;
color: $uni-base-color;
margin: auto 0;
margin-right: 5px;
}
.uni-select {
font-size: 14px;
border: 1px solid $uni-border-3;
box-sizing: border-box;
border-radius: 4px;
padding: 0 5px;
padding-left: 10px;
position: relative;
/* #ifndef APP-NVUE */
display: flex;
user-select: none;
/* #endif */
flex-direction: row;
align-items: center;
border-bottom: solid 1px $uni-border-3;
width: 100%;
flex: 1;
height: 35px;
min-height: 35px;
&--disabled {
background-color: #f5f7fa;
cursor: not-allowed;
}
}
.uni-select__label {
font-size: 16px;
// line-height: 22px;
min-height: 35px;
height: 35px;
padding-right: 10px;
color: $uni-secondary-color;
}
.uni-select__input-box {
height: 35px;
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
align-items: center;
.tag-calss {
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
font-size: 12px;
border: 1px solid #d9ecff;
border-radius: 4px;
white-space: nowrap;
height: 24px;
padding: 0 4px 0px 8px;
line-height: 22px;
box-sizing: border-box;
margin: 2px 0 2px 6px;
display: flex;
max-width: 100%;
align-items: center;
background-color: #f4f4f5;
border-color: #e9e9eb;
color: #909399;
.text {
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
font-weight: 400;
-webkit-font-smoothing: antialiased;
-webkit-tap-highlight-color: transparent;
font-size: 12px;
white-space: nowrap;
line-height: 22px;
color: #909399;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
.uni-select__input {
flex: 1;
font-size: 14px;
height: 22px;
line-height: 22px;
}
.uni-select__input-plac {
font-size: 14px;
color: $uni-secondary-color;
}
.uni-select__selector {
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
position: absolute;
top: calc(100% + 12px);
left: 0;
width: 100%;
background-color: #FFFFFF;
border: 1px solid #EBEEF5;
border-radius: 6px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 3;
padding: 4px 0;
}
.uni-select__selector-scroll {
/* #ifndef APP-NVUE */
max-height: 200px;
box-sizing: border-box;
/* #endif */
}
.uni-select__selector-empty,
.uni-select__selector-item {
/* #ifndef APP-NVUE */
display: flex;
cursor: pointer;
/* #endif */
line-height: 35px;
font-size: 14px;
text-align: center;
/* border-bottom: solid 1px $uni-border-3; */
padding: 0px 10px;
}
.uni-select__selector-item:hover {
background-color: #f9f9f9;
}
.uni-select__selector-empty:last-child,
.uni-select__selector-item:last-child {
/* #ifndef APP-NVUE */
border-bottom: none;
/* #endif */
}
.uni-select__selector__disabled {
opacity: 0.4;
cursor: default;
}
/* picker 弹出层通用的指示小三角 */
.uni-popper__arrow,
.uni-popper__arrow::after {
position: absolute;
display: block;
width: 0;
height: 0;
border-color: transparent;
border-style: solid;
border-width: 6px;
}
.uni-popper__arrow {
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
top: -6px;
left: 10%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
.uni-popper__arrow::after {
content: " ";
top: 1px;
margin-left: -6px;
border-top-width: 0;
border-bottom-color: #fff;
}
.uni-select__input-text {
// width: 280px;
width: 90%;
color: $uni-main-color;
white-space: nowrap;
text-overflow: ellipsis;
-o-text-overflow: ellipsis;
overflow: hidden;
}
.uni-select__input-placeholder {
color: $uni-base-color;
font-size: 12px;
}
.uni-select--mask {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
}
</style>

View File

@@ -0,0 +1,85 @@
{
"id": "zxz-uni-data-select",
"displayName": "zxz-uni-data-select 下拉框选择器(添加下拉框检索,多选功能,多选搜索功能,自定义数据)",
"version": "1.0.12",
"description": "通过数据驱动的下拉框选择器(添加下拉框检索,多选功能,多选搜索功能,自定义数据)",
"keywords": [
"uni-ui",
"select",
"uni-data-select",
"下拉框",
"下拉选"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.1"
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-load-more"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "u",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"京东": "y"
},
"快应用": {
"华为": "y",
"联盟": "y"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
## DataSelect 下拉框选择器
> **组件名zxz-uni-data-select**
> 代码块: `zxz-uni-data-select`
当选项过多时,使用下拉菜单展示并选择内容
## API
### zxz-uni-data-select Props
| 属性名 | 类型 | 默认值 | 说明 |
| - | - | - | - |
| v-model | String、Array、Number |- | 选中项绑定值 |
| multiple | Boolean | false | 是否多选 |
| disabled | Boolean |false | 是否禁用 |
| dataKey | String |"key" | 作为 key 唯一标识的键名 |
| dataValue | String | "value" | 作为 value 唯一标识的键名 |
| collapseTags | Boolean | false | 多选时是否将选中值按文字的形式展示|
|collapseTagsNum|Number | 1 | 多选时选中值按文字的形式展示的数量|
| localdata | Array |- | 下拉列表本地数据 |
|label | String | - | 左侧标题
|placeholder | String | "请选择" | 输入框的提示文字
|emptyTips | String |"无选项" | 无选项提示
|clear | Boolean | true| 是否清空
|format | String | - | 格式化输出 用法 field="_id as value, version as text, uni_platform as label" format="{label} - {text}"
#### 如使用过程中有任何问题或者您对组件有一些好的建议欢迎加微weiyila520

View File

@@ -21,117 +21,50 @@ export const handLogin = (user, password) => request({
}
})
// 菜单
export const authority = () => {
let res = {
sonTree: [
{menu_id: '1', imgsrc: 'RF01', name: '呼叫管理', path: '/pages/modules/callmanage'},
{menu_id: '2', imgsrc: 'RF02', name: '指令管理', path: '/pages/modules/zlmanage'},
{menu_id: '3', imgsrc: 'RF03', name: '任务管理', path: '/pages/modules/taskmanage'}
]
}
return res
}
/**
* 点管理
* 点管理
*/
// 1.1查询所有区域信息
// 1.1查询区域
export const queryArea = () => request({
url:'api/hand/queryArea',
url:'api/hand/region',
data: {}
})
// export const queryArea = () => {
// let res = {
// result: [{region_code: '1', region_name: 'A1'}, {region_code: '2', region_name: 'A2'}, {region_code: '3', region_name: 'A2'}, {region_code: '4', region_name: 'A10'}]
// result: [{value: '1', label: 'A1'}, {value: '2', label: 'A2'}]
// }
// return res
// }
// 1.2根据区域查询设备编号及状态
// 1.2查询点位
export const queryPointByArea = (code) => request({
url:'api/hand/queryPointByArea',
url:'api/hand/point',
data: {
areaCode: code
region_code: code
}
})
// export const queryPointByArea = () => {
// let res = {
// result: [{
// device_code: '1',
// device_name: 'JLDFJLLJ'
// }, {
// device_code: '12',
// device_name: 'JLDFJLLJ'
// }, {
// device_code: '13',
// device_name: 'JLDFJLLJ'
// }, {
// device_code: '14',
// device_name: 'JLDFJLLJ'
// }, {
// device_code: '15',
// device_name: 'JLDFJLLJ'
// }, {
// device_code: '16',
// device_name: 'JLDFJLLJ'
// }, {
// device_code: '17',
// device_name: 'JLDFJLLJ'
// }]
// result: [{device_code: '1', device_name: 'JLDFJLLJ', status: '0', material_type: '1', qty: '10'}, {device_code: '2', device_name: 'JLDFJLLJ2'}]
// }
// return res
// }
/**
* 呼叫管理
*/
// 1.1创建任务(确定起点)
export const callTask = (scodes, code) => request({
url:'api/hand/callTask',
// 1.3查询物料
export const handMaterial = () => request({
url:'api/hand/material',
data: {}
})
// export const handMaterial = () => {
// let res = {
// result: [{value: '1', label: 'a'}, {value: '2', label: 'b'}, {value: '3', label: 'abc'}]
// }
// return res
// }
// 1.4点位操作
export const handPointOpt = (type, mtype, qty) => request({
url:'api/hand/pointOpt',
data: {
start_device_codes: scodes,
next_device_code: code
}
})
/**
* 指令管理
*/
// 1.1查询未完成指令
export const queryInstraction = (keyword, scode, ncode) => request({
url:'api/hand/insts',
data: {
keyword: keyword,
start_devicecode: scode,
next_devicecode: ncode
}
})
//1.2 指令操作
export const instOperation = (uuid, type) => request({
url:'api/hand/inst',
data: {
inst_uuid: uuid,
type: type
}
})
/**
* 任务管理
*/
// 1.1 查询未完成指令
export const queryTask = (keyword, scode, ncode) => request({
url:'api/hand/tasks',
data: {
keyword: keyword,
start_devicecode: scode,
next_devicecode: ncode
}
})
// 1.2 指令操作
export const taskOperation = (uuid, type) => request({
url:'api/hand/taskoperation',
data: {
inst_uuid: uuid,
type: type
type: type,
material_type: mtype,
qty: qty
}
})