Commit fec135c8dcdbe9ce2e604420090cbe2affbc378f
1 parent
dda8d67e
feat: 新增派单下发,增加企业负责人角色
Showing
27 changed files
with
3218 additions
and
609 deletions
Too many changes to show.
To preserve performance only 27 of 29 files are displayed.
garbage-removal/src/apis/order.js
| @@ -44,7 +44,28 @@ export async function uploadEvaluate(params, config) { | @@ -44,7 +44,28 @@ export async function uploadEvaluate(params, config) { | ||
| 44 | return await request.post(`/order/evaluate`, params, config); | 44 | return await request.post(`/order/evaluate`, params, config); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | - | 47 | +/** |
| 48 | + * 匿名访问 | ||
| 49 | + * @param {*} orderId | ||
| 50 | + * @returns | ||
| 51 | + */ | ||
| 48 | export async function queryGuestOrderDetail(orderId) { | 52 | export async function queryGuestOrderDetail(orderId) { |
| 49 | return await request.get(`/order/webDetail/${orderId}`); | 53 | return await request.get(`/order/webDetail/${orderId}`); |
| 50 | } | 54 | } |
| 55 | + | ||
| 56 | +/** | ||
| 57 | + * 查询公司下运输驾驶员 | ||
| 58 | + * @param {*} companyId | ||
| 59 | + */ | ||
| 60 | +export async function queryOrderDispatch(orderId) { | ||
| 61 | + return await request.get(`/order/queryDispatch/${orderId}`); | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | + | ||
| 65 | +export async function dispatchOrders(params,config) { | ||
| 66 | + return await request.put('/order/dispatch', params,config); | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +export async function queryOrderHandlerStatus(orderId, config) { | ||
| 70 | + return await request.get(`/order/queryOrderHandlerStatus/${orderId}`, config); | ||
| 71 | +} |
garbage-removal/src/components/clash-dispatch/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <next-tree :changeVerify="changeVerify" :title="getTitle" ref="nextTreeRef" :checkStrictly="checkStrictly" | ||
| 3 | + :selectParent="selectParent" :multiple="multiple" :treeData="treeData" @cancel="close" @confirm="onconfirm"> | ||
| 4 | + <!-- label插槽示意代码 --> | ||
| 5 | + <!-- <template #label="{data: {id, label, iconSrc, prev, post}}"> | ||
| 6 | + <view class="line-block"> | ||
| 7 | + <image class="img" v-if="iconSrc" :src="iconSrc"></image> | ||
| 8 | + <text space="nbsp" v-if="prev">{{prev}} </text><text>{{label}}</text><text space="nbsp" v-if="post"> {{post}}</text> | ||
| 9 | + </view> | ||
| 10 | + </template> --> | ||
| 11 | + <!-- <template #topBar> | ||
| 12 | + <view style="color: #666;padding:5px;"><text style="font-size: 12px;">历史记录</text></view> | ||
| 13 | + <view style="display: flex;justify-content: space-between;padding-bottom: 10px;border-bottom: 1rpx solid #f0f0f0;"> | ||
| 14 | + <button @click="checkedFunc('1-3-3-4')" :style="'background-color:'+ (activeId === '1-3-3-4' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">北京区-4</button> | ||
| 15 | + <button @click="checkedFunc('3-1-2')" :style="'background-color:'+ (activeId === '3-1-2' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-2</button> | ||
| 16 | + <button @click="checkedFunc('3-1-6')" :style="'background-color:'+ (activeId === '3-1-6' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-5</button> | ||
| 17 | + </view> | ||
| 18 | + </template> --> | ||
| 19 | + </next-tree> | ||
| 20 | +</template> | ||
| 21 | + | ||
| 22 | +<script setup > | ||
| 23 | +import { nextTick, ref, unref } from 'vue'; | ||
| 24 | +// @ts-ignore | ||
| 25 | +import nextTree from '../next-tree/next-tree.vue'; | ||
| 26 | +const props = defineProps({ | ||
| 27 | + dataList: { | ||
| 28 | + type: Array, | ||
| 29 | + default: [] | ||
| 30 | + }, | ||
| 31 | + valueKey: { | ||
| 32 | + type: String, | ||
| 33 | + default: 'id' | ||
| 34 | + }, | ||
| 35 | + multiple: { | ||
| 36 | + type: Boolean, | ||
| 37 | + default: true | ||
| 38 | + }, | ||
| 39 | + selectParent: { | ||
| 40 | + type: Boolean, | ||
| 41 | + default: false | ||
| 42 | + }, | ||
| 43 | + checkStrictly: { | ||
| 44 | + type: Boolean, | ||
| 45 | + default: false | ||
| 46 | + }, | ||
| 47 | + onconfirm: { | ||
| 48 | + type: Function, | ||
| 49 | + default: () => { } | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | +}) | ||
| 53 | +const treeData = ref([]) | ||
| 54 | +const nextTreeRef = ref() | ||
| 55 | +function getTitle(checked) { | ||
| 56 | + return `已选:${checked.length}位驾驶员` | ||
| 57 | +} | ||
| 58 | +function changeVerify(current, chooseList) { | ||
| 59 | + // 注意:返回非空字符串会阻止原有行为,并提示返回的字符串 | ||
| 60 | + // 如果函数体不做return返回值,即验证通过,控件正常处理业务 | ||
| 61 | + // 限制条件 | ||
| 62 | + if (chooseList) { | ||
| 63 | + for (let index = 0; index < chooseList.length; index++) { | ||
| 64 | + const element = chooseList[index]; | ||
| 65 | + if (current.id.indexOf(element.id) === -1 && element.label.indexOf(current.label) != -1) { | ||
| 66 | + return "该驾驶员已经被选中了" | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | +function open(dataList) { | ||
| 72 | + treeData.value = handlerTreeData(dataList) | ||
| 73 | + treeData.value = treeData.value.filter(item => { | ||
| 74 | + return item.children[0].id | ||
| 75 | + }) | ||
| 76 | + setTimeout(() => { | ||
| 77 | + nextTick(() => { | ||
| 78 | + unref(nextTreeRef).showTree = true | ||
| 79 | + }) | ||
| 80 | + }, 0) | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +function handlerTreeData(dataList) { | ||
| 84 | + return dataList | ||
| 85 | + .map((item, index) => { | ||
| 86 | + return { | ||
| 87 | + "id": (index + 1), | ||
| 88 | + "licensePlateNumber": item.licensePlateNumber, | ||
| 89 | + "containerVolume": item.containerVolume + "方车", | ||
| 90 | + "label": item.containerVolume + "方车" + '-' + item.licensePlateNumber, | ||
| 91 | + "children": item.personnelInfo.map((childrenItem, childrenIndex) => { | ||
| 92 | + return { | ||
| 93 | + "id": (index + 1) + '-' + (childrenIndex + 1), | ||
| 94 | + "tel": childrenItem.tel, | ||
| 95 | + "name": childrenItem.name, | ||
| 96 | + "label": childrenItem.name + '-' + childrenItem.tel, | ||
| 97 | + "checked": childrenItem.checked, | ||
| 98 | + "carCode": item.licensePlateNumber, | ||
| 99 | + "disabled": childrenItem.checked ? true : childrenItem.tel ? false : true | ||
| 100 | + } | ||
| 101 | + }) | ||
| 102 | + } | ||
| 103 | + }) | ||
| 104 | +} | ||
| 105 | +function cleanTreeData(treeData) { | ||
| 106 | + treeData.map(item => { | ||
| 107 | + item.checked = false | ||
| 108 | + if (item.children && item.children.length) { | ||
| 109 | + cleanTreeData(item.children) | ||
| 110 | + } | ||
| 111 | + }) | ||
| 112 | +} | ||
| 113 | +function close() { | ||
| 114 | + // 清除treeData的选中状态 | ||
| 115 | + cleanTreeData(unref(treeData)) | ||
| 116 | +} | ||
| 117 | +defineExpose({ | ||
| 118 | + open, close, nextTreeRef | ||
| 119 | +}) | ||
| 120 | +</script> | ||
| 121 | +<style lang="scss"> | ||
| 122 | +.line-block { | ||
| 123 | + display: flex; | ||
| 124 | + flex-direction: row; | ||
| 125 | + justify-content: flex-start; | ||
| 126 | + align-items: center; | ||
| 127 | + | ||
| 128 | + .img { | ||
| 129 | + width: 40rpx; | ||
| 130 | + height: 40rpx; | ||
| 131 | + border-radius: 10rpx; | ||
| 132 | + margin: 0 20rpx; | ||
| 133 | + } | ||
| 134 | +} | ||
| 135 | +</style> |
garbage-removal/src/components/liu-delivery-time/liu-delivery-time.vue
| @@ -103,11 +103,21 @@ const getFutureDays = () => { | @@ -103,11 +103,21 @@ const getFutureDays = () => { | ||
| 103 | const year = date.getFullYear(); | 103 | const year = date.getFullYear(); |
| 104 | const month = (date.getMonth() + 1).toString().padStart(2, '0'); | 104 | const month = (date.getMonth() + 1).toString().padStart(2, '0'); |
| 105 | const day = date.getDate().toString().padStart(2, '0'); | 105 | const day = date.getDate().toString().padStart(2, '0'); |
| 106 | - | ||
| 107 | - days.push({ | ||
| 108 | - day: `${year}-${month}-${day}`, | ||
| 109 | - timeList: getTimeList() | ||
| 110 | - }); | 106 | + if (i === 0) { |
| 107 | + let hours = new Date().getHours(); | ||
| 108 | + if (hours >= 13) { | ||
| 109 | + continue; | ||
| 110 | + } | ||
| 111 | + days.push({ | ||
| 112 | + day: `${year}-${month}-${day}`, | ||
| 113 | + timeList: getCurrentDayTimeList(9, hours, 3) | ||
| 114 | + }); | ||
| 115 | + } else { | ||
| 116 | + days.push({ | ||
| 117 | + day: `${year}-${month}-${day}`, | ||
| 118 | + timeList: getTimeList() | ||
| 119 | + }); | ||
| 120 | + } | ||
| 111 | } | 121 | } |
| 112 | return days; | 122 | return days; |
| 113 | } | 123 | } |
| @@ -115,47 +125,58 @@ const getFutureDays = () => { | @@ -115,47 +125,58 @@ const getFutureDays = () => { | ||
| 115 | 125 | ||
| 116 | const getTimeList = () => { | 126 | const getTimeList = () => { |
| 117 | const timeList = [{ | 127 | const timeList = [{ |
| 118 | - time: '06:00-08:00', | ||
| 119 | - start: '06:00', | ||
| 120 | - end: '08:00' | ||
| 121 | - }, { | ||
| 122 | - time: '08:00-10:00', | ||
| 123 | - start: '08:00', | 128 | + time: '09:00-10:00', |
| 129 | + start: '09:00', | ||
| 124 | end: '10:00' | 130 | end: '10:00' |
| 125 | }, | 131 | }, |
| 126 | { | 132 | { |
| 127 | - time: '10:00-12:00', | 133 | + time: '10:00-11:00', |
| 128 | start: '10:00', | 134 | start: '10:00', |
| 129 | - end: '12:00' | 135 | + end: '11:00' |
| 130 | }, | 136 | }, |
| 131 | { | 137 | { |
| 132 | - time: '12:00-14:00', | ||
| 133 | - start: '12:00', | ||
| 134 | - end: '14:00' | 138 | + time: '11:00-12:00', |
| 139 | + start: '11:00', | ||
| 140 | + end: '12:00' | ||
| 135 | }, | 141 | }, |
| 136 | { | 142 | { |
| 137 | - time: '14:00-16:00', | ||
| 138 | - start: '14:00', | ||
| 139 | - end: '16:00' | 143 | + time: '12:00-13:00', |
| 144 | + start: '12:00', | ||
| 145 | + end: '13:00' | ||
| 140 | }, | 146 | }, |
| 141 | { | 147 | { |
| 142 | - time: '16:00-18:00', | ||
| 143 | - start: '16:00', | ||
| 144 | - end: '18:00' | 148 | + time: '13:00-14:00', |
| 149 | + start: '13:00', | ||
| 150 | + end: '14:00' | ||
| 145 | }, | 151 | }, |
| 146 | { | 152 | { |
| 147 | - time: '18:00-20:00', | ||
| 148 | - start: '18:00', | ||
| 149 | - end: '20:00' | 153 | + time: '14:00-15:00', |
| 154 | + start: '14:00', | ||
| 155 | + end: '15:00' | ||
| 150 | }, | 156 | }, |
| 151 | { | 157 | { |
| 152 | - time: '20:00-22:00', | ||
| 153 | - start: '20:00', | ||
| 154 | - end: '22:00' | 158 | + time: '15:00-16:00', |
| 159 | + start: '15:00', | ||
| 160 | + end: '16:00' | ||
| 155 | } | 161 | } |
| 156 | ]; | 162 | ]; |
| 157 | return timeList | 163 | return timeList |
| 158 | } | 164 | } |
| 165 | + | ||
| 166 | +/** | ||
| 167 | + * | ||
| 168 | + * @param {*} startTime 从几点开始 | ||
| 169 | + * @param {*} hours 当前几点 | ||
| 170 | + * @param {*} skip 跳过几个 | ||
| 171 | + */ | ||
| 172 | +const getCurrentDayTimeList = (startTime, hours, skip) => { | ||
| 173 | + const timeList = getTimeList(); | ||
| 174 | + // 因为从9点开始所以从9点开始截取 | ||
| 175 | + // let startIndex = startTime + skip; | ||
| 176 | + let abs = startTime > hours ? 1 : -1; | ||
| 177 | + let index = startTime - hours >= skip ? 0 : (startTime - hours) * abs + skip; | ||
| 178 | + return timeList.slice(index, timeList.length + 1) | ||
| 179 | +} | ||
| 159 | const open = () => { | 180 | const open = () => { |
| 160 | isShow.value = true; | 181 | isShow.value = true; |
| 161 | init(); | 182 | init(); |
| @@ -163,7 +184,7 @@ const open = () => { | @@ -163,7 +184,7 @@ const open = () => { | ||
| 163 | const handleDateClick = (index) => { | 184 | const handleDateClick = (index) => { |
| 164 | selectedIndex.value = index; | 185 | selectedIndex.value = index; |
| 165 | selectedDay.value = days.value[index]; | 186 | selectedDay.value = days.value[index]; |
| 166 | - selectedTimeIndex.value = 999; | 187 | + selectedTimeIndex.value = 10075; |
| 167 | 188 | ||
| 168 | } | 189 | } |
| 169 | const handleTimeClick = (index) => { | 190 | const handleTimeClick = (index) => { |
| @@ -387,7 +408,7 @@ defineExpose({ open }) | @@ -387,7 +408,7 @@ defineExpose({ open }) | ||
| 387 | } | 408 | } |
| 388 | 409 | ||
| 389 | .scroll-animation { | 410 | .scroll-animation { |
| 390 | - transition: all 0.25s linear; | 411 | + transition: all 0.4s linear; |
| 391 | } | 412 | } |
| 392 | 413 | ||
| 393 | .scroll-temp { | 414 | .scroll-temp { |
| @@ -402,7 +423,8 @@ defineExpose({ open }) | @@ -402,7 +423,8 @@ defineExpose({ open }) | ||
| 402 | right: 0; | 423 | right: 0; |
| 403 | bottom: 0; | 424 | bottom: 0; |
| 404 | background: rgba(0, 0, 0, 0.3); | 425 | background: rgba(0, 0, 0, 0.3); |
| 405 | - z-index: 998; | 426 | + z-index: 10075; |
| 427 | + transition-property: opacity; | ||
| 406 | } | 428 | } |
| 407 | 429 | ||
| 408 | .time-picker { | 430 | .time-picker { |
| @@ -469,7 +491,7 @@ defineExpose({ open }) | @@ -469,7 +491,7 @@ defineExpose({ open }) | ||
| 469 | .date.active { | 491 | .date.active { |
| 470 | font-size: 30rpx; | 492 | font-size: 30rpx; |
| 471 | font-weight: bold; | 493 | font-weight: bold; |
| 472 | - color: #007aff; | 494 | + color: #a9e08f; |
| 473 | } | 495 | } |
| 474 | 496 | ||
| 475 | .time-scroll { | 497 | .time-scroll { |
| @@ -492,6 +514,6 @@ defineExpose({ open }) | @@ -492,6 +514,6 @@ defineExpose({ open }) | ||
| 492 | .time.active { | 514 | .time.active { |
| 493 | font-size: 30rpx; | 515 | font-size: 30rpx; |
| 494 | font-weight: bold; | 516 | font-weight: bold; |
| 495 | - color: #007aff; | 517 | + color: #a9e08f; |
| 496 | } | 518 | } |
| 497 | </style> | 519 | </style> |
garbage-removal/src/components/next-tree/next-tree.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <view class="next-tree"> | ||
| 3 | + <view class="next-tree-mask" :class="{ 'show': showTree }" @tap="_cancel"></view> | ||
| 4 | + <view class="next-tree-cnt" :style="'top:' + top" | ||
| 5 | + :class="{ 'show': showTree, 'next-tree-cnt-page': uiMode === 'page' }"> | ||
| 6 | + <view v-if="_showTreeBar" class="next-tree-bar"> | ||
| 7 | + <view class="next-tree-bar-cancel" :style="{ 'color': cancelColor }" hover-class="hover-c" @tap="_cancel">取消 | ||
| 8 | + </view> | ||
| 9 | + <view class="next-tree-bar-title" :style="{ 'color': titleColor }">{{ customTitle }}</view> | ||
| 10 | + <view class="next-tree-bar-btns"> | ||
| 11 | + <view class="next-tree-bar-cancel" :style="{ 'color': cancelColor }" hover-class="hover-c" @tap="_clear">清空 | ||
| 12 | + </view> | ||
| 13 | + <view class="btn-divid"></view> | ||
| 14 | + <view class="next-tree-bar-confirm" :style="{ 'color': _themeColor }" hover-class="hover-c" @tap="_confirm">确定 | ||
| 15 | + </view> | ||
| 16 | + </view> | ||
| 17 | + </view> | ||
| 18 | + <view class="next-tree-view" :style="'top:' + (_showTreeBar ? '72rpx' : '0rpx')"> | ||
| 19 | + <next-search-more v-if="ifSearch" @search="onSearch" mode="center" placeholder="请输入关键字" | ||
| 20 | + :isFixedSearchBtn="false" /> | ||
| 21 | + <slot name="topBar"></slot> | ||
| 22 | + <scroll-view class="next-tree-view-sc" :scroll-y="true"> | ||
| 23 | + <view v-show="_treeList.length"> | ||
| 24 | + <block v-for="(item, index) in _treeList" :key="index"> | ||
| 25 | + <view class="next-tree-item-block" v-if="item.show"> | ||
| 26 | + <view class="next-tree-item" :style="[{ | ||
| 27 | + paddingLeft: item.rank * 15 + 'px', | ||
| 28 | + zIndex: item.rank * -1 + 50 | ||
| 29 | + }]" :class="{ | ||
| 30 | + border: border === true, | ||
| 31 | + show: item.show, | ||
| 32 | + last: item.lastRank, | ||
| 33 | + showchild: item.showChild, | ||
| 34 | + open: item.open, | ||
| 35 | + disabled: item.disabled === true | ||
| 36 | +}"> | ||
| 37 | + <block v-if="showAuxiliaryLine"> | ||
| 38 | + <template v-if="item.rank > 1"> | ||
| 39 | + <view :key="i" v-for="i in (item.rank - 1)" | ||
| 40 | + :style="{ left: (6 * (2 * i - 1) + 3 * (i - 1)) + 'px' }" class="parent-horizontal-line"></view> | ||
| 41 | + </template> | ||
| 42 | + <view class="left-line"> | ||
| 43 | + <view v-if="item.lastRank" class="horizontal-line"></view> | ||
| 44 | + </view> | ||
| 45 | + </block> | ||
| 46 | + <view class="next-tree-label" @tap.stop="_treeItemTap(item, index)"> | ||
| 47 | + <image class="next-tree-icon" | ||
| 48 | + :src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon"></image> | ||
| 49 | + <rich-text :nodes="getNodes(item.ouputText)" :selectable="false" | ||
| 50 | + v-if="ifSearch && searchModel === 'depHighlight' && keywords"></rich-text> | ||
| 51 | + <slot v-else-if="$slots.label" name="label" :data="_getLabelSlotData(item)"></slot> | ||
| 52 | + <rich-text v-else-if="item.checked && !item.disabled" :nodes="getThemeNodes(item.name)"></rich-text> | ||
| 53 | + <text v-else>{{ item.name }}</text> | ||
| 54 | + </view> | ||
| 55 | + <view class="next-tree-check" @tap.stop="_treeItemSelect(item, index)" | ||
| 56 | + v-if="selectParent ? true : item.lastRank"> | ||
| 57 | + <view class="next-tree-check-yes" v-if="item.checked" :class="{ 'radio': !multiple }" | ||
| 58 | + :style="{ 'border-color': item.disabled ? '#ccc' : _themeColor, 'background-color': item.disabled ? '#ccc' : _themeColor }"> | ||
| 59 | + <view class="next-tree-check-yes-b" | ||
| 60 | + :style="{ 'background-color': item.disabled ? '#ccc' : _themeColor }"> | ||
| 61 | + <text v-if="item.checked" class="icon-text">✔</text> | ||
| 62 | + </view> | ||
| 63 | + </view> | ||
| 64 | + <view class="next-tree-check-no" v-else :class="{ 'radio': !multiple }" | ||
| 65 | + :style="{ 'border-color': item.disabled ? '#ccc' : _themeColor }"> | ||
| 66 | + <text v-if="showHalfChecked(item) && showHalfCheckedTips" | ||
| 67 | + :style="{ 'color': item.disabled ? '#ccc' : _themeColor, 'font-weight': 'blod', 'font-size': '10px' }" | ||
| 68 | + class="icon-text">一</text> | ||
| 69 | + </view> | ||
| 70 | + </view> | ||
| 71 | + </view> | ||
| 72 | + </view> | ||
| 73 | + </block> | ||
| 74 | + </view> | ||
| 75 | + <view v-show="!_treeList.length"> | ||
| 76 | + <slot v-if="$slots.empty" name="empty"></slot> | ||
| 77 | + <view class="empty" v-else><text>暂无数据</text></view> | ||
| 78 | + </view> | ||
| 79 | + <view v-if="ifSearch" style="height: 80rpx"></view> | ||
| 80 | + <slot name="bottomBar"></slot> | ||
| 81 | + </scroll-view> | ||
| 82 | + </view> | ||
| 83 | + </view> | ||
| 84 | + <view class="fixed-bottom-bar"> | ||
| 85 | + <slot name="fixedBottomBar"></slot> | ||
| 86 | + </view> | ||
| 87 | + </view> | ||
| 88 | +</template> | ||
| 89 | + | ||
| 90 | +<script> | ||
| 91 | +export default { | ||
| 92 | + name: "next-tree", | ||
| 93 | + props: { | ||
| 94 | + uiMode: { | ||
| 95 | + type: String, | ||
| 96 | + default: 'popup' // popup(弹窗), page(页面) | ||
| 97 | + }, | ||
| 98 | + treeData: { | ||
| 99 | + type: Array, | ||
| 100 | + default: function () { | ||
| 101 | + return [] | ||
| 102 | + } | ||
| 103 | + }, | ||
| 104 | + valueKey: { | ||
| 105 | + type: String, | ||
| 106 | + default: 'id' | ||
| 107 | + }, | ||
| 108 | + labelKey: { | ||
| 109 | + type: String, | ||
| 110 | + default: 'label' | ||
| 111 | + }, | ||
| 112 | + disabledKey: { | ||
| 113 | + type: String, | ||
| 114 | + default: 'disabled' | ||
| 115 | + }, | ||
| 116 | + childrenKey: { | ||
| 117 | + type: String, | ||
| 118 | + default: 'children' | ||
| 119 | + }, | ||
| 120 | + title: { | ||
| 121 | + type: [String, Function], | ||
| 122 | + default: '' | ||
| 123 | + }, | ||
| 124 | + multiple: { // 是否可以多选 | ||
| 125 | + type: Boolean, | ||
| 126 | + default: false | ||
| 127 | + // default: true | ||
| 128 | + }, | ||
| 129 | + selectParent: { //是否可以选父级 | ||
| 130 | + type: Boolean, | ||
| 131 | + default: false | ||
| 132 | + }, | ||
| 133 | + foldAll: { //折叠时关闭所有已经打开的子集,再次打开时需要一级一级打开 | ||
| 134 | + type: Boolean, | ||
| 135 | + default: false | ||
| 136 | + }, | ||
| 137 | + themeColor: { // 主题颜色 | ||
| 138 | + type: String, | ||
| 139 | + default: '#53C21D' // #f9ae3d | ||
| 140 | + }, | ||
| 141 | + cancelColor: { // 取消按钮颜色 | ||
| 142 | + type: String, | ||
| 143 | + default: '' // #757575 | ||
| 144 | + }, | ||
| 145 | + titleColor: { // 标题颜色 | ||
| 146 | + type: String, | ||
| 147 | + default: '' // #757575 | ||
| 148 | + }, | ||
| 149 | + currentIcon: { // 展开时候的ic | ||
| 150 | + type: String, | ||
| 151 | + default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEQ0QTM0MzQ1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEQ0QTM0MzU1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRDRBMzQzMjVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRDRBMzQzMzVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PidwepsAAAK0SURBVHja7JxbTsJAFIYHww7ciStgCeoGvGxAiOsgURegoL5720AXYLiIr0aJviq3Zx3PhIEnKG3ndtr+f3KixrSUj/ZjzjClIqUUiFm2gAAQAREQEUAEREAERAQQAREQAREBREAEREBEEqa67h9RFDWllDv0awWYlqlQHmu1WjMRRMoV1QFttA12y3xRtdNczq8EsE4/f8FumX2q77ROvNXk8UGMEKdUz6tYJHljaZAbuyUH+UR1to5BEohTuqwPCeS4pAA/qY6o/kyHOAMCeRK3owJnj+rH1jjxhqpVsstaebCz6TmnHWyXyY+xHjSBWBY/bvSgadtXBj9u9KCN3rnIfkzkQVsTEEX0Y2IP2oKo/HhMICcFAThUcwVZNGU6FdbX/XURzkbVF4+ybGhjPrFdgP66QdXNurGtSdk6Xdb9nAJ8oDo3OQlsQZzkdPw41ONBo6vI5scDefRjZg+6gpg3Pxp50CXEvPjR2IOuIXL3oxUPuobI3Y9WPOgDIlc/WvOgL4iL/vqFCcD7LH0xB4hj7cfQ/fWH9qCT+FhG0tN+DBk1PzjOM0SVllixcsBT1AvYc/kAPhc0hRg/3uvxoCgKRN9+dOrBUBB9+9GpB0NC9OVH5x4MDdG1H714kANEV3705kEOEBf9dcPi/lQnsuvLg1wgSu3Ha0v7Uh4MMgUXeuG71H407a+VBy9CPQkOdw+MtB+nGbd/D+FBbhBNxo9SjwcngJjNj0E9yBFiFj8G9SBXiGn8GNyDnCEm8SMLD3KHGOdHNh7kDjHOj2w8mAeIi/5arX+c6b/fxHz9oADEdGdjR/fXCw/OOB5oVfCOgnepz8IB14PMw03jCmTE+QBx5z0gAmKSqK9OUF+hcAeIhu/QYr4Qie8rjW83hhMBERARQAREQAREBBABERCLnH8BBgA+TQI7U4t53AAAAABJRU5ErkJggg==' | ||
| 152 | + }, | ||
| 153 | + defaultIcon: { // 折叠时候的ic | ||
| 154 | + type: String, | ||
| 155 | + default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAACE0lEQVR4Xu3c200DMRCF4XEltJAOkEugA+ggpUAHoQMqiFMCdEAJUMEiS4mEELlIO7bPOeN9i6K1rG/952myyea1WiCtXmEuYBPR4RBMxInoIOCwhOtJLKVszWyXc/5y2BvNEq6I+/3+kFK6M7OHnPM7jcLKjbZAvD/uaZtzflm5P4rbWyJWgDcze1LPuzVihfxUz7sH4ilJ2bx7Isrm3RtRMu8RiHJ5j0SUyXs0okTeCIj0eSMh0uaNhkiZNyIiXd7IiDR5oyNS5M2ACJ83EyJs3myIkHkzIsLlzYwIkzc7IkTeCojD81ZCHJa3GuKQvBURu+etjNgtb3XELnlHQGyedyTEZnlHQ2ySd0RE97wjI7rlHR3RJe+JeIrbLOecD6ePpZQ6W1kn2epo4MUrPOKyLN8ppYq1+y1VStncOjIdGnFZlo+U0uOtWOeOY2TE12Ouq//pEA7xXL7XfvcufR8K0Svfv6CREN3yDYfYIt9QiK3yjYTYLF95xB75SiP2ylcZsVu+cogj8pVCHJWvEuKwfOkREfKlRkTJlxkRJl86RMR8qRBR82VChM0XHpEhX2hElnyREWnyhUNkzBcKkTVfJETafIcjKuQ7FFEl35GIMvl2R1TMtyuiar49EWXzbY5oZpv/hibXTF2h3+s60FRKeT6+3TjMS3nrA3ZFRD8xrfY3ER1kJ+JEdBBwWGKeRAfEH1wS5WFZSDB/AAAAAElFTkSuQmCC' | ||
| 156 | + }, | ||
| 157 | + lastIcon: { // 没有子集的ic | ||
| 158 | + type: String, | ||
| 159 | + default: '' | ||
| 160 | + }, | ||
| 161 | + border: { // 是否有分割线 | ||
| 162 | + type: Boolean, | ||
| 163 | + default: false | ||
| 164 | + }, | ||
| 165 | + checkStrictly: { // 只有在multiple为true状态下生效; 状态下节点选择完全受控(父子节点选中状态不再关联) | ||
| 166 | + type: Boolean, | ||
| 167 | + default: false | ||
| 168 | + }, | ||
| 169 | + checkStrictlyModel: { // 关联模式 weak: 弱关联;strong: 强关联 | ||
| 170 | + type: String, | ||
| 171 | + default: 'weak' | ||
| 172 | + }, | ||
| 173 | + showHalfCheckedTips: { // 只有在multiple为true, checkStrictly为false状态下生效; 父子节点选中状态不再关联,显示半选提示 | ||
| 174 | + type: Boolean, | ||
| 175 | + default: true | ||
| 176 | + }, | ||
| 177 | + ifSearch: { // 是否开启search模式 | ||
| 178 | + type: Boolean, | ||
| 179 | + default: true | ||
| 180 | + }, | ||
| 181 | + searchModel: { // 搜索模式配置 | ||
| 182 | + type: String, | ||
| 183 | + default: 'common' // depHighlight: 从属高亮;common: 一般 | ||
| 184 | + }, | ||
| 185 | + showAuxiliaryLine: { // 辅助线模式 | ||
| 186 | + type: Boolean, | ||
| 187 | + default: false | ||
| 188 | + }, | ||
| 189 | + loadData: { | ||
| 190 | + type: Function | ||
| 191 | + }, | ||
| 192 | + height: { | ||
| 193 | + type: Number, | ||
| 194 | + default: 500 | ||
| 195 | + }, | ||
| 196 | + changeVerify: { | ||
| 197 | + type: Function | ||
| 198 | + } | ||
| 199 | + }, | ||
| 200 | + data() { | ||
| 201 | + return { | ||
| 202 | + showTree: false, | ||
| 203 | + treeList: [], | ||
| 204 | + currentTreeData: [], | ||
| 205 | + selectIndex: -1, | ||
| 206 | + keywords: '', | ||
| 207 | + nodeInitContrl: {}, | ||
| 208 | + top: '' | ||
| 209 | + } | ||
| 210 | + }, | ||
| 211 | + computed: { | ||
| 212 | + _showTreeBar() { | ||
| 213 | + return this.uiMode === 'popup' | ||
| 214 | + }, | ||
| 215 | + _themeColor() { | ||
| 216 | + return this.themeColor || '#53C21D' | ||
| 217 | + }, | ||
| 218 | + _treeList() { | ||
| 219 | + if (this.ifSearch && this.keywords) { | ||
| 220 | + return this.treeList.filter(item => { | ||
| 221 | + return (item.name && item.name.indexOf(this.keywords) !== -1) | ||
| 222 | + }).map(item => { | ||
| 223 | + const o = JSON.parse(JSON.stringify(item)); | ||
| 224 | + if (o.showChild === false) { | ||
| 225 | + o.showChild = true; | ||
| 226 | + } | ||
| 227 | + if (o.show === false) { | ||
| 228 | + o.show = true; | ||
| 229 | + } | ||
| 230 | + return o | ||
| 231 | + }) | ||
| 232 | + } else { | ||
| 233 | + return this.treeList | ||
| 234 | + } | ||
| 235 | + }, | ||
| 236 | + customTitle() { | ||
| 237 | + if (typeof this.title === 'function') { | ||
| 238 | + return this.title(this._getCheckedParams()); | ||
| 239 | + } else { | ||
| 240 | + return this.title | ||
| 241 | + } | ||
| 242 | + } | ||
| 243 | + }, | ||
| 244 | + methods: { | ||
| 245 | + _show() { | ||
| 246 | + this.showTree = true | ||
| 247 | + }, | ||
| 248 | + _hide() { | ||
| 249 | + this.showTree = false | ||
| 250 | + }, | ||
| 251 | + _cancel() { | ||
| 252 | + this._hide() | ||
| 253 | + this.$emit("cancel", ''); | ||
| 254 | + }, | ||
| 255 | + _confirm() { | ||
| 256 | + // 处理所选数据 | ||
| 257 | + let rt = this._getCheckedParams(); | ||
| 258 | + this._hide() | ||
| 259 | + this.$emit("confirm", rt); | ||
| 260 | + }, | ||
| 261 | + _getLabelSlotData(item) { | ||
| 262 | + const _it = this.getItemFromTreeData(this.currentTreeData, item.id); | ||
| 263 | + const it = Object.assign({}, _it); | ||
| 264 | + delete it[this.childrenKey]; | ||
| 265 | + return it | ||
| 266 | + }, | ||
| 267 | + _getCheckedParams() { | ||
| 268 | + // 处理所选数据 | ||
| 269 | + let rt = [], | ||
| 270 | + obj = {}; | ||
| 271 | + this.treeList.forEach((v, i) => { | ||
| 272 | + if (this.treeList[i].checked) { | ||
| 273 | + obj = {} | ||
| 274 | + obj.parents = this.treeList[i].parents | ||
| 275 | + obj = Object.assign(obj, this.treeList[i].source) | ||
| 276 | + // 移除子元素 | ||
| 277 | + delete obj.children | ||
| 278 | + rt.push(obj) | ||
| 279 | + } | ||
| 280 | + }); | ||
| 281 | + return rt; | ||
| 282 | + }, | ||
| 283 | + checkedFunc(values, state = true) { | ||
| 284 | + if (values instanceof Array) { | ||
| 285 | + values.map(id => { | ||
| 286 | + const item = this.treeList.find(it => it.id === id); | ||
| 287 | + if (item) { | ||
| 288 | + item.checked = !!state | ||
| 289 | + } | ||
| 290 | + }) | ||
| 291 | + } else { | ||
| 292 | + const _item = this.treeList.find(it => it.id === values); | ||
| 293 | + if (_item) { | ||
| 294 | + _item.checked = !!state | ||
| 295 | + } | ||
| 296 | + } | ||
| 297 | + }, | ||
| 298 | + getRenderTreeList(list = [], rank = 0, parentId = [], parents = []) { | ||
| 299 | + const treeList = []; | ||
| 300 | + list.forEach(item => { | ||
| 301 | + const halfChecked = this.getHalfCheckedFormTreeData(item); | ||
| 302 | + let ouputText = ''; | ||
| 303 | + if (this.searchModel === 'depHighlight') { | ||
| 304 | + if (parents && parents.length) { | ||
| 305 | + ouputText = parents.map(item => item[this.labelKey]).join(' > '); | ||
| 306 | + ouputText = ouputText + ' > ' + item[this.labelKey]; | ||
| 307 | + } else { | ||
| 308 | + ouputText = item[this.labelKey]; | ||
| 309 | + } | ||
| 310 | + } | ||
| 311 | + treeList.push({ | ||
| 312 | + id: item[this.valueKey], | ||
| 313 | + name: item[this.labelKey], | ||
| 314 | + source: item, | ||
| 315 | + parentId, // 父级id数组 | ||
| 316 | + parents, // 父级id数组 | ||
| 317 | + rank, // 层级 | ||
| 318 | + showChild: false, //子级是否显示 | ||
| 319 | + open: false, //是否打开 | ||
| 320 | + show: rank === 0, // 自身是否显示 | ||
| 321 | + hideArr: [], | ||
| 322 | + ouputText, | ||
| 323 | + orChecked: item.checked ? item.checked : false, | ||
| 324 | + checked: item.checked ? item.checked : false, | ||
| 325 | + halfChecked, | ||
| 326 | + disabled: this.disabledKey && item[this.disabledKey] === true | ||
| 327 | + }) | ||
| 328 | + if ( | ||
| 329 | + (Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length > 0) || | ||
| 330 | + (this.loadData && Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length === 0) | ||
| 331 | + ) { | ||
| 332 | + let parentid = [...parentId], | ||
| 333 | + parentArr = [...parents], | ||
| 334 | + childrenid = []; | ||
| 335 | + delete parentArr.children | ||
| 336 | + parentid.push(item[this.valueKey]); | ||
| 337 | + parentArr.push({ | ||
| 338 | + [this.valueKey]: item[this.valueKey], | ||
| 339 | + [this.labelKey]: item[this.labelKey], | ||
| 340 | + }) | ||
| 341 | + // this._renderTreeList(item[this.childrenKey], rank + 1, parentid, parentArr); | ||
| 342 | + } else { | ||
| 343 | + treeList[treeList.length - 1].lastRank = true; | ||
| 344 | + } | ||
| 345 | + }) | ||
| 346 | + return treeList; | ||
| 347 | + }, | ||
| 348 | + //扁平化树结构 | ||
| 349 | + _renderTreeList(list = [], rank = 0, parentId = [], parents = []) { | ||
| 350 | + list.forEach(item => { | ||
| 351 | + const halfChecked = this.getHalfCheckedFormTreeData(item); | ||
| 352 | + let ouputText = ''; | ||
| 353 | + if (this.searchModel === 'depHighlight') { | ||
| 354 | + if (parents && parents.length) { | ||
| 355 | + ouputText = parents.map(item => item[this.labelKey]).join(' > '); | ||
| 356 | + ouputText = ouputText + ' > ' + item[this.labelKey]; | ||
| 357 | + } else { | ||
| 358 | + ouputText = item[this.labelKey]; | ||
| 359 | + } | ||
| 360 | + } | ||
| 361 | + this.treeList.push({ | ||
| 362 | + id: item[this.valueKey], | ||
| 363 | + name: item[this.labelKey], | ||
| 364 | + source: item, | ||
| 365 | + parentId, // 父级id数组 | ||
| 366 | + parents, // 父级id数组 | ||
| 367 | + rank, // 层级 | ||
| 368 | + showChild: false, //子级是否显示 | ||
| 369 | + open: false, //是否打开 | ||
| 370 | + show: rank === 0, // 自身是否显示 | ||
| 371 | + hideArr: [], | ||
| 372 | + ouputText, | ||
| 373 | + orChecked: item.checked ? item.checked : false, | ||
| 374 | + checked: item.checked ? item.checked : false, | ||
| 375 | + halfChecked, | ||
| 376 | + disabled: this.disabledKey && item[this.disabledKey] === true | ||
| 377 | + }) | ||
| 378 | + if ( | ||
| 379 | + (Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length > 0) || | ||
| 380 | + (this.loadData && Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length === 0) | ||
| 381 | + ) { | ||
| 382 | + let parentid = [...parentId], | ||
| 383 | + parentArr = [...parents], | ||
| 384 | + childrenid = []; | ||
| 385 | + delete parentArr.children | ||
| 386 | + parentid.push(item[this.valueKey]); | ||
| 387 | + parentArr.push({ | ||
| 388 | + [this.valueKey]: item[this.valueKey], | ||
| 389 | + [this.labelKey]: item[this.labelKey], | ||
| 390 | + "data": item | ||
| 391 | + }) | ||
| 392 | + this._renderTreeList(item[this.childrenKey], rank + 1, parentid, parentArr); | ||
| 393 | + } else { | ||
| 394 | + this.treeList[this.treeList.length - 1].lastRank = true; | ||
| 395 | + } | ||
| 396 | + }) | ||
| 397 | + }, | ||
| 398 | + // 处理默认选择 | ||
| 399 | + _defaultSelect() { | ||
| 400 | + this.treeList.forEach((v, i) => { | ||
| 401 | + if (v.checked) { | ||
| 402 | + this.treeList.forEach((v2, i2) => { | ||
| 403 | + if (v.parentId.toString().indexOf(v2.parentId.toString()) >= 0) { | ||
| 404 | + v2.show = true | ||
| 405 | + if (v.parentId.includes(v2.id)) { | ||
| 406 | + v2.showChild = true; | ||
| 407 | + v2.open = true; | ||
| 408 | + } | ||
| 409 | + } | ||
| 410 | + }) | ||
| 411 | + } | ||
| 412 | + }) | ||
| 413 | + }, | ||
| 414 | + // 点击 | ||
| 415 | + async _treeItemTap(item, _index) { | ||
| 416 | + const index = this.treeList.findIndex(it => it.id === item.id); | ||
| 417 | + if (item.lastRank === true) { | ||
| 418 | + if (item.disabled === true) return | ||
| 419 | + //点击最后一级时触发事件 | ||
| 420 | + this.treeList[index].checked = !this.treeList[index].checked; | ||
| 421 | + if (this.changeVerify && (typeof this.changeVerify === 'function')) { | ||
| 422 | + const current = Object.assign({}, item.source); | ||
| 423 | + current.checked = item.checked; | ||
| 424 | + const tip = this.changeVerify(current, this.multiple ? this._getCheckedParams() : [current]); | ||
| 425 | + if (tip) { | ||
| 426 | + this.treeList[index].checked = !this.treeList[index].checked; | ||
| 427 | + uni.showToast({ | ||
| 428 | + title: tip, | ||
| 429 | + icon: 'none' | ||
| 430 | + }); | ||
| 431 | + return | ||
| 432 | + } | ||
| 433 | + }; | ||
| 434 | + this.treeList[index].halfChecked = false; | ||
| 435 | + if (this.multiple && !this.checkStrictly && this.showHalfCheckedTips) { | ||
| 436 | + this.updateHalfChecked(index); | ||
| 437 | + } else if (this.multiple && this.checkStrictly) { | ||
| 438 | + this.updateParentChecked(index); | ||
| 439 | + } | ||
| 440 | + this._fixMultiple(index) | ||
| 441 | + return; | ||
| 442 | + } | ||
| 443 | + // loadData实现 | ||
| 444 | + const isLoadData = this.loadData && !this.nodeInitContrl[item.id]; | ||
| 445 | + if (isLoadData) { | ||
| 446 | + uni && uni.showLoading({ title: "请稍后..." }); | ||
| 447 | + const newChild = await this.loadData(this.treeList[index].source); | ||
| 448 | + // 为了保证treeData数据的完整性,异步加载的数据需要添加到treeData上; | ||
| 449 | + const treeItem = this.getItemFromTreeData(this.currentTreeData, item.id); | ||
| 450 | + treeItem[this.childrenKey] = newChild && newChild.length ? newChild : undefined; | ||
| 451 | + const parentId = item.parentId || []; | ||
| 452 | + const lists = this.getRenderTreeList(newChild || [], item.rank + 1, parentId.concat([item.id]), [{ [this.valueKey]: item[this.valueKey], [this.labelKey]: item[this.labelKey] }]); | ||
| 453 | + this.nodeInitContrl[item.id] = true; | ||
| 454 | + this.treeList.splice(index + 1, 0, ...lists); | ||
| 455 | + } | ||
| 456 | + const childLen = this.treeList.filter(it => it.parentId.includes(item.id)).length; | ||
| 457 | + if (!isLoadData && childLen > 50) { | ||
| 458 | + uni && uni.showLoading({ title: "请稍后..." }); | ||
| 459 | + } | ||
| 460 | + let list = this.treeList; | ||
| 461 | + let id = item.id; | ||
| 462 | + item.showChild = !item.showChild; | ||
| 463 | + item.open = item.showChild ? true : !item.open; | ||
| 464 | + list.forEach((childItem, i) => { | ||
| 465 | + if (item.showChild === false) { | ||
| 466 | + //隐藏所有子级 | ||
| 467 | + if (!childItem.parentId.includes(id)) { | ||
| 468 | + return; | ||
| 469 | + } | ||
| 470 | + if (!this.foldAll) { | ||
| 471 | + if (childItem.lastRank !== true && !childItem.open) { | ||
| 472 | + childItem.showChild = false; | ||
| 473 | + } | ||
| 474 | + // 为隐藏的内容添加一个标记 | ||
| 475 | + if (childItem.show) { | ||
| 476 | + childItem.hideArr[item.rank] = id | ||
| 477 | + } | ||
| 478 | + } else { | ||
| 479 | + if (childItem.lastRank !== true) { | ||
| 480 | + childItem.showChild = false; | ||
| 481 | + } | ||
| 482 | + } | ||
| 483 | + childItem.show = false; | ||
| 484 | + } else { | ||
| 485 | + // 打开子集 | ||
| 486 | + if (childItem.parentId[childItem.parentId.length - 1] === id) { | ||
| 487 | + childItem.show = true; | ||
| 488 | + } | ||
| 489 | + // 打开被隐藏的子集 | ||
| 490 | + if (childItem.parentId.includes(id) && !this.foldAll) { | ||
| 491 | + // console.log(childItem.hideArr) | ||
| 492 | + if (childItem.hideArr[item.rank] === id) { | ||
| 493 | + childItem.show = true; | ||
| 494 | + if (childItem.open && childItem.showChild) { | ||
| 495 | + childItem.showChild = true | ||
| 496 | + } else { | ||
| 497 | + childItem.showChild = false | ||
| 498 | + } | ||
| 499 | + childItem.hideArr[item.rank] = null | ||
| 500 | + } | ||
| 501 | + } | ||
| 502 | + } | ||
| 503 | + }); | ||
| 504 | + setTimeout(() => { | ||
| 505 | + uni && uni.hideLoading() | ||
| 506 | + }) | ||
| 507 | + }, | ||
| 508 | + getThemeNodes(text) { | ||
| 509 | + const regex = new RegExp(`(${text || ''})`, 'gi'); | ||
| 510 | + return text ? text.replace(regex, `<span style="color: ${this._themeColor}">$1</span>`) : ''; | ||
| 511 | + }, | ||
| 512 | + getNodes(ouputText) { | ||
| 513 | + if (this.keywords && ouputText) { | ||
| 514 | + const regex = new RegExp(`(${this.keywords})`, 'gi'); | ||
| 515 | + return ouputText.replace(regex, `<span style="color: ${this._themeColor}">$1</span>`); | ||
| 516 | + } | ||
| 517 | + return ouputText | ||
| 518 | + }, | ||
| 519 | + getHalfCheckedFormTreeData(item) { | ||
| 520 | + if (this.checkStrictly) { | ||
| 521 | + return false; | ||
| 522 | + } else if (!this.showHalfCheckedTips) { | ||
| 523 | + return false | ||
| 524 | + } else { | ||
| 525 | + if (item[this.childrenKey] && item[this.childrenKey].length) { | ||
| 526 | + return item[this.childrenKey].some(it => { | ||
| 527 | + if (it.checked === true) { | ||
| 528 | + return true; | ||
| 529 | + } else if (it[this.childrenKey] && it[this.childrenKey].length) { | ||
| 530 | + return this.getHalfCheckedFormTreeData(it); | ||
| 531 | + } else { | ||
| 532 | + return false; | ||
| 533 | + }; | ||
| 534 | + }); | ||
| 535 | + } else { | ||
| 536 | + return false; | ||
| 537 | + } | ||
| 538 | + } | ||
| 539 | + }, | ||
| 540 | + getItemFromTreeData(treeData, id) { | ||
| 541 | + if (id) { | ||
| 542 | + let item = null; | ||
| 543 | + (treeData || []).some(it => { | ||
| 544 | + if (it[this.valueKey] === id) { | ||
| 545 | + item = it | ||
| 546 | + return true | ||
| 547 | + } else if (it[this.childrenKey] && it[this.childrenKey].length) { | ||
| 548 | + item = this.getItemFromTreeData(it[this.childrenKey], id) | ||
| 549 | + return !!item | ||
| 550 | + } else { | ||
| 551 | + return false | ||
| 552 | + } | ||
| 553 | + }); | ||
| 554 | + return item | ||
| 555 | + }; | ||
| 556 | + return null | ||
| 557 | + }, | ||
| 558 | + _treeItemSelect(item, _index) { | ||
| 559 | + const index = this.treeList.findIndex(it => it.id === item.id); | ||
| 560 | + if (item.disabled === true) return | ||
| 561 | + this.treeList[index].checked = !this.treeList[index].checked; | ||
| 562 | + // console.log(index) | ||
| 563 | + if (this.changeVerify && (typeof this.changeVerify === 'function')) { | ||
| 564 | + const current = Object.assign({}, item.source); | ||
| 565 | + current.checked = item.checked; | ||
| 566 | + const tip = this.changeVerify(current, this.multiple ? this._getCheckedParams() : [current]); | ||
| 567 | + if (tip) { | ||
| 568 | + this.treeList[index].checked = !this.treeList[index].checked; | ||
| 569 | + uni.showToast({ | ||
| 570 | + title: tip, | ||
| 571 | + icon: 'none' | ||
| 572 | + }); | ||
| 573 | + return | ||
| 574 | + } | ||
| 575 | + }; | ||
| 576 | + this.treeList[index].halfChecked = false; | ||
| 577 | + if (this.multiple && this.checkStrictly) { | ||
| 578 | + if (!item.lastRank) { | ||
| 579 | + const source = item.source || {}; | ||
| 580 | + const children = source[this.childrenKey] || []; | ||
| 581 | + const checkedKeyList = this.getChildrenKeys(children); | ||
| 582 | + this.treeList.forEach((v, i) => { | ||
| 583 | + if (checkedKeyList.indexOf(v.id) !== -1) { | ||
| 584 | + if (this.checkStrictlyModel === 'weak') { | ||
| 585 | + if (!this.treeList[i].disabled) { | ||
| 586 | + this.treeList[i].checked = this.treeList[index].checked | ||
| 587 | + } | ||
| 588 | + } else if (this.checkStrictlyModel === 'strong') { | ||
| 589 | + this.treeList[i].checked = this.treeList[index].checked | ||
| 590 | + } | ||
| 591 | + } | ||
| 592 | + }) | ||
| 593 | + } | ||
| 594 | + this.updateParentChecked(index) | ||
| 595 | + } else if (this.multiple && !this.checkStrictly && this.showHalfCheckedTips) { | ||
| 596 | + this.updateHalfChecked(index); | ||
| 597 | + } else { | ||
| 598 | + this._fixMultiple(index); | ||
| 599 | + } | ||
| 600 | + }, | ||
| 601 | + updateParentChecked(index) { | ||
| 602 | + const parentId = (this.treeList[index].parentId || []).concat([]).reverse(); | ||
| 603 | + if (parentId && parentId.length) { | ||
| 604 | + parentId.map(id => { | ||
| 605 | + const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); | ||
| 606 | + const childrenIds = (parentTreeDataItem[this.childrenKey] || []).map(item => item[this.valueKey]); | ||
| 607 | + const bool = this.treeList | ||
| 608 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | ||
| 609 | + .every(it => it.checked === true); | ||
| 610 | + | ||
| 611 | + const _bool = this.treeList | ||
| 612 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | ||
| 613 | + .every(it => it.checked === false); | ||
| 614 | + | ||
| 615 | + const parentItem = this.treeList.find(it => it.id === id); | ||
| 616 | + if (parentItem) { | ||
| 617 | + if (this.checkStrictlyModel === 'weak') { | ||
| 618 | + if (bool && !parentItem.disabled) { | ||
| 619 | + parentItem.checked = true; | ||
| 620 | + } else if (_bool && !parentItem.disabled) { | ||
| 621 | + parentItem.checked = false; | ||
| 622 | + } | ||
| 623 | + } else if (this.checkStrictlyModel === 'strong') { | ||
| 624 | + if (bool) { | ||
| 625 | + parentItem.checked = true; | ||
| 626 | + } else { | ||
| 627 | + parentItem.checked = false; | ||
| 628 | + } | ||
| 629 | + } | ||
| 630 | + } | ||
| 631 | + }) | ||
| 632 | + } | ||
| 633 | + }, | ||
| 634 | + updateHalfChecked(index) { | ||
| 635 | + const _parentId = this.treeList[index].parentId || []; | ||
| 636 | + const parentId = _parentId.concat([]).reverse(); | ||
| 637 | + if (parentId && parentId.length) { | ||
| 638 | + parentId.map(id => { | ||
| 639 | + const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); | ||
| 640 | + const childrenIds = (parentTreeDataItem[this.childrenKey] || []).map(item => item[this.valueKey]); | ||
| 641 | + | ||
| 642 | + const bool = this.treeList | ||
| 643 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | ||
| 644 | + .every(it => it.checked === false && it.halfChecked === false); | ||
| 645 | + | ||
| 646 | + const _bool = this.treeList | ||
| 647 | + .filter(it => childrenIds.indexOf(it.id) !== -1) | ||
| 648 | + .some(it => it.checked === true || it.halfChecked === true); | ||
| 649 | + | ||
| 650 | + const parentItem = this.treeList.find(it => it.id === id); | ||
| 651 | + if (parentItem) { | ||
| 652 | + if (!parentItem.checked) { | ||
| 653 | + if (bool) { | ||
| 654 | + parentItem.halfChecked = false | ||
| 655 | + } else if (_bool) { | ||
| 656 | + parentItem.halfChecked = true | ||
| 657 | + } else { | ||
| 658 | + parentItem.halfChecked = false | ||
| 659 | + } | ||
| 660 | + } | ||
| 661 | + } | ||
| 662 | + }) | ||
| 663 | + } | ||
| 664 | + if (this.treeList[index].checked == false) { | ||
| 665 | + const source = this.treeList[index].source || {}; | ||
| 666 | + const children = source[this.childrenKey] || []; | ||
| 667 | + const checkedKeyList = this.getChildrenKeys(children); | ||
| 668 | + const bool = this.treeList.filter(item => checkedKeyList.indexOf(item.id) !== -1).some(item => item.checked); | ||
| 669 | + if (bool) { | ||
| 670 | + this.treeList[index].halfChecked = true; | ||
| 671 | + } | ||
| 672 | + } | ||
| 673 | + }, | ||
| 674 | + showHalfChecked(item) { | ||
| 675 | + if (this.multiple && !this.checkStrictly && item.halfChecked === true) { | ||
| 676 | + return true | ||
| 677 | + } else { | ||
| 678 | + return false | ||
| 679 | + } | ||
| 680 | + }, | ||
| 681 | + getChildrenKeys(children) { | ||
| 682 | + let keys = []; | ||
| 683 | + (children || []).map(item => { | ||
| 684 | + keys.push(item[this.valueKey]) | ||
| 685 | + if (item[this.childrenKey] && item[this.childrenKey].length) { | ||
| 686 | + keys = keys.concat(this.getChildrenKeys(item[this.childrenKey])) | ||
| 687 | + } | ||
| 688 | + }) | ||
| 689 | + return keys | ||
| 690 | + }, | ||
| 691 | + // 处理单选多选 | ||
| 692 | + _fixMultiple(index) { | ||
| 693 | + if (!this.multiple) { | ||
| 694 | + // 如果是单选 | ||
| 695 | + this.treeList.forEach((v, i) => { | ||
| 696 | + if (i != index) { | ||
| 697 | + this.treeList[i].checked = false | ||
| 698 | + } else { | ||
| 699 | + this.treeList[i].checked = true | ||
| 700 | + } | ||
| 701 | + }) | ||
| 702 | + } | ||
| 703 | + }, | ||
| 704 | + // 重置数据 | ||
| 705 | + _reTreeList() { | ||
| 706 | + this.treeList.forEach((v, i) => { | ||
| 707 | + this.treeList[i].checked = v.orChecked | ||
| 708 | + }) | ||
| 709 | + }, | ||
| 710 | + _initTree() { | ||
| 711 | + this.treeList.length = 0; | ||
| 712 | + if (this.loadData) { | ||
| 713 | + this.currentTreeData = JSON.parse(JSON.stringify(this.treeData)); | ||
| 714 | + } else { | ||
| 715 | + this.currentTreeData = this.treeData; | ||
| 716 | + } | ||
| 717 | + this._renderTreeList(this.currentTreeData); | ||
| 718 | + this.$nextTick(() => { | ||
| 719 | + this._defaultSelect(this.currentTreeData); | ||
| 720 | + }) | ||
| 721 | + }, | ||
| 722 | + _clear() { | ||
| 723 | + this.treeList.map(item => { | ||
| 724 | + if (this.multiple && this.checkStrictly) { | ||
| 725 | + if (this.checkStrictlyModel === 'strong') { | ||
| 726 | + item.checked = false; | ||
| 727 | + } else if (this.checkStrictlyModel === 'weak') { | ||
| 728 | + if (!item.disabled) { | ||
| 729 | + item.checked = false; | ||
| 730 | + }; | ||
| 731 | + } else { | ||
| 732 | + item.checked = false; | ||
| 733 | + } | ||
| 734 | + } else { | ||
| 735 | + if (!item.disabled) { | ||
| 736 | + item.checked = false; | ||
| 737 | + } | ||
| 738 | + }; | ||
| 739 | + | ||
| 740 | + item.halfChecked = false; | ||
| 741 | + }) | ||
| 742 | + this.$emit("clear"); | ||
| 743 | + }, | ||
| 744 | + onSearch(val) { | ||
| 745 | + this.keywords = val; | ||
| 746 | + }, | ||
| 747 | + initUiModePopup(watched) { | ||
| 748 | + uni.getSystemInfo({ | ||
| 749 | + success: (res) => { | ||
| 750 | + this.top = (res.windowHeight - this.height) + 'px'; | ||
| 751 | + } | ||
| 752 | + }); | ||
| 753 | + watched && watched(); | ||
| 754 | + watched = this.$watch(() => this.showTree, (bool) => { | ||
| 755 | + if (bool) { | ||
| 756 | + this._initTree(); | ||
| 757 | + } else { | ||
| 758 | + this.treeList.length = 0; | ||
| 759 | + this.nodeInitContrl = {}; | ||
| 760 | + } | ||
| 761 | + }, { immediate: true }); | ||
| 762 | + }, | ||
| 763 | + initUiModePage(watched) { | ||
| 764 | + this.top = '0px'; | ||
| 765 | + watched && watched(); | ||
| 766 | + watched = this.$watch(() => this.treeData, () => { | ||
| 767 | + this.treeList.length = 0; | ||
| 768 | + this.nodeInitContrl = {}; | ||
| 769 | + this.$nextTick(() => { | ||
| 770 | + this._initTree(); | ||
| 771 | + }); | ||
| 772 | + }, { immediate: true, deep: true }) | ||
| 773 | + this.$nextTick(() => { | ||
| 774 | + this.showTree = true; | ||
| 775 | + }); | ||
| 776 | + }, | ||
| 777 | + uiModeInit() { | ||
| 778 | + let watched = null; | ||
| 779 | + if (this.uiMode === 'popup') { | ||
| 780 | + this.initUiModePopup(watched); | ||
| 781 | + } else if (this.uiMode === 'page') { | ||
| 782 | + this.initUiModePage(watched); | ||
| 783 | + } else { | ||
| 784 | + this.initUiModePopup(watched); | ||
| 785 | + } | ||
| 786 | + } | ||
| 787 | + }, | ||
| 788 | + mounted() { | ||
| 789 | + this.uiModeInit(); | ||
| 790 | + } | ||
| 791 | +} | ||
| 792 | +</script> | ||
| 793 | + | ||
| 794 | +<style scoped> | ||
| 795 | +@import "./style.css"; | ||
| 796 | +</style> |
garbage-removal/src/components/next-tree/readme/changelog.md
0 → 100644
| 1 | +## 1.6.7(2024-01-04) | ||
| 2 | +修复异步加载节点搜索展示bug | ||
| 3 | +## 1.6.6(2023-12-29) | ||
| 4 | +修复next-tree异步加载节点关闭bug | ||
| 5 | +## 1.6.5(2023-12-21) | ||
| 6 | +fix bug | ||
| 7 | +## 1.6.4(2023-12-21) | ||
| 8 | +fix bug | ||
| 9 | +## 1.6.3(2023-12-21) | ||
| 10 | +更新vue2版本说明文档 | ||
| 11 | +## 1.6.2(2023-12-21) | ||
| 12 | +修复说明文档 | ||
| 13 | +## 1.6.1(2023-12-18) | ||
| 14 | +增加empty插槽 | ||
| 15 | +## 1.6.0(2023-12-18) | ||
| 16 | +增加empty插槽 | ||
| 17 | +## 1.5.9(2023-12-15) | ||
| 18 | +修改说明文件 | ||
| 19 | +## 1.5.8(2023-12-15) | ||
| 20 | +修复changeVerify函数单选时,返回参数bug | ||
| 21 | +## 1.5.7(2023-12-14) | ||
| 22 | +修复checkStrictlyModel === 'strong'的bug | ||
| 23 | +## 1.5.6(2023-12-13) | ||
| 24 | +代码优化 | ||
| 25 | +## 1.5.5(2023-12-13) | ||
| 26 | +优化changeVerify的使用 | ||
| 27 | +## 1.5.4(2023-12-12) | ||
| 28 | +修复提示层级问题 | ||
| 29 | +## 1.5.3(2023-12-12) | ||
| 30 | +优化uiMode=page模式下的使用 | ||
| 31 | +## 1.5.2(2023-12-11) | ||
| 32 | +增加uiMode配置,实现页面模式展示 | ||
| 33 | +## 1.5.1(2023-12-06) | ||
| 34 | +更新说明 | ||
| 35 | +## 1.5.0(2023-12-06) | ||
| 36 | +更新插件使用注意事项 | ||
| 37 | +## 1.4.9(2023-12-01) | ||
| 38 | +增加topBar插槽 | ||
| 39 | +## 1.4.8(2023-11-30) | ||
| 40 | +增加changeVerify验证函数,实现change的各种控制 | ||
| 41 | +## 1.4.7(2023-11-30) | ||
| 42 | +增加弹层容器高度可配置 | ||
| 43 | +## 1.4.6(2023-11-28) | ||
| 44 | +修复bug | ||
| 45 | +## 1.4.5(2023-11-28) | ||
| 46 | +修复disabled是,需要显示灰色不可操作 | ||
| 47 | +## 1.4.4(2023-11-28) | ||
| 48 | +增加说明 | ||
| 49 | +## 1.4.3(2023-11-28) | ||
| 50 | +增加主题配置 | ||
| 51 | +## 1.4.2(2023-11-28) | ||
| 52 | +增加异步加载时,子节点说明 | ||
| 53 | +## 1.4.1(2023-11-27) | ||
| 54 | +修复说明bug | ||
| 55 | +## 1.4.0(2023-11-27) | ||
| 56 | +next-tree 全面说明文档 | ||
| 57 | +## 1.3.6(2023-11-27) | ||
| 58 | +增加远程加载loadData,全面实现全功能覆盖 | ||
| 59 | +## 1.3.5(2023-11-27) | ||
| 60 | +增加title的定义 | ||
| 61 | +## 1.3.4(2023-11-27) | ||
| 62 | +增加title支持自定义定制 | ||
| 63 | +## 1.3.3(2023-11-21) | ||
| 64 | +增加搜索模式searchModel=depHighlight模式,从属高亮显示模式 | ||
| 65 | +## 1.3.2(2023-11-20) | ||
| 66 | +修复valueKey设置bug | ||
| 67 | +## 1.3.1(2023-11-17) | ||
| 68 | +增加说明文件,和demo | ||
| 69 | +## 1.3.0(2023-11-17) | ||
| 70 | +修复clear时不支持关联模式的设置 | ||
| 71 | +## 1.2.9(2023-11-17) | ||
| 72 | +增加checkStrictlyModel模式设置,强关联,和弱关联 | ||
| 73 | +## 1.2.8(2023-11-16) | ||
| 74 | +增加next-tree的辅助线模式 | ||
| 75 | +## 1.2.7(2023-11-16) | ||
| 76 | +优化next-tree | ||
| 77 | +## 1.2.6(2023-11-16) | ||
| 78 | +修复搜索时,隐藏未打开的数据 | ||
| 79 | +## 1.2.5(2023-11-16) | ||
| 80 | +修复搜索无法点击,和级联半选不生效问题 | ||
| 81 | +## 1.2.4(2023-11-16) | ||
| 82 | +更新新功能插件使用说明 | ||
| 83 | +## 1.2.3(2023-11-16) | ||
| 84 | +增加插槽模式,只是高ui要求定制 | ||
| 85 | +## 1.2.2(2023-11-15) | ||
| 86 | +修复checkStrictly配置下,子关联父的选择状态 | ||
| 87 | +## 1.2.1(2023-11-15) | ||
| 88 | +增加半选提示功能配置showHalfCheckedTips | ||
| 89 | +## 1.2.0(2023-11-14) | ||
| 90 | +修复disabled配置状态下,父子级联,不需要改变disabled设置项的选择状态 | ||
| 91 | +## 1.1.9(2023-11-13) | ||
| 92 | +增强大数据量体验交互,增加筛选搜索模式 | ||
| 93 | +## 1.1.8(2023-11-13) | ||
| 94 | +增加清除clear和取消cancel事件 | ||
| 95 | +## 1.1.7(2023-11-08) | ||
| 96 | +更新next-tree插件功能清单说明 | ||
| 97 | +## 1.1.6(2023-11-07) | ||
| 98 | +update说明文档 | ||
| 99 | +## 1.1.5(2023-11-07) | ||
| 100 | +update | ||
| 101 | +## 1.1.4(2023-11-07) | ||
| 102 | +更新readme.md说明 | ||
| 103 | +## 1.1.3(2023-11-07) | ||
| 104 | +更新说明demo | ||
| 105 | +## 1.1.2(2023-11-07) | ||
| 106 | +增加子节点按需渲染演示demo | ||
| 107 | +## 1.1.1(2023-11-07) | ||
| 108 | +增加清空功能 | ||
| 109 | +## 1.1.0(2023-11-07) | ||
| 110 | +增加子孙节点按需渲染,扩展本插件支持大数据量渲染; | ||
| 111 | +## 1.0.9(2023-10-26) | ||
| 112 | +增加文件说明 | ||
| 113 | +## 1.0.8(2023-09-14) | ||
| 114 | +增加禁用节点属性配置disabledKey | ||
| 115 | +## 1.0.7(2023-09-06) | ||
| 116 | +增加checkStrictly,实现父子节点关联 | ||
| 117 | +## 1.0.6(2023-09-06) | ||
| 118 | +更新vue2使用过程视图不更新的技术说明 | ||
| 119 | +## 1.0.5(2023-09-06) | ||
| 120 | +修复说明文档 | ||
| 121 | +## 1.0.4(2023-06-19) | ||
| 122 | +修改demo | ||
| 123 | +## 1.0.3(2023-06-19) | ||
| 124 | +更新vue2的使用demo | ||
| 125 | +## 1.0.2(2023-06-19) | ||
| 126 | +修复说明文档 | ||
| 127 | + | ||
| 128 | +## 1.0.1(2023-05-10) | ||
| 129 | +更新说明文件 | ||
| 130 | +## 1.0.0(2023-05-09) | ||
| 131 | +初始化项目 |
garbage-removal/src/components/next-tree/readme/package.json
0 → 100644
| 1 | +{ | ||
| 2 | + "id": "next-tree", | ||
| 3 | + "displayName": "next-tree(超强树选择器、树组件、树插件、无限级联树、单选树、多选树、自定义样式树、树形选择器)", | ||
| 4 | + "version": "1.6.7", | ||
| 5 | + "description": "next-tree 弹窗树形选择器,支持多选,支持大数据, 无限级联,单选,父子级级联,远程/ajax加载,子节点增量/异步渲染,自定义样式定制,具名插槽等;支持h5/小程序/APP,全端通用", | ||
| 6 | + "keywords": [ | ||
| 7 | + "树选择", | ||
| 8 | + "tree", | ||
| 9 | + "弹窗树选择器", | ||
| 10 | + "多选树", | ||
| 11 | + "单选树" | ||
| 12 | +], | ||
| 13 | +"engines": { | ||
| 14 | + }, | ||
| 15 | +"dcloudext": { | ||
| 16 | + "sale": { | ||
| 17 | + "regular": { | ||
| 18 | + "price": "0.00" | ||
| 19 | + }, | ||
| 20 | + "sourcecode": { | ||
| 21 | + "price": "0.00" | ||
| 22 | + } | ||
| 23 | + }, | ||
| 24 | + "contact": { | ||
| 25 | + "qq": "" | ||
| 26 | + }, | ||
| 27 | + "declaration": { | ||
| 28 | + "ads": "无", | ||
| 29 | + "data": "修改版本说明", | ||
| 30 | + "permissions": "无" | ||
| 31 | + }, | ||
| 32 | + "npmurl": "", | ||
| 33 | + "type": "component-vue" | ||
| 34 | + }, | ||
| 35 | + "uni_modules": { | ||
| 36 | + "dependencies": ["next-search-more"], | ||
| 37 | + "encrypt": [], | ||
| 38 | + "platforms": { | ||
| 39 | + "cloud": { | ||
| 40 | + "tcb": "y", | ||
| 41 | + "aliyun": "y" | ||
| 42 | + }, | ||
| 43 | + "client": { | ||
| 44 | + "Vue": { | ||
| 45 | + "vue2": "y", | ||
| 46 | + "vue3": "y" | ||
| 47 | + }, | ||
| 48 | + "App": { | ||
| 49 | + "app-vue": "y", | ||
| 50 | + "app-nvue": "u" | ||
| 51 | + }, | ||
| 52 | + "H5-mobile": { | ||
| 53 | + "Safari": "y", | ||
| 54 | + "Android Browser": "y", | ||
| 55 | + "微信浏览器(Android)": "y", | ||
| 56 | + "QQ浏览器(Android)": "y" | ||
| 57 | + }, | ||
| 58 | + "H5-pc": { | ||
| 59 | + "Chrome": "y", | ||
| 60 | + "IE": "n", | ||
| 61 | + "Edge": "y", | ||
| 62 | + "Firefox": "y", | ||
| 63 | + "Safari": "u" | ||
| 64 | + }, | ||
| 65 | + "小程序": { | ||
| 66 | + "微信": "y", | ||
| 67 | + "阿里": "y", | ||
| 68 | + "百度": "y", | ||
| 69 | + "字节跳动": "u", | ||
| 70 | + "QQ": "y", | ||
| 71 | + "钉钉": "y", | ||
| 72 | + "快手": "u", | ||
| 73 | + "飞书": "u", | ||
| 74 | + "京东": "u" | ||
| 75 | + }, | ||
| 76 | + "快应用": { | ||
| 77 | + "华为": "u", | ||
| 78 | + "联盟": "u" | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | +} | ||
| 0 | \ No newline at end of file | 84 | \ No newline at end of file |
garbage-removal/src/components/next-tree/readme/readme.md
0 → 100644
| 1 | + | ||
| 2 | +## next-tree --下拉树 | ||
| 3 | + | ||
| 4 | +> 遇到问题或有建议可以加入QQ群(<font color=#f00>455948571</font>)反馈 | ||
| 5 | +> 如果觉得组件不错,<font color=#f00>给五星鼓励鼓励</font>咯! | ||
| 6 | + | ||
| 7 | +## 亮点功能说明(打造你不得不用的好插件) | ||
| 8 | + | ||
| 9 | +### 本插件自1.5.0版本后支持一下功能 | ||
| 10 | + | ||
| 11 | + > 1.大数据量渲染(本插件智能判断,如果子孙集数据量大于50时,会响应等待渲染视图;) | ||
| 12 | + > 2.子节点按需渲染(自动启用,无需配置) | ||
| 13 | + > 3.父子级联选择设置 | ||
| 14 | + > 4.单选多选设置 | ||
| 15 | + > 5.父节点是否可选设置 | ||
| 16 | + > 6.回显默认选中值 | ||
| 17 | + > 7.不可选项disabled设置 | ||
| 18 | + > 8.增强大数据量体验交互,增加筛选搜索模式 | ||
| 19 | + > 9.增强样式定制,提供自定插槽,实现高要求样式定制 | ||
| 20 | + > 10.增加辅助线模式,外观更加精美 | ||
| 21 | + > 11.支持动态配置title | ||
| 22 | + > 12.支持搜索模式searchModel=depHighlight模式,从属高亮显示模式 | ||
| 23 | + > 13.支持异步加载子节点,ajax加载子节点 | ||
| 24 | + > 14.增加可配置主题,自由定制插件主题颜色 | ||
| 25 | + > 15.支持动态校验,可以进行提示控制校验 | ||
| 26 | + > 16.支持页面模式,可以进行单页面展示 | ||
| 27 | + > 17.支持半选提示状态显示 | ||
| 28 | + | ||
| 29 | +## 注意 | ||
| 30 | + | ||
| 31 | +### 作者不介意你对组件源码进行改造使用,为了开源更加高效,谢谢你的配合;为了节省不必要的沟通浪费,以下情况请不要再反馈给作者,请自行解决; | ||
| 32 | +### 在这感各位的理解,我支持开源,但是作者时间有限;谢谢各位的配合;在这里期望我写的小小插件能为你提供便捷; | ||
| 33 | + | ||
| 34 | + > 1.如果你对源码进行了修改使用,请不需要对作者做任何的反馈,作者确实没有空陪你做技术分析解答; | ||
| 35 | + > 2.如果你引入插件,连插件是否有正常被uniapp框架识别解析都不清楚,请你换个插件使用; | ||
| 36 | + > 3.如果你引入插件,针对自己项目进行功能改造的,请自行仔细阅读源码并了解其原理,自行改造;这里作者不愿意浪费过多时间进行技术解答; | ||
| 37 | + > 4.如果你不想进行全局加载next-tree,需要按需加载;next-tree中有相关依赖的组件,需要你自行在组件内部单独引入;依赖组件可以在package.json中找到; | ||
| 38 | + > 5.理论上作者不再解决由于本地开发环境问题所导致的插件使用问题,请自行到uniapp官网学习解决; | ||
| 39 | + | ||
| 40 | +## 使用 | ||
| 41 | + | ||
| 42 | +>[从uniapp插件市场导入](https://ext.dcloud.net.cn/plugin?name=next-tree) | ||
| 43 | + | ||
| 44 | +## 关注作者其他开源 | ||
| 45 | + | ||
| 46 | +npm开源包:[npm](https://www.npmjs.com/~lixueshiaa); | ||
| 47 | +github开源项目:[github](https://github.com/lixueshiaa); | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +```html | ||
| 51 | +<template> | ||
| 52 | + <view style="padding:10px;color: #333;font-weight: 500;"> | ||
| 53 | + <view style="padding: 10px 0"><text>1、设置单选和父级不可选</text></view> | ||
| 54 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, false)">设置</button> | ||
| 55 | + <view style="padding: 10px 0"><text>2、设置多选和父级不可选</text></view> | ||
| 56 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, false)">设置</button> | ||
| 57 | + <view style="padding: 10px 0"><text>3、设置单选和父级可选</text></view> | ||
| 58 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, true)">设置</button> | ||
| 59 | + <view style="padding: 10px 0"><text>4、设置多选和父级可选</text></view> | ||
| 60 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true)" >设置</button> | ||
| 61 | + <view style="padding: 10px 0"><text>4、设置多选和父级可选和父级关联子级选择</text></view> | ||
| 62 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true, true)" >设置</button> | ||
| 63 | + <view style="padding: 10px 0"><text>5、设置默认回显(默认选中: '上海-2', '黄埔区-35')</text></view> | ||
| 64 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="echoDefault()" >设置</button> | ||
| 65 | + <!-- 异步加载demo --> | ||
| 66 | + <view style="padding: 10px 0"><text>6、异步加载渲染demo</text></view> | ||
| 67 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="openTree()" >设置</button> | ||
| 68 | + </view> | ||
| 69 | + | ||
| 70 | + <!-- 异步加载demo --> | ||
| 71 | + <next-tree :selectParent="false" :checkStrictly="true" :multiple="true" ref="nextTreeAsyncRef" :treeData="asyncTreeData" :loadData="loadData" /> | ||
| 72 | + | ||
| 73 | + <next-tree :changeVerify="changeVerify" :title="getTitle" ref="nextTreeRef" :checkStrictly="checkStrictly" :selectParent="selectParent" :multiple="multiple" :treeData="treeData" @cancel="oncancel" @confirm="onconfirm"> | ||
| 74 | + <!-- label插槽示意代码 --> | ||
| 75 | + <!-- <template #label="{data: {id, label, iconSrc, prev, post}}"> | ||
| 76 | + <view class="line-block"> | ||
| 77 | + <image class="img" v-if="iconSrc" :src="iconSrc"></image> | ||
| 78 | + <text space="nbsp" v-if="prev">{{prev}} </text><text>{{label}}</text><text space="nbsp" v-if="post"> {{post}}</text> | ||
| 79 | + </view> | ||
| 80 | + </template> --> | ||
| 81 | + <!-- <template #topBar> | ||
| 82 | + <view style="color: #666;padding:5px;"><text style="font-size: 12px;">历史记录</text></view> | ||
| 83 | + <view style="display: flex;justify-content: space-between;padding-bottom: 10px;border-bottom: 1rpx solid #f0f0f0;"> | ||
| 84 | + <button @click="checkedFunc('1-3-3-4')" :style="'background-color:'+ (activeId === '1-3-3-4' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">北京区-4</button> | ||
| 85 | + <button @click="checkedFunc('3-1-2')" :style="'background-color:'+ (activeId === '3-1-2' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-2</button> | ||
| 86 | + <button @click="checkedFunc('3-1-6')" :style="'background-color:'+ (activeId === '3-1-6' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-5</button> | ||
| 87 | + </view> | ||
| 88 | + </template> --> | ||
| 89 | + </next-tree> | ||
| 90 | +</template> | ||
| 91 | +``` | ||
| 92 | + | ||
| 93 | +### vue3 + ts 使用 | ||
| 94 | + | ||
| 95 | +```ts | ||
| 96 | +<script setup lang="ts"> | ||
| 97 | +import { ref, unref } from 'vue' | ||
| 98 | +import nextTree from '@/components/next-tree/next-tree.vue' | ||
| 99 | + | ||
| 100 | +const multiple = ref(false) | ||
| 101 | +const selectParent = ref(false) | ||
| 102 | +const nextTreeRef = ref() | ||
| 103 | +const nextTreeAsyncRef = ref() | ||
| 104 | +const activeId = ref('') | ||
| 105 | + | ||
| 106 | +const localData: any = { | ||
| 107 | + 'a1': [{id: 'a1-1', label: 'a1-1'}, {id: 'a1-2', label: 'a1-2',children: [] },{id: 'a1-3', label: 'a1-3'}], | ||
| 108 | + 'b1': [{id: 'b1-1', label: 'b1-1',children: []}, {id: 'b1-2', label: 'b1-2'},{id: 'b1-3', label: 'b1-3'}], | ||
| 109 | + 'c1': [{id: 'c1-1', label: 'c1-1'}, {id: 'c1-2', label: 'c1-2'},{id: 'c1-3', label: 'c1-3',children: []}], | ||
| 110 | + 'a1-2': [{id: 'a1-2-1', label: 'a1-2-1'}, {id: 'a1-2-2', label: 'a1-2-2'}], | ||
| 111 | + 'b1-1': [{id: 'b1-1-1', label: 'b1-1-1'}, {id: 'b1-1-2', label: 'b1-1-2'}], | ||
| 112 | + 'c1-3': [{id: 'c1-3-1', label: 'c1-3-1'}, {id: 'c1-3-2', label: 'c1-3-2'}] | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +const checkStrictly = ref(false) | ||
| 116 | +const asyncTreeData = ref([{id: 'a1', label: 'a1', children: []},{id: 'b1', label: 'b1', children: []},{id: 'c1', label: 'c1', children: []}]) | ||
| 117 | +const treeData = ref([ | ||
| 118 | + {id: '1', label: '北京'}, | ||
| 119 | + {id: '2', label: '上海', children: [ | ||
| 120 | + {id: '2-1', label: '上海-1'}, | ||
| 121 | + {id: '2-2', label: '上海-2'}, | ||
| 122 | + {id: '2-3', label: '上海-3'}, | ||
| 123 | + ] }, | ||
| 124 | + {id: '3', label: '广州', children: [ | ||
| 125 | + {id: '3-1', label: '海珠区', children: [ | ||
| 126 | + {id: '3-1-1', label: '海珠区-1'}, | ||
| 127 | + {id: '3-1-2', label: '海珠区-2'}, | ||
| 128 | + {id: '3-1-4', label: '海珠区-3'}, | ||
| 129 | + {id: '3-1-5', label: '海珠区-4'}, | ||
| 130 | + {id: '3-1-6', label: '海珠区-5'}, | ||
| 131 | + {id: '3-1-7', label: '海珠区-6'}, | ||
| 132 | + {id: '3-1-8', label: '海珠区-7'}, | ||
| 133 | + {id: '3-1-9', label: '海珠区-8'}, | ||
| 134 | + {id: '3-1-10', label: '海珠区-9'}, | ||
| 135 | + {id: '3-1-11', label: '海珠区-10'}, | ||
| 136 | + ]}, | ||
| 137 | + {id: '3-2', label: '番禺区', children: [ | ||
| 138 | + {id: '3-2-1', label: '番禺区-1'}, | ||
| 139 | + {id: '3-2-2', label: '番禺区-2'}, | ||
| 140 | + {id: '3-2-4', label: '番禺区-3'}, | ||
| 141 | + {id: '3-2-5', label: '番禺区-4'}, | ||
| 142 | + {id: '3-2-6', label: '番禺区-5'}, | ||
| 143 | + {id: '3-2-7', label: '番禺区-6'}, | ||
| 144 | + {id: '3-2-8', label: '番禺区-7'}, | ||
| 145 | + {id: '3-2-9', label: '番禺区-8'}, | ||
| 146 | + {id: '3-2-10', label: '番禺区-9'}, | ||
| 147 | + {id: '3-2-11', label: '番禺区-10'}, | ||
| 148 | + ]}, | ||
| 149 | + {id: '3-3', label: '黄埔区', children: [ | ||
| 150 | + {id: '3-3-1', label: '黄埔区-1'}, | ||
| 151 | + {id: '3-3-2', label: '黄埔区-2'}, | ||
| 152 | + {id: '3-3-3', label: '黄埔区-3'}, | ||
| 153 | + {id: '3-3-4', label: '黄埔区-4'}, | ||
| 154 | + {id: '3-3-5', label: '黄埔区-5'}, | ||
| 155 | + {id: '3-3-6', label: '黄埔区-6'}, | ||
| 156 | + {id: '3-3-7', label: '黄埔区-7'}, | ||
| 157 | + {id: '3-3-8', label: '黄埔区-8'}, | ||
| 158 | + {id: '3-3-9', label: '黄埔区-9'}, | ||
| 159 | + {id: '3-3-10', label: '黄埔区-10'}, | ||
| 160 | + {id: '3-3-12', label: '黄埔区-11'}, | ||
| 161 | + {id: '3-3-13', label: '黄埔区-12'}, | ||
| 162 | + {id: '3-3-13', label: '黄埔区-13'}, | ||
| 163 | + {id: '3-3-14', label: '黄埔区-14'}, | ||
| 164 | + {id: '3-3-15', label: '黄埔区-15'}, | ||
| 165 | + {id: '3-3-16', label: '黄埔区-16'}, | ||
| 166 | + {id: '3-3-17', label: '黄埔区-17'}, | ||
| 167 | + {id: '3-3-18', label: '黄埔区-18'}, | ||
| 168 | + {id: '3-3-19', label: '黄埔区-19'}, | ||
| 169 | + {id: '3-3-20', label: '黄埔区-20'}, | ||
| 170 | + {id: '3-3-21', label: '黄埔区-21'}, | ||
| 171 | + {id: '3-3-22', label: '黄埔区-22'}, | ||
| 172 | + {id: '3-3-23', label: '黄埔区-23'}, | ||
| 173 | + {id: '3-3-24', label: '黄埔区-24'}, | ||
| 174 | + {id: '3-3-25', label: '黄埔区-25'}, | ||
| 175 | + {id: '3-3-26', label: '黄埔区-26'}, | ||
| 176 | + {id: '3-3-27', label: '黄埔区-27'}, | ||
| 177 | + {id: '3-3-28', label: '黄埔区-28'}, | ||
| 178 | + {id: '3-3-29', label: '黄埔区-29'}, | ||
| 179 | + {id: '3-3-30', label: '黄埔区-30'}, | ||
| 180 | + {id: '3-3-31', label: '黄埔区-31'}, | ||
| 181 | + {id: '3-3-32', label: '黄埔区-32'}, | ||
| 182 | + {id: '3-3-33', label: '黄埔区-33'}, | ||
| 183 | + {id: '3-3-34', label: '黄埔区-34'}, | ||
| 184 | + {id: '3-3-35', label: '黄埔区-35'}, | ||
| 185 | + {id: '3-3-36', label: '黄埔区-36'}, | ||
| 186 | + | ||
| 187 | + ]}, | ||
| 188 | + ], | ||
| 189 | + }]) | ||
| 190 | +function getTitle(checked) { | ||
| 191 | + return `已选:${checked.length}项` | ||
| 192 | +} | ||
| 193 | +function itemclick (_multiple, _selectParent, _checkStrictly = false) { | ||
| 194 | + multiple.value = _multiple | ||
| 195 | + selectParent.value = _selectParent | ||
| 196 | + checkStrictly.value = _checkStrictly | ||
| 197 | + unref(nextTreeRef).showTree = true | ||
| 198 | +} | ||
| 199 | +function checkedFunc(id) { | ||
| 200 | + if(unref(activeId) === id) { | ||
| 201 | + activeId.value = ''; | ||
| 202 | + unref(nextTreeRef).checkedFunc(id, false) | ||
| 203 | + } else { | ||
| 204 | + activeId.value = id; | ||
| 205 | + unref(nextTreeRef).checkedFunc(id) | ||
| 206 | + } | ||
| 207 | +} | ||
| 208 | +function changeVerify(current, chooseList) { | ||
| 209 | + // 注意:返回非空字符串会阻止原有行为,并提示返回的字符串 | ||
| 210 | + // 如果函数体不做return返回值,即验证通过,控件正常处理业务 | ||
| 211 | + console.log('当前变化的数据', current) | ||
| 212 | + console.log('已选择的数据', chooseList) | ||
| 213 | + if(chooseList && chooseList.length > 4) { | ||
| 214 | + | ||
| 215 | + return '最多可以选择4个节点' | ||
| 216 | + } | ||
| 217 | +} | ||
| 218 | +function openTree() { | ||
| 219 | + unref(nextTreeAsyncRef).showTree = true | ||
| 220 | +} | ||
| 221 | +function echoDefault () { | ||
| 222 | + const selectIds = ['2-1','3-3-35'] | ||
| 223 | + checkedTreeData(unref(treeData), selectIds) | ||
| 224 | + console.log('treeData的数据:', unref(treeData)) | ||
| 225 | + multiple.value = true | ||
| 226 | + unref(nextTreeRef).showTree = true | ||
| 227 | +} | ||
| 228 | +function loadData(nodeItem) { | ||
| 229 | + // 同步实现的代码处理方式 | ||
| 230 | + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} | ||
| 231 | + | ||
| 232 | + // if(nodeItem && localData[nodeItem.id]) { | ||
| 233 | + // return localData[nodeItem.id] | ||
| 234 | + // } else { | ||
| 235 | + // return [] | ||
| 236 | + // } | ||
| 237 | + | ||
| 238 | + // 异步的代码实现方式 | ||
| 239 | + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} | ||
| 240 | + | ||
| 241 | + return new Promise((resolve, reject) => { | ||
| 242 | + setTimeout(() => { | ||
| 243 | + if(nodeItem && localData[nodeItem.id]) { | ||
| 244 | + return resolve(localData[nodeItem.id]) | ||
| 245 | + } else { | ||
| 246 | + return resolve([]) | ||
| 247 | + } | ||
| 248 | + }, 1000) | ||
| 249 | + }) | ||
| 250 | +} | ||
| 251 | +function checkedTreeData (treeData, selectIds) { | ||
| 252 | + treeData.map(item => { | ||
| 253 | + if (selectIds.indexOf(item.id) !== -1) { | ||
| 254 | + item.checked = true | ||
| 255 | + } else { | ||
| 256 | + item.checked = false | ||
| 257 | + } | ||
| 258 | + if (item.children && item.children.length) { | ||
| 259 | + checkedTreeData(item.children, selectIds) | ||
| 260 | + } | ||
| 261 | + }) | ||
| 262 | +} | ||
| 263 | +function oncancel() { | ||
| 264 | + // 清除treeData的选中状态 | ||
| 265 | + checkedTreeData(unref(treeData), []) | ||
| 266 | +} | ||
| 267 | +function onconfirm(list) { | ||
| 268 | + console.log('选中项的数量列表list:', list) | ||
| 269 | +} | ||
| 270 | +</script> | ||
| 271 | +<style lang="scss"> | ||
| 272 | + .line-block { | ||
| 273 | + display: flex; | ||
| 274 | + flex-direction: row; | ||
| 275 | + justify-content: flex-start; | ||
| 276 | + align-items: center; | ||
| 277 | + .img { | ||
| 278 | + width: 40rpx; | ||
| 279 | + height: 40rpx; | ||
| 280 | + border-radius: 10rpx; | ||
| 281 | + margin: 0 20rpx; | ||
| 282 | + } | ||
| 283 | + } | ||
| 284 | +</style> | ||
| 285 | + | ||
| 286 | +``` | ||
| 287 | + | ||
| 288 | +### vue2 使用 | ||
| 289 | +```html | ||
| 290 | +<template> | ||
| 291 | + <view> | ||
| 292 | + <view style="padding:10px;color: #333;font-weight: 500;"> | ||
| 293 | + <view style="padding: 10px 0"><text>1、设置单选和父级不可选</text></view> | ||
| 294 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, false)">设置</button> | ||
| 295 | + <view style="padding: 10px 0"><text>2、设置多选和父级不可选</text></view> | ||
| 296 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, false)">设置</button> | ||
| 297 | + <view style="padding: 10px 0"><text>3、设置单选和父级可选</text></view> | ||
| 298 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, true)">设置</button> | ||
| 299 | + <view style="padding: 10px 0"><text>4、设置多选和父级可选</text></view> | ||
| 300 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true)" >设置</button> | ||
| 301 | + <view style="padding: 10px 0"><text>4、设置多选和父级可选和父级关联子级选择</text></view> | ||
| 302 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true, true)" >设置</button> | ||
| 303 | + <view style="padding: 10px 0"><text>5、设置默认回显(默认选中: '上海-2', '黄埔区-35')</text></view> | ||
| 304 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="echoDefault()" >设置</button> | ||
| 305 | + <!-- 异步加载demo --> | ||
| 306 | + <view style="padding: 10px 0"><text>6、异步加载渲染demo</text></view> | ||
| 307 | + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="openTree()" >设置</button> | ||
| 308 | + </view> | ||
| 309 | + <!-- 异步加载demo --> | ||
| 310 | + <next-tree :selectParent="false" :checkStrictly="true" :multiple="true" ref="nextTreeAsyncRef" :treeData="asyncTreeData" :loadData="loadData" /> | ||
| 311 | + | ||
| 312 | + <next-tree :changeVerify="changeVerify" :title="getTitle" ref="nextTreeRef" :checkStrictly="checkStrictly" :selectParent="selectParent" :multiple="multiple" :treeData="treeData" @cancel="oncancel" @confirm="onconfirm"> | ||
| 313 | + <!-- label插槽示意代码 --> | ||
| 314 | + <!-- <template v-slot:label="{data: {id, label, iconSrc, prev, post}}"> | ||
| 315 | + <view class="line-block"> | ||
| 316 | + <image class="img" v-if="iconSrc" :src="iconSrc"></image> | ||
| 317 | + <text space="nbsp" v-if="prev">{{prev}} </text><text>{{label}}</text><text space="nbsp" v-if="post"> {{post}}</text> | ||
| 318 | + </view> | ||
| 319 | + </template> --> | ||
| 320 | + <!-- <template #topBar> | ||
| 321 | + <view style="color: #666;padding:5px;"><text style="font-size: 12px;">历史记录</text></view> | ||
| 322 | + <view style="display: flex;justify-content: space-between;padding-bottom: 10px;border-bottom: 1rpx solid #f0f0f0;"> | ||
| 323 | + <button @click="checkedFunc('1-3-3-4')" :style="'background-color:'+ (activeId === '1-3-3-4' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">北京区-4</button> | ||
| 324 | + <button @click="checkedFunc('3-1-2')" :style="'background-color:'+ (activeId === '3-1-2' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-2</button> | ||
| 325 | + <button @click="checkedFunc('3-1-6')" :style="'background-color:'+ (activeId === '3-1-6' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-5</button> | ||
| 326 | + </view> | ||
| 327 | + </template> --> | ||
| 328 | + </next-tree> | ||
| 329 | + </view> | ||
| 330 | +</template> | ||
| 331 | +``` | ||
| 332 | + | ||
| 333 | +```js | ||
| 334 | +<script> | ||
| 335 | +let self = null; | ||
| 336 | +export default { | ||
| 337 | + data () { | ||
| 338 | + return { | ||
| 339 | + multiple: false, | ||
| 340 | + selectParent: false, | ||
| 341 | + checkStrictly: false, | ||
| 342 | + activeId: '', | ||
| 343 | + localData:{ | ||
| 344 | + 'a1': [{id: 'a1-1', label: 'a1-1'}, {id: 'a1-2', label: 'a1-2',children: [] },{id: 'a1-3', label: 'a1-3'}], | ||
| 345 | + 'b1': [{id: 'b1-1', label: 'b1-1',children: []}, {id: 'b1-2', label: 'b1-2'},{id: 'b1-3', label: 'b1-3'}], | ||
| 346 | + 'c1': [{id: 'c1-1', label: 'c1-1'}, {id: 'c1-2', label: 'c1-2'},{id: 'c1-3', label: 'c1-3',children: []}], | ||
| 347 | + 'a1-2': [{id: 'a1-2-1', label: 'a1-2-1'}, {id: 'a1-2-2', label: 'a1-2-2'}], | ||
| 348 | + 'b1-1': [{id: 'b1-1-1', label: 'b1-1-1'}, {id: 'b1-1-2', label: 'b1-1-2'}], | ||
| 349 | + 'c1-3': [{id: 'c1-3-1', label: 'c1-3-1'}, {id: 'c1-3-2', label: 'c1-3-2'}] | ||
| 350 | + }, | ||
| 351 | + asyncTreeData: [{id: 'a1', label: 'a1', children: []},{id: 'b1', label: 'b1', children: []},{id: 'c1', label: 'c1', children: []}], | ||
| 352 | + treeData: [ | ||
| 353 | + {id: '1', label: '北京', checked: false}, | ||
| 354 | + {id: '2', label: '上海', checked: false, children: [ | ||
| 355 | + {id: '2-1', label: '上海-1', checked: false}, | ||
| 356 | + {id: '2-2', label: '上海-2', checked: false}, | ||
| 357 | + {id: '2-3', label: '上海-3', checked: false}, | ||
| 358 | + ] }, | ||
| 359 | + {id: '3', label: '广州', children: [ | ||
| 360 | + {id: '3-1', label: '海珠区', checked: false, children: [ | ||
| 361 | + {id: '3-1-1', label: '海珠区-1', checked: false, disabled: true}, | ||
| 362 | + {id: '3-1-2', label: '海珠区-2', checked: false}, | ||
| 363 | + {id: '3-1-4', label: '海珠区-3', checked: false}, | ||
| 364 | + {id: '3-1-5', label: '海珠区-4', checked: false}, | ||
| 365 | + {id: '3-1-6', label: '海珠区-5', checked: false}, | ||
| 366 | + {id: '3-1-7', label: '海珠区-6', checked: false}, | ||
| 367 | + {id: '3-1-8', label: '海珠区-7', checked: false}, | ||
| 368 | + {id: '3-1-9', label: '海珠区-8', checked: false}, | ||
| 369 | + {id: '3-1-10', label: '海珠区-9', checked: false}, | ||
| 370 | + {id: '3-1-11', label: '海珠区-10', checked: false}, | ||
| 371 | + ]}, | ||
| 372 | + {id: '3-2', label: '番禺区', checked: false, children: [ | ||
| 373 | + {id: '3-2-1', label: '番禺区-1', checked: false}, | ||
| 374 | + {id: '3-2-2', label: '番禺区-2', checked: false}, | ||
| 375 | + {id: '3-2-4', label: '番禺区-3', checked: false}, | ||
| 376 | + {id: '3-2-5', label: '番禺区-4', checked: false}, | ||
| 377 | + {id: '3-2-6', label: '番禺区-5', checked: false}, | ||
| 378 | + {id: '3-2-7', label: '番禺区-6', checked: false}, | ||
| 379 | + {id: '3-2-8', label: '番禺区-7', checked: false}, | ||
| 380 | + {id: '3-2-9', label: '番禺区-8', checked: false}, | ||
| 381 | + {id: '3-2-10', label: '番禺区-9', checked: false}, | ||
| 382 | + {id: '3-2-11', label: '番禺区-10', checked: false}, | ||
| 383 | + ]}, | ||
| 384 | + {id: '3-3', label: '黄埔区', checked: false, children: [ | ||
| 385 | + {id: '3-3-1', label: '黄埔区-1', checked: false}, | ||
| 386 | + {id: '3-3-2', label: '黄埔区-2', checked: false}, | ||
| 387 | + {id: '3-3-3', label: '黄埔区-3', checked: false}, | ||
| 388 | + {id: '3-3-4', label: '黄埔区-4', checked: false}, | ||
| 389 | + {id: '3-3-5', label: '黄埔区-5', checked: false}, | ||
| 390 | + {id: '3-3-6', label: '黄埔区-6', checked: false}, | ||
| 391 | + {id: '3-3-7', label: '黄埔区-7', checked: false}, | ||
| 392 | + {id: '3-3-8', label: '黄埔区-8', checked: false}, | ||
| 393 | + {id: '3-3-9', label: '黄埔区-9', checked: false}, | ||
| 394 | + {id: '3-3-10', label: '黄埔区-10', checked: false}, | ||
| 395 | + {id: '3-3-12', label: '黄埔区-11', checked: false}, | ||
| 396 | + {id: '3-3-13', label: '黄埔区-12', checked: false}, | ||
| 397 | + {id: '3-3-13', label: '黄埔区-13', checked: false}, | ||
| 398 | + {id: '3-3-14', label: '黄埔区-14', checked: false}, | ||
| 399 | + {id: '3-3-15', label: '黄埔区-15', checked: false}, | ||
| 400 | + {id: '3-3-16', label: '黄埔区-16', checked: false}, | ||
| 401 | + {id: '3-3-17', label: '黄埔区-17', checked: false}, | ||
| 402 | + {id: '3-3-18', label: '黄埔区-18', checked: false}, | ||
| 403 | + {id: '3-3-19', label: '黄埔区-19', checked: false}, | ||
| 404 | + {id: '3-3-20', label: '黄埔区-20', checked: false}, | ||
| 405 | + {id: '3-3-21', label: '黄埔区-21', checked: false}, | ||
| 406 | + {id: '3-3-22', label: '黄埔区-22', checked: false}, | ||
| 407 | + {id: '3-3-23', label: '黄埔区-23', checked: false}, | ||
| 408 | + {id: '3-3-24', label: '黄埔区-24', checked: false}, | ||
| 409 | + {id: '3-3-25', label: '黄埔区-25', checked: false}, | ||
| 410 | + {id: '3-3-26', label: '黄埔区-26', checked: false}, | ||
| 411 | + {id: '3-3-27', label: '黄埔区-27', checked: false}, | ||
| 412 | + {id: '3-3-28', label: '黄埔区-28', checked: false}, | ||
| 413 | + {id: '3-3-29', label: '黄埔区-29', checked: false}, | ||
| 414 | + {id: '3-3-30', label: '黄埔区-30', checked: false}, | ||
| 415 | + {id: '3-3-31', label: '黄埔区-31', checked: false}, | ||
| 416 | + {id: '3-3-32', label: '黄埔区-32', checked: false}, | ||
| 417 | + {id: '3-3-33', label: '黄埔区-33', checked: false}, | ||
| 418 | + {id: '3-3-34', label: '黄埔区-34', checked: false}, | ||
| 419 | + {id: '3-3-35', label: '黄埔区-35', checked: false}, | ||
| 420 | + {id: '3-3-36', label: '黄埔区-36', checked: false}, | ||
| 421 | + ]}, | ||
| 422 | + ], | ||
| 423 | + }] | ||
| 424 | + } | ||
| 425 | + }, | ||
| 426 | + methods: { | ||
| 427 | + openTree: function() { | ||
| 428 | + this.$refs.nextTreeAsyncRef.showTree = true | ||
| 429 | + }, | ||
| 430 | + changeVerify: function(current, chooseList) { | ||
| 431 | + // 注意:返回非空字符串会阻止原有行为,并提示返回的字符串 | ||
| 432 | + // 如果函数体不做return返回值,即验证通过,控件正常处理业务 | ||
| 433 | + console.log('当前变化的数据', current) | ||
| 434 | + console.log('已选择的数据', chooseList) | ||
| 435 | + if(chooseList && chooseList.length > 4) { | ||
| 436 | + | ||
| 437 | + return '最多可以选择4个节点' | ||
| 438 | + } | ||
| 439 | + }, | ||
| 440 | + checkedFunc: function(id) { | ||
| 441 | + if(this.activeId === id) { | ||
| 442 | + this.activeId = ''; | ||
| 443 | + this.$refs.nextTreeRef.checkedFunc(id, false) | ||
| 444 | + } else { | ||
| 445 | + this.activeId = id; | ||
| 446 | + this.$refs.nextTreeRef.checkedFunc(id) | ||
| 447 | + } | ||
| 448 | + }, | ||
| 449 | + loadData(nodeItem) { | ||
| 450 | + // 同步实现的代码处理方式 可以返回单个子节点的集合也可以返回子孙节点的集合 | ||
| 451 | + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} | ||
| 452 | + | ||
| 453 | + // if(nodeItem && this.localData[nodeItem.id]) { | ||
| 454 | + // return this.localData[nodeItem.id] | ||
| 455 | + // } else { | ||
| 456 | + // return [] | ||
| 457 | + // } | ||
| 458 | + // 异步的代码实现方式 可以返回单个子节点的集合也可以返回子孙节点的集合 | ||
| 459 | + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} | ||
| 460 | + return new Promise((resolve, reject) => { | ||
| 461 | + setTimeout(() => { | ||
| 462 | + if(nodeItem && self.localData[nodeItem.id]) { | ||
| 463 | + return resolve(self.localData[nodeItem.id]) | ||
| 464 | + } else { | ||
| 465 | + return resolve([]) | ||
| 466 | + } | ||
| 467 | + }, 1000) | ||
| 468 | + }) | ||
| 469 | + }, | ||
| 470 | + getTitle: function(checked) { | ||
| 471 | + return `已选:${checked.length}项` | ||
| 472 | + }, | ||
| 473 | + echoDefault: function() { | ||
| 474 | + const selectIds = ['2-1','3-3-35'] | ||
| 475 | + this.checkedTreeData(this.treeData, selectIds) | ||
| 476 | + console.log('treeData的数据:', this.treeData) | ||
| 477 | + this.multiple = true | ||
| 478 | + this.$refs.nextTreeRef.showTree = true | ||
| 479 | + }, | ||
| 480 | + itemclick: function(_multiple, _selectParent, _checkStrictly = false) { | ||
| 481 | + this.multiple = _multiple | ||
| 482 | + this.selectParent = _selectParent | ||
| 483 | + this.checkStrictly = _checkStrictly | ||
| 484 | + this.$refs.nextTreeRef.showTree = true | ||
| 485 | + }, | ||
| 486 | + checkedTreeData: function(treeData, selectIds) { | ||
| 487 | + // 注意 vue2当数据深嵌套时,如果没有在treeData里面初始化checked属性,那在改变数据的时候直接将checked属性赋值为true,这时候ui界面有可能不会更新, | ||
| 488 | + // 这时候建议使用this.$set去更新checked属性值,或者在初始化this.treeData的时候初始化checked属性 | ||
| 489 | + (treeData || []).map(item => { | ||
| 490 | + if (selectIds.indexOf(item.id) !== -1) { | ||
| 491 | + item.checked = true | ||
| 492 | + } else { | ||
| 493 | + item.checked = false | ||
| 494 | + } | ||
| 495 | + if (item.children && item.children.length) { | ||
| 496 | + this.checkedTreeData(item.children, selectIds) | ||
| 497 | + } | ||
| 498 | + }) | ||
| 499 | + }, | ||
| 500 | + onconfirm: function(list) { | ||
| 501 | + console.log('选中项的数量列表list:', list) | ||
| 502 | + }, | ||
| 503 | + oncancel: function() { | ||
| 504 | + // 清除treeData的选中状态 | ||
| 505 | + this.checkedTreeData(this.treeData, []) | ||
| 506 | + } | ||
| 507 | + }, | ||
| 508 | + created() { | ||
| 509 | + self = this | ||
| 510 | + } | ||
| 511 | +} | ||
| 512 | +</script> | ||
| 513 | +<style lang="scss"> | ||
| 514 | + .line-block { | ||
| 515 | + display: flex; | ||
| 516 | + flex-direction: row; | ||
| 517 | + justify-content: flex-start; | ||
| 518 | + align-items: center; | ||
| 519 | + .img { | ||
| 520 | + width: 40rpx; | ||
| 521 | + height: 40rpx; | ||
| 522 | + border-radius: 10rpx; | ||
| 523 | + margin: 0 20rpx; | ||
| 524 | + } | ||
| 525 | + } | ||
| 526 | +</style> | ||
| 527 | + | ||
| 528 | +``` | ||
| 529 | + | ||
| 530 | +### 个性化自定义样式渲染 | ||
| 531 | + | ||
| 532 | +如果你的需求对样式需求比较高,请使用插槽模式渲染,本组件提供label插槽供你自定义定制; | ||
| 533 | + | ||
| 534 | +```js | ||
| 535 | +<script> | ||
| 536 | +// 提供参考一组自定义渲染数据demo,treeData如下; | ||
| 537 | +const treeData = [ | ||
| 538 | + {id: '1', label: '北京', prev: 'PonderNext-', iconSrc: 'https://img95.699pic.com/xsj/03/fg/hj.jpg%21/fh/300', children: [ | ||
| 539 | + {id: '1-3-3-1', label: '北京区-1', prev: '前置-'}, | ||
| 540 | + {id: '1-3-3-2', label: '北京区-2', post: '-后置'}, | ||
| 541 | + {id: '1-3-3-3', label: '北京区-3', post: '-后置', prev: '前置-'}, | ||
| 542 | + {id: '1-3-3-4', label: '北京区-4'}, | ||
| 543 | + {id: '1-3-3-5', label: '北京区-5'}, | ||
| 544 | + {id: '1-3-3-6', label: '北京区-6'}, | ||
| 545 | + {id: '1-3-3-7', label: '北京区-7'}, | ||
| 546 | + {id: '1-3-3-8', label: '北京区-8'}, | ||
| 547 | + {id: '1-3-3-9', label: '北京区-9'}, | ||
| 548 | + {id: '1-3-3-10', label: '北京区-10'}, | ||
| 549 | + {id: '1-3-3-12', label: '北京区-11'}, | ||
| 550 | + {id: '1-3-3-13', label: '北京区-12'}, | ||
| 551 | + {id: '1-3-3-13', label: '北京区-13'}, | ||
| 552 | + {id: '1-3-3-14', label: '北京区-14'}, | ||
| 553 | + {id: '1-3-3-15', label: '北京区-15'}, | ||
| 554 | + {id: '1-3-3-16', label: '北京区-16'}, | ||
| 555 | + {id: '1-3-3-17', label: '北京区-17'}, | ||
| 556 | + {id: '1-3-3-18', label: '北京区-18'}, | ||
| 557 | + {id: '1-3-3-19', label: '北京区-19'}, | ||
| 558 | + {id: '1-3-3-20', label: '北京区-20'}, | ||
| 559 | + {id: '1-3-3-21', label: '北京区-21'}, | ||
| 560 | + {id: '1-3-3-22', label: '北京区-22'}, | ||
| 561 | + {id: '1-3-3-23', label: '北京区-23'}, | ||
| 562 | + {id: '1-3-3-24', label: '北京区-24'}, | ||
| 563 | + {id: '1-3-3-25', label: '北京区-25'}, | ||
| 564 | + {id: '1-3-3-26', label: '北京区-26'}, | ||
| 565 | + {id: '1-3-3-27', label: '北京区-27'}, | ||
| 566 | + {id: '1-3-3-28', label: '北京区-28'}, | ||
| 567 | + {id: '1-3-3-29', label: '北京区-29'}, | ||
| 568 | + {id: '1-1-3-3-30', label: '北京区-30'}, | ||
| 569 | + {id: '1-3-3-31', label: '北京区-31'}, | ||
| 570 | + {id: '1-3-3-32', label: '北京区-32'}, | ||
| 571 | + {id: '1-3-3-33', label: '北京区-33'}, | ||
| 572 | + {id: '1-3-3-34', label: '北京区-34'}, | ||
| 573 | + {id: '1-3-3-35', label: '北京区-35'}, | ||
| 574 | + {id: '1-3-3-36', label: '北京区-36'}, | ||
| 575 | + {id: '1-3-3-37', label: '北京区-37'}, | ||
| 576 | + {id: '1-3-3-38', label: '北京区-38'}, | ||
| 577 | + {id: '1-3-3-39', label: '北京区-39'}, | ||
| 578 | + {id: '1-3-3-40', label: '北京区-40'}, | ||
| 579 | + {id: '1-3-3-41', label: '北京区-41'}, | ||
| 580 | + {id: '1-3-3-42', label: '北京区-42'}, | ||
| 581 | + {id: '1-3-3-43', label: '北京区-43'}, | ||
| 582 | + {id: '1-3-3-44', label: '北京区-44'}, | ||
| 583 | + {id: '1-3-3-45', label: '北京区-45'}, | ||
| 584 | + {id: '1-3-3-46', label: '北京区-46'}, | ||
| 585 | + {id: '1-3-3-47', label: '北京区-47'}, | ||
| 586 | + {id: '1-3-3-48', label: '北京区-48'}, | ||
| 587 | + {id: '1-3-3-49', label: '北京区-49'}, | ||
| 588 | + {id: '1-3-3-50', label: '北京区-50'}, | ||
| 589 | + {id: '1-3-3-51', label: '北京区-51'}, | ||
| 590 | + {id: '1-3-3-52', label: '北京区-52'}, | ||
| 591 | + {id: '1-3-3-53', label: '北京区-53'}, | ||
| 592 | + {id: '1-3-3-54', label: '北京区-54'}, | ||
| 593 | + ]}, | ||
| 594 | + {id: '2', label: '上海', prev: 'PonderNext-', iconSrc: 'https://img95.699pic.com/xsj/0g/hb/tc.jpg%21/fh/300', children: [ | ||
| 595 | + {id: '2-1', label: '上海-1', iconSrc: 'https://img1.baidu.com/it/u=1997340124,765201109&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285'}, | ||
| 596 | + {id: '2-2', label: '上海-2', iconSrc: 'https://img1.baidu.com/it/u=1997340124,765201109&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285'}, | ||
| 597 | + {id: '2-3', label: '上海-3', iconSrc: 'https://img1.baidu.com/it/u=1997340124,765201109&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285'}, | ||
| 598 | + ] }, | ||
| 599 | + {id: '3', label: '广州', prev: 'PonderNext-', iconSrc: 'https://storage-public.zhaopin.cn/user/avatar/1589350028141684980/d00a1afa-e3ec-40a5-a68e-aef1f684b189.jpg', children: [ | ||
| 600 | + {id: '3-1', label: '海珠区', iconSrc: 'https://img95.699pic.com/xsj/0u/f3/5h.jpg%21/fh/300', children: [ | ||
| 601 | + {id: '3-1-1', label: '海珠区-1', disabled: true}, | ||
| 602 | + {id: '3-1-2', label: '海珠区-2', post: '-后置', prev: '前置-'}, | ||
| 603 | + {id: '3-1-4', label: '海珠区-3', post: '-后置',}, | ||
| 604 | + {id: '3-1-5', label: '海珠区-4'}, | ||
| 605 | + {id: '3-1-6', label: '海珠区-5'}, | ||
| 606 | + {id: '3-1-7', label: '海珠区-6'}, | ||
| 607 | + {id: '3-1-8', label: '海珠区-7', post: '-后置',}, | ||
| 608 | + {id: '3-1-9', label: '海珠区-8'}, | ||
| 609 | + {id: '3-1-10', label: '海珠区-9'}, | ||
| 610 | + {id: '3-1-11', label: '海珠区-10'}, | ||
| 611 | + {id: '3-1-1', label: '海珠区-11', disabled: true}, | ||
| 612 | + {id: '3-1-2', label: '海珠区-12'}, | ||
| 613 | + {id: '3-1-4', label: '海珠区-13'}, | ||
| 614 | + {id: '3-1-5', label: '海珠区-14'}, | ||
| 615 | + {id: '3-1-6', label: '海珠区-15'}, | ||
| 616 | + {id: '3-1-7', label: '海珠区-16'}, | ||
| 617 | + {id: '3-1-8', label: '海珠区-17'}, | ||
| 618 | + {id: '3-1-9', label: '海珠区-18'}, | ||
| 619 | + {id: '3-1-10', label: '海珠区-19', prev: '前置-'}, | ||
| 620 | + {id: '3-1-11', label: '海珠区-20'}, | ||
| 621 | + {id: '3-1-1', label: '海珠区-21', disabled: true}, | ||
| 622 | + {id: '3-1-2', label: '海珠区-22'}, | ||
| 623 | + {id: '3-1-4', label: '海珠区-23'}, | ||
| 624 | + {id: '3-1-5', label: '海珠区-24'}, | ||
| 625 | + {id: '3-1-6', label: '海珠区-25'}, | ||
| 626 | + {id: '3-1-7', label: '海珠区-26'}, | ||
| 627 | + {id: '3-1-8', label: '海珠区-27'}, | ||
| 628 | + {id: '3-1-9', label: '海珠区-28'}, | ||
| 629 | + {id: '3-1-10', label: '海珠区-29'}, | ||
| 630 | + {id: '3-1-11', label: '海珠区-30'}, | ||
| 631 | + {id: '3-1-1', label: '海珠区-31', disabled: true}, | ||
| 632 | + {id: '3-1-2', label: '海珠区-32'}, | ||
| 633 | + {id: '3-1-4', label: '海珠区-33'}, | ||
| 634 | + {id: '3-1-5', label: '海珠区-34'}, | ||
| 635 | + {id: '3-1-6', label: '海珠区-35'}, | ||
| 636 | + {id: '3-1-7', label: '海珠区-36'}, | ||
| 637 | + {id: '3-1-8', label: '海珠区-37'}, | ||
| 638 | + {id: '3-1-9', label: '海珠区-38'}, | ||
| 639 | + {id: '3-1-10', label: '海珠区-39'}, | ||
| 640 | + {id: '3-1-11', label: '海珠区-40'}, | ||
| 641 | + {id: '3-1-1', label: '海珠区-41', disabled: true}, | ||
| 642 | + {id: '3-1-2', label: '海珠区-42'}, | ||
| 643 | + {id: '3-1-4', label: '海珠区-43'}, | ||
| 644 | + {id: '3-1-5', label: '海珠区-44'}, | ||
| 645 | + {id: '3-1-6', label: '海珠区-45'}, | ||
| 646 | + {id: '3-1-7', label: '海珠区-46'}, | ||
| 647 | + {id: '3-1-8', label: '海珠区-47'}, | ||
| 648 | + {id: '3-1-9', label: '海珠区-48'}, | ||
| 649 | + {id: '3-1-10', label: '海珠区-49'}, | ||
| 650 | + {id: '3-1-11', label: '海珠区-50'}, | ||
| 651 | + {id: '3-1-11', label: '海珠区-51'}, | ||
| 652 | + ]}, | ||
| 653 | + {id: '3-2', label: '番禺区', iconSrc: 'https://img1.baidu.com/it/u=931648192,3196263841&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285', disabled: true, checked: true, children: [ | ||
| 654 | + {id: '3-2-1', label: '番禺区-1'}, | ||
| 655 | + {id: '3-2-2', label: '番禺区-2'}, | ||
| 656 | + {id: '3-2-4', label: '番禺区-3'}, | ||
| 657 | + {id: '3-2-5', label: '番禺区-4'}, | ||
| 658 | + {id: '3-2-6', label: '番禺区-5'}, | ||
| 659 | + {id: '3-2-7', label: '番禺区-6'}, | ||
| 660 | + {id: '3-2-8', label: '番禺区-7'}, | ||
| 661 | + {id: '3-2-9', label: '番禺区-8'}, | ||
| 662 | + {id: '3-2-10', label: '番禺区-9'}, | ||
| 663 | + {id: '3-2-11', label: '番禺区-10'}, | ||
| 664 | + ]}, | ||
| 665 | + {id: '3-3', label: '黄埔区', iconSrc: 'https://img.jiaoyubao.cn/43423/20210423113959473-20210423114005024.jpeg', children: [ | ||
| 666 | + {id: '3-3-1', label: '黄埔区-1'}, | ||
| 667 | + {id: '3-3-2', label: '黄埔区-2'}, | ||
| 668 | + {id: '3-3-3', label: '黄埔区-3'}, | ||
| 669 | + {id: '3-3-4', label: '黄埔区-4'}, | ||
| 670 | + {id: '3-3-5', label: '黄埔区-5'}, | ||
| 671 | + {id: '3-3-6', label: '黄埔区-6'}, | ||
| 672 | + {id: '3-3-7', label: '黄埔区-7'}, | ||
| 673 | + {id: '3-3-8', label: '黄埔区-8'}, | ||
| 674 | + {id: '3-3-9', label: '黄埔区-9'}, | ||
| 675 | + {id: '3-3-10', label: '黄埔区-10'}, | ||
| 676 | + {id: '3-3-12', label: '黄埔区-11'}, | ||
| 677 | + {id: '3-3-13', label: '黄埔区-12'}, | ||
| 678 | + {id: '3-3-13', label: '黄埔区-13'}, | ||
| 679 | + {id: '3-3-14', label: '黄埔区-14'}, | ||
| 680 | + {id: '3-3-15', label: '黄埔区-15'}, | ||
| 681 | + {id: '3-3-16', label: '黄埔区-16'}, | ||
| 682 | + {id: '3-3-17', label: '黄埔区-17'}, | ||
| 683 | + {id: '3-3-18', label: '黄埔区-18'}, | ||
| 684 | + {id: '3-3-19', label: '黄埔区-19'}, | ||
| 685 | + {id: '3-3-20', label: '黄埔区-20'}, | ||
| 686 | + {id: '3-3-21', label: '黄埔区-21'}, | ||
| 687 | + {id: '3-3-22', label: '黄埔区-22'}, | ||
| 688 | + {id: '3-3-23', label: '黄埔区-23'}, | ||
| 689 | + {id: '3-3-24', label: '黄埔区-24'}, | ||
| 690 | + {id: '3-3-25', label: '黄埔区-25'}, | ||
| 691 | + {id: '3-3-26', label: '黄埔区-26'}, | ||
| 692 | + {id: '3-3-27', label: '黄埔区-27'}, | ||
| 693 | + {id: '3-3-28', label: '黄埔区-28'}, | ||
| 694 | + {id: '3-3-29', label: '黄埔区-29'}, | ||
| 695 | + {id: '3-3-30', label: '黄埔区-30'}, | ||
| 696 | + {id: '3-3-31', label: '黄埔区-31'}, | ||
| 697 | + {id: '3-3-32', label: '黄埔区-32'}, | ||
| 698 | + {id: '3-3-33', label: '黄埔区-33'}, | ||
| 699 | + {id: '3-3-34', label: '黄埔区-34'}, | ||
| 700 | + {id: '3-3-35', label: '黄埔区-35'}, | ||
| 701 | + {id: '3-3-36', label: '黄埔区-36'}, | ||
| 702 | + {id: '3-3-37', label: '黄埔区-37'}, | ||
| 703 | + {id: '3-3-38', label: '黄埔区-38'}, | ||
| 704 | + {id: '3-3-39', label: '黄埔区-39'}, | ||
| 705 | + {id: '3-3-40', label: '黄埔区-40'}, | ||
| 706 | + {id: '3-3-41', label: '黄埔区-41'}, | ||
| 707 | + {id: '3-3-42', label: '黄埔区-42'}, | ||
| 708 | + {id: '3-3-43', label: '黄埔区-43'}, | ||
| 709 | + {id: '3-3-44', label: '黄埔区-44'}, | ||
| 710 | + {id: '3-3-45', label: '黄埔区-45'}, | ||
| 711 | + {id: '3-3-46', label: '黄埔区-46'}, | ||
| 712 | + {id: '3-3-47', label: '黄埔区-47'}, | ||
| 713 | + {id: '3-3-48', label: '黄埔区-48'}, | ||
| 714 | + {id: '3-3-49', label: '黄埔区-49'}, | ||
| 715 | + {id: '3-3-50', label: '黄埔区-50'}, | ||
| 716 | + {id: '3-3-51', label: '黄埔区-51'}, | ||
| 717 | + {id: '3-3-52', label: '黄埔区-52'}, | ||
| 718 | + {id: '3-3-53', label: '黄埔区-53'}, | ||
| 719 | + {id: '3-3-54', label: '黄埔区-54'}, | ||
| 720 | + ]}, | ||
| 721 | + ], | ||
| 722 | + }] | ||
| 723 | +</script> | ||
| 724 | +``` | ||
| 725 | + | ||
| 726 | +### 预览 | ||
| 727 | +### | ||
| 728 | +*** | ||
| 729 | + | ||
| 730 | +| 功能预览 | 父子级关联演示 | 全面支持大数据量,子孙节点ui按需渲染(按需渲染数据) | | ||
| 731 | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | | ||
| 732 | +|  |  |  | | ||
| 733 | + | ||
| 734 | + | ||
| 735 | + | ||
| 736 | +| 增强控件交互能力,增加筛选search模式,全面支持大数据量交互 | 超强的样式定制能力,满足你高精美组件的需求 | 打开精美的辅助线模式,让你的控件更加友好 | | ||
| 737 | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | | ||
| 738 | +|  |  |  | | ||
| 739 | + | ||
| 740 | + | ||
| 741 | +| 增加搜索模式searchModel=depHighlight模式,从属高亮显示模式 | 支持异步加载子节点,子树集,ajax远程加载数据等 | 支持不同主题的切换,ui定制更简单 | | ||
| 742 | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | | ||
| 743 | +|  |  |  | | ||
| 744 | + | ||
| 745 | +| 增加验证函数和topBar插槽使得更加容易和组件进行交互 | 增加页面模式,支持整页ui展示模式 | | ||
| 746 | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | | ||
| 747 | +| | | | ||
| 748 | +## 参数 | ||
| 749 | +可选参数属性列表 | ||
| 750 | + | ||
| 751 | +|参数名 |说明 |类型 |是否必填 |默认值 |可选值 | | ||
| 752 | +|---- |---- |---- |---- |---- |---- | | ||
| 753 | +|uiMode |ui表现方式;popup<弹窗>, page<页面>;默认是 popup |String |是 |popup |page | | ||
| 754 | +|treeData |树源数据列表 |Array |是 |[] |- | | ||
| 755 | +|valueKey |绑定value的键属性(项的唯一key标识) |String |否 |id |- | | ||
| 756 | +|labelKey |用于显示的字段 |String |否 |label |- | | ||
| 757 | +|disabledKey |禁用节点绑定属性 |String |否 |disabled |- | | ||
| 758 | +|childrenKey |子节点绑定属性 |String |否 |children |- | | ||
| 759 | +|title | 弹出标题(如果是函数时会返回所选项的值作为回调参数如;title: (checked):String => {}) |String, Function |否 |'' |- | | ||
| 760 | +|multiple |是否可以多选 |Boolean |否 |false |true | | ||
| 761 | +|selectParent |是否可以选父级 |Boolean |否 |false |true | | ||
| 762 | +|foldAll| 折叠时关闭所有已经打开的子集,再次打开时需要一级一级打开 |Boolean |否 |false |true | | ||
| 763 | +|themeColor |主题颜色 |String |否 |#f9ae3d |- | | ||
| 764 | +|cancelColor |取消按钮颜色 |String |否 |#757575 |- | | ||
| 765 | +|titleColor |标题颜色 |String |否 |#757575 |- | | ||
| 766 | +|border |是否有分割线 |Boolean |否 |false |true | | ||
| 767 | +|checkStrictly|只有在multiple为true状态下生效; 状态下节点选择完全受控(父子节点选中状态不再关联) |Boolean |否 |false |true | | ||
| 768 | +|checkStrictlyModel|只有在multiple为true状态下生效;父子节点关联模式:strong:强关联(不再受限节点的disabled控制),weak:弱关联(节点关联受disabled控制) |String |是 |weak |strong | | ||
| 769 | +|showHalfCheckedTips|半选提示;只有在multiple为true, checkStrictly为false的状态下生效;父子节点选中状态不再关联,是否展示半选提示; |Boolean |否 |false |true | | ||
| 770 | +|ifSearch| 筛选search模式 |Boolean |否 |true |false | | ||
| 771 | +|searchModel| 搜索模式配置 depHighlight: 从属高亮(显示层级并高亮显示);common: 一般 |String |否 |common |depHighlight | | ||
| 772 | +|showAuxiliaryLine| 是否打开辅助线 |Boolean |否 |false |true | | ||
| 773 | +|loadData| 异步加载函数 (node):Promise([childData]) => {} // demo有说明 |Function |否 |- |- | | ||
| 774 | +|height| 只在uiMode=popup时生效;弹层容器的高度,默认是500 |Number |否 |500 |- | | ||
| 775 | +|changeVerify| 验证函数 (current as any, chooseList as any []):String => {} // 验证函数会把当前控件的选择值作为参数返给函数体,demo有说明 |Function |否 |- |- | | ||
| 776 | + | ||
| 777 | + | ||
| 778 | +# Event 事件 | ||
| 779 | +|事件名 |说明 |类型 |回调参数 | | ||
| 780 | +|---- |---- |---- |---- | | ||
| 781 | +|confirm|菜单收起时返回的筛选结果 |emit |array | | ||
| 782 | +|clear|点击清除按钮时触发 |emit |- | | ||
| 783 | +|cancel|关闭弹层和点击取消时触发 |emit |- | | ||
| 784 | + | ||
| 785 | +## Slot 插槽 | ||
| 786 | + | ||
| 787 | +|名称 |说明 |参数 | | ||
| 788 | +|---- |---- |---- | | ||
| 789 | +|label |label插槽 |data(当前项对于treeData里面的数据) | | ||
| 790 | +|topBar |topBar插槽 |----滚动区域顶部topBar插槽 | | ||
| 791 | +|bottomBar |bottomBar插槽 |----滚动区域底部bottomBar插槽 | | ||
| 792 | +|fixedBottomBar |fixedBottomBar插槽 |----固定在页面的底部,使用fixed进行定位 | | ||
| 793 | +|empty |empty插槽 |----数据为空的插槽 | | ||
| 794 | + |
garbage-removal/src/components/next-tree/style.css
0 → 100644
| 1 | +.next-tree-mask { | ||
| 2 | + position: fixed; | ||
| 3 | + top: 0rpx; | ||
| 4 | + right: 0rpx; | ||
| 5 | + bottom: 0rpx; | ||
| 6 | + left: 0rpx; | ||
| 7 | + z-index: 997; | ||
| 8 | + background-color: rgba(0, 0, 0, 0.6); | ||
| 9 | + opacity: 0; | ||
| 10 | + transition: all 0.3s ease; | ||
| 11 | + visibility: hidden; | ||
| 12 | +} | ||
| 13 | +.next-tree-mask.show { | ||
| 14 | + visibility: visible; | ||
| 15 | + opacity: 1; | ||
| 16 | +} | ||
| 17 | +.next-tree-cnt { | ||
| 18 | + position: fixed; | ||
| 19 | + top: 0rpx; | ||
| 20 | + right: 0rpx; | ||
| 21 | + bottom: 0rpx; | ||
| 22 | + left: 0rpx; | ||
| 23 | + z-index: 997; | ||
| 24 | + top: 360rpx; | ||
| 25 | + transition: all 0.3s ease; | ||
| 26 | + transform: translateY(100%); | ||
| 27 | +} | ||
| 28 | +.next-tree-cnt.next-tree-cnt-page { | ||
| 29 | + transition: none; | ||
| 30 | +} | ||
| 31 | +.next-tree-cnt.show { | ||
| 32 | + transform: translateY(0); | ||
| 33 | +} | ||
| 34 | +.next-tree-bar { | ||
| 35 | + background-color: #fff; | ||
| 36 | + height: 72rpx; | ||
| 37 | + padding-left: 20rpx; | ||
| 38 | + padding-right: 20rpx; | ||
| 39 | + display: flex; | ||
| 40 | + justify-content: space-between; | ||
| 41 | + align-items: center; | ||
| 42 | + box-sizing: border-box; | ||
| 43 | + border-bottom-width: 1rpx !important; | ||
| 44 | + border-bottom-style: solid; | ||
| 45 | + border-bottom-color: #f5f5f5; | ||
| 46 | + font-size: 32rpx; | ||
| 47 | + color: #757575; | ||
| 48 | + line-height: 1; | ||
| 49 | +} | ||
| 50 | +.next-tree-bar-btns { | ||
| 51 | + display: inline-block; | ||
| 52 | + display: flex; | ||
| 53 | + flex-direction: row; | ||
| 54 | +} | ||
| 55 | +.btn-divid { | ||
| 56 | + display: inline-block; | ||
| 57 | + width: 1px; | ||
| 58 | + margin: 0 10px; | ||
| 59 | + background-color: #ccc; | ||
| 60 | +} | ||
| 61 | +.next-tree-bar-confirm { | ||
| 62 | + color: #f9ae3d; | ||
| 63 | +} | ||
| 64 | +.next-tree-view { | ||
| 65 | + position: absolute; | ||
| 66 | + top: 0rpx; | ||
| 67 | + right: 0rpx; | ||
| 68 | + bottom: 0rpx; | ||
| 69 | + left: 0rpx; | ||
| 70 | + top: 72rpx; | ||
| 71 | + background-color: #fff; | ||
| 72 | + padding-top: 20rpx; | ||
| 73 | + padding-right: 20rpx; | ||
| 74 | + padding-bottom: 20rpx; | ||
| 75 | + padding-left: 20rpx; | ||
| 76 | +} | ||
| 77 | +.next-tree-view-sc { | ||
| 78 | + height: 100%; | ||
| 79 | + overflow: hidden; | ||
| 80 | +} | ||
| 81 | +.next-tree-view-sc .empty { | ||
| 82 | + text-align: center; | ||
| 83 | + color: #757575; | ||
| 84 | + padding: 30rpx; | ||
| 85 | +} | ||
| 86 | +.next-tree-item-block { | ||
| 87 | + | ||
| 88 | +} | ||
| 89 | +.next-tree-item { | ||
| 90 | + display: flex; | ||
| 91 | + justify-content: space-between; | ||
| 92 | + align-items: center; | ||
| 93 | + font-size: 26rpx; | ||
| 94 | + color: #757575; | ||
| 95 | + line-height: 1; | ||
| 96 | + height: 0; | ||
| 97 | + opacity: 0; | ||
| 98 | + transition: 0.2s; | ||
| 99 | + position: relative; | ||
| 100 | + overflow: hidden; | ||
| 101 | +} | ||
| 102 | +.next-tree-item .left-line { | ||
| 103 | + position: relative; | ||
| 104 | + width: 1rpx; | ||
| 105 | + height: 100%; | ||
| 106 | + box-sizing: border-box; | ||
| 107 | +} | ||
| 108 | +.next-tree-item .left-line::before { | ||
| 109 | + position: absolute; | ||
| 110 | + content: ""; | ||
| 111 | + width: 1rpx; | ||
| 112 | + height: 100%; | ||
| 113 | + background-color: rgba(204,204,204,0.9); | ||
| 114 | + box-sizing: border-box; | ||
| 115 | + | ||
| 116 | + left: -18rpx; | ||
| 117 | +} | ||
| 118 | +.next-tree-item .parent-horizontal-line { | ||
| 119 | + width: 1rpx; | ||
| 120 | + height: 100%; | ||
| 121 | + position: absolute; | ||
| 122 | + top: 0; | ||
| 123 | + left: 0rpx; | ||
| 124 | + box-sizing: border-box; | ||
| 125 | + background-color: rgba(204,204,204,0.9); | ||
| 126 | +} | ||
| 127 | +.next-tree-item .left-line .horizontal-line { | ||
| 128 | + width: 20rpx; | ||
| 129 | + height: 1rpx; | ||
| 130 | + position: absolute; | ||
| 131 | + top: 40rpx; | ||
| 132 | + left: 0rpx; | ||
| 133 | + background-color: rgba(204,204,204,0.9); | ||
| 134 | + box-sizing: border-box; | ||
| 135 | +} | ||
| 136 | + | ||
| 137 | +.next-tree-item.show { | ||
| 138 | + height: 80rpx; | ||
| 139 | + opacity: 1; | ||
| 140 | +} | ||
| 141 | +.next-tree-item.showchild:before { | ||
| 142 | + transform: rotate(90deg); | ||
| 143 | +} | ||
| 144 | +.next-tree-item.border { | ||
| 145 | + border-bottom: 1rpx solid rgba(204,204,204,0.2); | ||
| 146 | +} | ||
| 147 | +.next-tree-item.last:before { | ||
| 148 | + opacity: 0; | ||
| 149 | +} | ||
| 150 | +.next-tree-item.disabled { | ||
| 151 | + color: #ccc!important; | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +.next-tree-icon { | ||
| 155 | + width: 26rpx; | ||
| 156 | + height: 26rpx; | ||
| 157 | + margin-right: 8rpx; | ||
| 158 | +} | ||
| 159 | +.next-tree-label { | ||
| 160 | + flex: 1; | ||
| 161 | + display: flex; | ||
| 162 | + align-items: center; | ||
| 163 | + height: 100%; | ||
| 164 | + line-height: 1.2; | ||
| 165 | +} | ||
| 166 | +.next-tree-check { | ||
| 167 | + width: 40px; | ||
| 168 | + height: 40px; | ||
| 169 | + display: flex; | ||
| 170 | + justify-content: center; | ||
| 171 | + align-items: center; | ||
| 172 | +} | ||
| 173 | +.next-tree-check-yes, | ||
| 174 | +.next-tree-check-no { | ||
| 175 | + width: 20px; | ||
| 176 | + height: 20px; | ||
| 177 | + border-top-left-radius: 20%; | ||
| 178 | + border-top-right-radius: 20%; | ||
| 179 | + border-bottom-right-radius: 20%; | ||
| 180 | + border-bottom-left-radius: 20%; | ||
| 181 | + border-top-width: 1rpx; | ||
| 182 | + border-left-width: 1rpx; | ||
| 183 | + border-bottom-width: 1rpx; | ||
| 184 | + border-right-width: 1rpx; | ||
| 185 | + border-style: solid; | ||
| 186 | + border-color: #f9ae3d; | ||
| 187 | + display: flex; | ||
| 188 | + justify-content: center; | ||
| 189 | + align-items: center; | ||
| 190 | + box-sizing: border-box; | ||
| 191 | +} | ||
| 192 | +.next-tree-check-yes-b { | ||
| 193 | + border-top-left-radius: 20%; | ||
| 194 | + border-top-right-radius: 20%; | ||
| 195 | + border-bottom-right-radius: 20%; | ||
| 196 | + border-bottom-left-radius: 20%; | ||
| 197 | + background-color: #f9ae3d; | ||
| 198 | + color: #fff; | ||
| 199 | +} | ||
| 200 | +.next-tree-check-yes-b .icon-text { | ||
| 201 | + font-size: 14px; | ||
| 202 | + font-weight: normal; | ||
| 203 | + font-family: uicon-iconfont; | ||
| 204 | + display: flex; | ||
| 205 | + flex-direction: row; | ||
| 206 | + align-items: center; | ||
| 207 | +} | ||
| 208 | +.next-tree-check .radio { | ||
| 209 | + border-top-left-radius: 50%; | ||
| 210 | + border-top-right-radius: 50%; | ||
| 211 | + border-bottom-right-radius: 50%; | ||
| 212 | + border-bottom-left-radius: 50%; | ||
| 213 | +} | ||
| 214 | +.next-tree-check .radio .next-tree-check-yes-b { | ||
| 215 | + border-top-left-radius: 50%; | ||
| 216 | + border-top-right-radius: 50%; | ||
| 217 | + border-bottom-right-radius: 50%; | ||
| 218 | + border-bottom-left-radius: 50%; | ||
| 219 | +} | ||
| 220 | + | ||
| 221 | +.next-tree-item.disabled .next-tree-check-no { | ||
| 222 | + color: #ccc!important; | ||
| 223 | +} | ||
| 224 | +.next-tree-item.disabled .next-tree-check-yes-b { | ||
| 225 | + background-color: #ccc!important; | ||
| 226 | +} | ||
| 227 | +.hover-c { | ||
| 228 | + opacity: 0.6; | ||
| 229 | +} | ||
| 230 | + | ||
| 231 | +.fixed-bottom-bar { | ||
| 232 | + position: fixed; | ||
| 233 | + bottom: 0rpx; | ||
| 234 | + left: 0rpx; | ||
| 235 | + right: 0rpx; | ||
| 236 | + z-index: 998; | ||
| 237 | +} | ||
| 238 | + | ||
| 239 | + |
garbage-removal/src/main.js
| @@ -9,11 +9,9 @@ import App from "./App.vue"; | @@ -9,11 +9,9 @@ import App from "./App.vue"; | ||
| 9 | // 拦截器 | 9 | // 拦截器 |
| 10 | let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]; | 10 | let list = ["navigateTo", "redirectTo", "reLaunch", "switchTab"]; |
| 11 | list.forEach(item => { //用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器 | 11 | list.forEach(item => { //用遍历的方式分别为,uni.navigateTo,uni.redirectTo,uni.reLaunch,uni.switchTab这4个路由方法添加拦截器 |
| 12 | - console.log(item, 'router list item') | ||
| 13 | uni.addInterceptor(item, { | 12 | uni.addInterceptor(item, { |
| 14 | invoke(e) { // 调用前拦截 | 13 | invoke(e) { // 调用前拦截 |
| 15 | //获取用户的token | 14 | //获取用户的token |
| 16 | - console.log(e, 'routerjs invoke') | ||
| 17 | const flag = uni.getStorageSync('cancelFlag'); | 15 | const flag = uni.getStorageSync('cancelFlag'); |
| 18 | //获取当前页面路径(即url去掉"?"和"?"后的参数) | 16 | //获取当前页面路径(即url去掉"?"和"?"后的参数) |
| 19 | if (flag) { | 17 | if (flag) { |
garbage-removal/src/pages.json
| @@ -52,6 +52,14 @@ | @@ -52,6 +52,14 @@ | ||
| 52 | "enablePullDownRefresh": false | 52 | "enablePullDownRefresh": false |
| 53 | } | 53 | } |
| 54 | },{ | 54 | },{ |
| 55 | + "path": "pages/order/success/index", | ||
| 56 | + "style": { | ||
| 57 | + "navigationBarTitleText": "完成派单", | ||
| 58 | + "navigationBarTextStyle": "white", | ||
| 59 | + "navigationBarBackgroundColor": "#53c21d", | ||
| 60 | + "enablePullDownRefresh": false | ||
| 61 | + } | ||
| 62 | + },{ | ||
| 55 | "path": "pages/order/guest/index", | 63 | "path": "pages/order/guest/index", |
| 56 | "style": { | 64 | "style": { |
| 57 | "navigationBarTitleText": "详情", | 65 | "navigationBarTitleText": "详情", |
garbage-removal/src/pages/home/address/addSite.vue
| @@ -5,7 +5,7 @@ | @@ -5,7 +5,7 @@ | ||
| 5 | <u--form :labelStyle="{ color: '#909399' }" labelPosition="left" labelWidth="140" :model="addressInfo" | 5 | <u--form :labelStyle="{ color: '#909399' }" labelPosition="left" labelWidth="140" :model="addressInfo" |
| 6 | ref="addressFrom"> | 6 | ref="addressFrom"> |
| 7 | <u-form-item :required="true" label="所在地区" prop="addressArea" borderBottom> | 7 | <u-form-item :required="true" label="所在地区" prop="addressArea" borderBottom> |
| 8 | - <view @click="showRegionPicker" class="input-box"> | 8 | + <view @click.stop="showRegionPicker" hover-class="click-box"> |
| 9 | <u--input border="none" readonly style="pointer-events:none" type="text" v-model="addressInfo.addressArea" | 9 | <u--input border="none" readonly style="pointer-events:none" type="text" v-model="addressInfo.addressArea" |
| 10 | placeholder-class="line" placeholder="省市区县、乡镇等"></u--input> | 10 | placeholder-class="line" placeholder="省市区县、乡镇等"></u--input> |
| 11 | </view> | 11 | </view> |
| @@ -38,10 +38,10 @@ | @@ -38,10 +38,10 @@ | ||
| 38 | </view> | 38 | </view> |
| 39 | </view> | 39 | </view> |
| 40 | <view class="submit-button"> | 40 | <view class="submit-button"> |
| 41 | - <view v-if="addFlag" @click="submit" class="add">新增地址</view> | 41 | + <view v-if="addFlag" @click="submit" class="add" hover-class="click-box">新增地址</view> |
| 42 | <view v-else class="update-box"> | 42 | <view v-else class="update-box"> |
| 43 | - <view class="del" @click="handleDeleteClick">删除地址</view> | ||
| 44 | - <view class="update" @click="handleUpdateClick">保存地址</view> | 43 | + <view class="del" @click="handleDeleteClick" hover-class="click-box">删除地址</view> |
| 44 | + <view class="update" @click="handleUpdateClick" hover-class="click-box">保存地址</view> | ||
| 45 | </view> | 45 | </view> |
| 46 | </view> | 46 | </view> |
| 47 | </view> | 47 | </view> |
| @@ -239,9 +239,7 @@ const reset = () => { | @@ -239,9 +239,7 @@ const reset = () => { | ||
| 239 | } | 239 | } |
| 240 | } | 240 | } |
| 241 | 241 | ||
| 242 | - .input-box { | ||
| 243 | - @include handleClick; | ||
| 244 | - } | 242 | + |
| 245 | 243 | ||
| 246 | 244 | ||
| 247 | .submit-button { | 245 | .submit-button { |
| @@ -291,7 +289,9 @@ const reset = () => { | @@ -291,7 +289,9 @@ const reset = () => { | ||
| 291 | 289 | ||
| 292 | } | 290 | } |
| 293 | } | 291 | } |
| 292 | +} | ||
| 294 | 293 | ||
| 295 | - | 294 | +.click-box { |
| 295 | + @include handleClick; | ||
| 296 | } | 296 | } |
| 297 | </style> | 297 | </style> |
garbage-removal/src/pages/home/address/index.vue
| @@ -18,7 +18,7 @@ | @@ -18,7 +18,7 @@ | ||
| 18 | </view> | 18 | </view> |
| 19 | 19 | ||
| 20 | </view> | 20 | </view> |
| 21 | - <view class="addSite" @tap="toAddSite"> | 21 | + <view class="addSite" @click.stop="toAddSite" hover-class="click-box"> |
| 22 | <view class="add">添加地址</view> | 22 | <view class="add">添加地址</view> |
| 23 | </view> | 23 | </view> |
| 24 | </view> | 24 | </view> |
| @@ -166,4 +166,8 @@ onShow(() => { | @@ -166,4 +166,8 @@ onShow(() => { | ||
| 166 | } | 166 | } |
| 167 | } | 167 | } |
| 168 | } | 168 | } |
| 169 | + | ||
| 170 | +.click-box { | ||
| 171 | + @include handleClick; | ||
| 172 | +} | ||
| 169 | </style> | 173 | </style> |
garbage-removal/src/pages/home/clean/index.vue
| 1 | <template> | 1 | <template> |
| 2 | - <liu-delivery-time :isMask="true" :change="changeTime" ref="chooseTime" title="请选择预约时间"></liu-delivery-time> | 2 | + <view class="mask-box"> |
| 3 | + <liu-delivery-time :isMask="true" :change="changeTime" ref="chooseTime" title="请选择预约时间"></liu-delivery-time> | ||
| 4 | + <u-picker closeOnClickOverlay :show="carTypeShowFlag" :columns="candidates" :itemHeight="100" | ||
| 5 | + @confirm="handlePickerCarInfoConfirm" @cancel="handleCarInfoClick(false)" | ||
| 6 | + @close="handleCarInfoClick(false)"></u-picker> | ||
| 7 | + <u-picker closeOnClickOverlay :show="garbageTypeShowFlag" :columns="garbageTypeList" :itemHeight="100" | ||
| 8 | + @confirm="handlePickerGarbageTypeConfirm" @close="handleGarbageTypeClick(false)" | ||
| 9 | + @cancel="handleGarbageTypeClick(false)"></u-picker> | ||
| 10 | + <u-popup :zIndex="10074" closeOnClickOverlay :show="carPopupShowFlag" :round="10" @close="handlePopupClick(false)" | ||
| 11 | + @open="handlePopupClick(true)"> | ||
| 12 | + <view class="company-clean-container-car-popup"> | ||
| 13 | + <!-- 主要内容 --> | ||
| 14 | + <view class="company-clean-container-car-popup-content"> | ||
| 15 | + <view class="company-clean-container-car-popup-content-title"> | ||
| 16 | + <view style="text-align: center;"> | ||
| 17 | + 车辆类型 | ||
| 18 | + </view> | ||
| 19 | + </view> | ||
| 20 | + <view class="company-clean-container-car-popup-content-box"> | ||
| 21 | + <view class="company-clean-container-car-popup-content-box-item" v-for="(item, index) in garCarInfoList" | ||
| 22 | + :key="index"> | ||
| 23 | + <view class="company-clean-container-car-popup-content-box-item-text"> | ||
| 24 | + {{ item.garOrderCarType }} | ||
| 25 | + </view> | ||
| 26 | + <view class="company-clean-container-car-popup-content-box-item-number" hover-class="hoverClickStyle"> | ||
| 27 | + <u-number-box :min="0" :max="9999" integer buttonSize="46" :inputWidth="100" | ||
| 28 | + v-model="garCarInfoList[item.garOrderCarType].garOrderCarNumber"></u-number-box> | ||
| 29 | + </view> | ||
| 30 | + </view> | ||
| 31 | + | ||
| 32 | + </view> | ||
| 33 | + </view> | ||
| 34 | + <!-- 占位盒子 --> | ||
| 35 | + <view class="company-clean-container-car-popup-button-safe"> | ||
| 36 | + | ||
| 37 | + </view> | ||
| 38 | + </view> | ||
| 39 | + </u-popup> | ||
| 40 | + </view> | ||
| 3 | <view class="company-clean-container"> | 41 | <view class="company-clean-container"> |
| 4 | <view class="company-clean-container-box"> | 42 | <view class="company-clean-container-box"> |
| 5 | <view class="company-clean-container-header"> | 43 | <view class="company-clean-container-header"> |
| @@ -21,34 +59,42 @@ | @@ -21,34 +59,42 @@ | ||
| 21 | </view> | 59 | </view> |
| 22 | <view class="company-clean-container-car-main"> | 60 | <view class="company-clean-container-car-main"> |
| 23 | <view class="company-clean-container-car-main-content"> | 61 | <view class="company-clean-container-car-main-content"> |
| 62 | + <view v-if="paramFrom.carType" class="company-clean-container-car-main-content-type"> | ||
| 63 | + <text class="company-clean-container-car-main-content-type-price-area"><text | ||
| 64 | + style="color: red;">*</text>车辆类型:</text> | ||
| 65 | + <!-- <uni-combox label="" :candidates="candidates" placeholder="请选择运输车辆类型" | ||
| 66 | + v-model="paramFrom.carType"></uni-combox> --> | ||
| 67 | + <view class="" hover-class="hoverClickStyle" @click.stop="handleCarInfoClick(true)"> | ||
| 68 | + <u--input color="#909399" border="none" style="pointer-events:none" :modelValue="paramFrom.carType" | ||
| 69 | + type="text" placeholder-class="line" readonly /> | ||
| 70 | + </view> | ||
| 71 | + </view> | ||
| 24 | <view class="company-clean-container-car-main-content-type"> | 72 | <view class="company-clean-container-car-main-content-type"> |
| 25 | <text class="company-clean-container-car-main-content-type-price-area"><text | 73 | <text class="company-clean-container-car-main-content-type-price-area"><text |
| 26 | style="color: red;">*</text>垃圾类型:</text> | 74 | style="color: red;">*</text>垃圾类型:</text> |
| 27 | - <uni-combox label="" :candidates="garbageTypeList" placeholder="请选择垃圾类型" | ||
| 28 | - v-model="paramFrom.garbageType"></uni-combox> | 75 | + <view hover-class="hoverClickStyle" @click.stop="handleGarbageTypeClick(true)"> |
| 76 | + <u--input color="#909399" border="none" style="pointer-events:none" :modelValue="paramFrom.garbageType" | ||
| 77 | + type="text" placeholder-class="line" readonly /> | ||
| 78 | + </view> | ||
| 29 | </view> | 79 | </view> |
| 30 | - <!-- <view class="company-clean-container-car-main-content-img"> | ||
| 31 | - <image class="company-clean-container-car-main-content-img" /> | 80 | + <view class="company-clean-container-car-main-content-img"> |
| 81 | + <image class="company-clean-container-car-main-content-img" :src="carFront" /> | ||
| 32 | </view> | 82 | </view> |
| 33 | <view class="company-clean-container-car-main-content-remark"> | 83 | <view class="company-clean-container-car-main-content-remark"> |
| 34 | - 箱体长4.2m宽1.1,高0.7,最多课容纳约110袋袋装修垃圾(75cm*45每袋) | ||
| 35 | - </view> --> | ||
| 36 | - <view class="company-clean-container-car-main-content-type"> | ||
| 37 | - <text class="company-clean-container-car-main-content-type-price-area"><text | ||
| 38 | - style="color: red;">*</text>车辆类型:</text> | ||
| 39 | - <uni-combox label="" :candidates="candidates" placeholder="请选择运输车辆类型" | ||
| 40 | - v-model="paramFrom.carType"></uni-combox> | 84 | + {{ garCarTransportInfo }} |
| 41 | </view> | 85 | </view> |
| 42 | - <view class="company-clean-container-car-main-content-number"> | 86 | + |
| 87 | + <view v-if="paramFrom.carType" class="company-clean-container-car-main-content-number"> | ||
| 43 | <view class="company-clean-container-car-main-content-number-txt"> | 88 | <view class="company-clean-container-car-main-content-number-txt"> |
| 44 | <text style="color: red;">*</text>添加车辆数量 | 89 | <text style="color: red;">*</text>添加车辆数量 |
| 45 | </view> | 90 | </view> |
| 46 | <view class="company-clean-container-car-main-content-number-button"> | 91 | <view class="company-clean-container-car-main-content-number-button"> |
| 47 | - <u-number-box :min="1" integer buttonSize="46" v-model="paramFrom.carNumber"></u-number-box> | 92 | + <u-number-box :min="0" :max="9999" integer buttonSize="46" :inputWidth="100" |
| 93 | + v-model="garCarInfoList[paramFrom.carType].garOrderCarNumber"></u-number-box> | ||
| 48 | </view> | 94 | </view> |
| 49 | </view> | 95 | </view> |
| 50 | <view class="company-clean-container-car-main-content-prompt"> | 96 | <view class="company-clean-container-car-main-content-prompt"> |
| 51 | - 温馨提示:垃圾类型不符合,有权拒绝清运。 | 97 | + 温馨提示:垃圾类型不符合,企业有权拒绝清运。 |
| 52 | </view> | 98 | </view> |
| 53 | </view> | 99 | </view> |
| 54 | </view> | 100 | </view> |
| @@ -77,8 +123,8 @@ | @@ -77,8 +123,8 @@ | ||
| 77 | </view> | 123 | </view> |
| 78 | </view> | 124 | </view> |
| 79 | </view> | 125 | </view> |
| 80 | - <view class="company-clean-bottom"> | ||
| 81 | - <movable-area ref="movableAreaElement" class="movableArea"> | 126 | + <view class="company-clean-bottom" style="z-index: 10074;"> |
| 127 | + <movable-area v-if="!carPopupShowFlag" ref="movableAreaElement" class="movableArea"> | ||
| 82 | <movable-view class="movableView" :x="x" :y="y" direction="all" @change="onChange"> | 128 | <movable-view class="movableView" :x="x" :y="y" direction="all" @change="onChange"> |
| 83 | <view class="company-clean-call-box-container"> | 129 | <view class="company-clean-call-box-container"> |
| 84 | <u-icon @click="handleContactClick(tel)" name="phone-fill" color="#ffffff" size="50"></u-icon> | 130 | <u-icon @click="handleContactClick(tel)" name="phone-fill" color="#ffffff" size="50"></u-icon> |
| @@ -87,7 +133,12 @@ | @@ -87,7 +133,12 @@ | ||
| 87 | </movable-area> | 133 | </movable-area> |
| 88 | <view class="company-clean-bottom-box"> | 134 | <view class="company-clean-bottom-box"> |
| 89 | <view class="company-clean-bottom-left"> | 135 | <view class="company-clean-bottom-left"> |
| 90 | - <u-icon @click="handleCarInfo" :stop="true" size="50" name="car-fill"></u-icon> | 136 | + <view class="company-clean-bottom-left-icon"> |
| 137 | + <u-icon @click="carPopupShowFlag = true" :stop="true" size="50" name="car-fill"></u-icon> | ||
| 138 | + </view> | ||
| 139 | + <view class="company-clean-bottom-left-number"> | ||
| 140 | + <up-badge :type="type" max="99" :value="garCarNumberCount"></up-badge> | ||
| 141 | + </view> | ||
| 91 | </view> | 142 | </view> |
| 92 | <view class="company-clean-bottom-right"> | 143 | <view class="company-clean-bottom-right"> |
| 93 | <u-button @click="handleOderSure" shape="circle" color="#a9e08f" text="立即派单"></u-button> | 144 | <u-button @click="handleOderSure" shape="circle" color="#a9e08f" text="立即派单"></u-button> |
| @@ -102,24 +153,66 @@ import { queryCarList } from '@/apis/carinfo.js'; | @@ -102,24 +153,66 @@ import { queryCarList } from '@/apis/carinfo.js'; | ||
| 102 | import { uploadFilePromise } from '@/apis/common.js'; | 153 | import { uploadFilePromise } from '@/apis/common.js'; |
| 103 | import { saveOrder } from '@/apis/order.js'; | 154 | import { saveOrder } from '@/apis/order.js'; |
| 104 | import liuDeliveryTime from "@/components/liu-delivery-time/liu-delivery-time.vue"; | 155 | import liuDeliveryTime from "@/components/liu-delivery-time/liu-delivery-time.vue"; |
| 105 | -import uniCombox from "@/components/uni-combox/index.vue"; | 156 | +import { useMainStore } from '@/stores/index.js'; |
| 106 | import { onLoad } from '@dcloudio/uni-app'; | 157 | import { onLoad } from '@dcloudio/uni-app'; |
| 107 | -import { getCurrentInstance, onMounted, ref } from 'vue'; | 158 | +import { computed, getCurrentInstance, nextTick, ref, watch } from 'vue'; |
| 108 | const { proxy } = getCurrentInstance(); | 159 | const { proxy } = getCurrentInstance(); |
| 160 | + | ||
| 161 | +const store = useMainStore(); | ||
| 162 | +const userType = computed(() => store.userType) | ||
| 109 | const x = ref(5) | 163 | const x = ref(5) |
| 110 | const y = ref() | 164 | const y = ref() |
| 111 | const movableAreaElement = ref() | 165 | const movableAreaElement = ref() |
| 112 | const companyObj = ref() | 166 | const companyObj = ref() |
| 113 | const tel = ref() | 167 | const tel = ref() |
| 168 | +const carTypeShowFlag = ref(false) | ||
| 169 | +const garbageTypeShowFlag = ref(false) | ||
| 170 | +const carPopupShowFlag = ref(false) | ||
| 114 | const userAddress = ref({ | 171 | const userAddress = ref({ |
| 115 | garUserContactName: "", | 172 | garUserContactName: "", |
| 116 | garUserContactTel: "", | 173 | garUserContactTel: "", |
| 117 | garRemark: "", | 174 | garRemark: "", |
| 118 | garUserAddress: "" | 175 | garUserAddress: "" |
| 119 | }) | 176 | }) |
| 120 | -const garbageTypeList = ref(["建筑垃圾", "装修垃圾"]) | 177 | +// 车辆信息 |
| 178 | +const garCarInfoList = ref({}) | ||
| 179 | +const garCarLabelInfoList = ref({}) | ||
| 180 | +const garCarLabelInfoNow = ref() | ||
| 181 | +const garCarTransportInfo = computed(() => { | ||
| 182 | + try { | ||
| 183 | + let carInfo = garCarLabelInfoNow.value | ||
| 184 | + let lengthWidthHeight = carInfo.lengthWidthHeight.split(";"); | ||
| 185 | + let boxLength = lengthWidthHeight[0]; // 箱子的长度(单位:米) | ||
| 186 | + let boxWidth = lengthWidthHeight[1]; // 箱子的宽度(单位:米) | ||
| 187 | + let boxHeight = lengthWidthHeight[2]; // 箱子的高度(单位:米) | ||
| 188 | + | ||
| 189 | + let bagLength = 0.75; // 袋子的长度(单位:米) | ||
| 190 | + let bagWidth = 0.45; // 袋子的宽度(单位:米) | ||
| 191 | + let bagHeight = 0.22; // 袋子的高度(单位:米) | ||
| 192 | + | ||
| 193 | + let boxVolume = boxLength * boxWidth * boxHeight; // 箱子的体积(单位:立方米) | ||
| 194 | + let bagVolume = bagLength * bagWidth * bagHeight; // 袋子的体积(单位:立方米) | ||
| 195 | + | ||
| 196 | + let bagCount = Math.floor(boxVolume / bagVolume); // 箱子可以容纳的袋子数量(向下取整) | ||
| 197 | + | ||
| 198 | + return `箱体长${boxLength}m宽${boxWidth}m高${boxHeight}m,最多课容纳约${bagCount}袋袋装修垃圾(75cm * 45cm每袋)。` | ||
| 199 | + } catch (error) { | ||
| 200 | + return "符合装修垃圾运输管理规范的新型环保智能装修垃圾运输车。" | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | +}) | ||
| 204 | +// 车辆数量 | ||
| 205 | +const garCarNumberCount = computed(() => { | ||
| 206 | + let count = 0; | ||
| 207 | + for (const key in garCarInfoList.value) { | ||
| 208 | + const element = garCarInfoList.value[key]; | ||
| 209 | + count += element.garOrderCarNumber; | ||
| 210 | + } | ||
| 211 | + return count; | ||
| 212 | +}) | ||
| 213 | +const garbageTypeList = ref([["装修垃圾", "建筑垃圾"]]) | ||
| 121 | const paramFrom = ref({ | 214 | const paramFrom = ref({ |
| 122 | - carNumber: 1, | 215 | + carNumber: 0, |
| 123 | remark: "", | 216 | remark: "", |
| 124 | sureReadFlag: [], | 217 | sureReadFlag: [], |
| 125 | carType: "", | 218 | carType: "", |
| @@ -143,18 +236,48 @@ const changeAgree = (e) => { | @@ -143,18 +236,48 @@ const changeAgree = (e) => { | ||
| 143 | const onChange = (e) => { | 236 | const onChange = (e) => { |
| 144 | // console.log(e); | 237 | // console.log(e); |
| 145 | } | 238 | } |
| 239 | + | ||
| 240 | +const handlePopupClick = (val) => { | ||
| 241 | + carPopupShowFlag.value = val | ||
| 242 | +} | ||
| 243 | + | ||
| 146 | /** | 244 | /** |
| 147 | * 初始化信息 | 245 | * 初始化信息 |
| 148 | */ | 246 | */ |
| 149 | onLoad((options) => { | 247 | onLoad((options) => { |
| 248 | + | ||
| 150 | companyObj.value = JSON.parse(options.companyObj); | 249 | companyObj.value = JSON.parse(options.companyObj); |
| 151 | tel.value = options.tel; | 250 | tel.value = options.tel; |
| 152 | userAddress.value = JSON.parse(options.userAddress); | 251 | userAddress.value = JSON.parse(options.userAddress); |
| 153 | queryCarList({ companyId: companyObj.value.id }).then(res => { | 252 | queryCarList({ companyId: companyObj.value.id }).then(res => { |
| 154 | - candidates.value = [...new Set(res.data.rows.map(item => item.carType))]; | 253 | + // 设置车辆类型 |
| 254 | + candidates.value = [[...new Set(res.data.rows | ||
| 255 | + .filter(item => item.containerVolume) | ||
| 256 | + .map(item => { | ||
| 257 | + garCarLabelInfoList.value[item.containerVolume + "方车"] = item | ||
| 258 | + return item.containerVolume + "方车" | ||
| 259 | + })) | ||
| 260 | + ]]; | ||
| 261 | + // 设置初始车辆数量 | ||
| 262 | + candidates.value[0].forEach((item, index) => { | ||
| 263 | + garCarInfoList.value[item] = { | ||
| 264 | + garOrderCarNumber: 0, | ||
| 265 | + garOrderCarType: item | ||
| 266 | + } | ||
| 267 | + }) | ||
| 268 | + // 设置默认车辆 | ||
| 269 | + paramFrom.value.carType = candidates.value[0][0]; | ||
| 270 | + garCarLabelInfoNow.value = garCarLabelInfoList.value[paramFrom.value.carType] | ||
| 155 | }) | 271 | }) |
| 156 | }) | 272 | }) |
| 157 | 273 | ||
| 274 | + | ||
| 275 | +const handleCarInfoClick = (val) => { | ||
| 276 | + carTypeShowFlag.value = val | ||
| 277 | +} | ||
| 278 | +const handleGarbageTypeClick = (val) => { | ||
| 279 | + garbageTypeShowFlag.value = val | ||
| 280 | +} | ||
| 158 | /** | 281 | /** |
| 159 | * 拨打电话回调 | 282 | * 拨打电话回调 |
| 160 | */ | 283 | */ |
| @@ -195,18 +318,26 @@ const afterRead = async (event) => { | @@ -195,18 +318,26 @@ const afterRead = async (event) => { | ||
| 195 | }; | 318 | }; |
| 196 | 319 | ||
| 197 | 320 | ||
| 198 | - | ||
| 199 | -/** | ||
| 200 | - * 处理车子数量 | ||
| 201 | - */ | ||
| 202 | -const handleCarInfo = () => { | ||
| 203 | - | 321 | +const handlePickerGarbageTypeConfirm = (e) => { |
| 322 | + paramFrom.value.garbageType = e.value | ||
| 323 | + garbageTypeShowFlag.value = false | ||
| 324 | +} | ||
| 325 | +const handlePickerCarInfoConfirm = (e) => { | ||
| 326 | + paramFrom.value.carType = e.value | ||
| 327 | + garCarLabelInfoNow.value = garCarLabelInfoList.value[paramFrom.value.carType] | ||
| 328 | + carTypeShowFlag.value = false | ||
| 329 | + console.log(garCarLabelInfoNow.value); | ||
| 204 | } | 330 | } |
| 205 | 331 | ||
| 206 | /** | 332 | /** |
| 207 | * 处理下单 | 333 | * 处理下单 |
| 208 | */ | 334 | */ |
| 209 | const handleOderSure = () => { | 335 | const handleOderSure = () => { |
| 336 | + let garCarInfos = []; | ||
| 337 | + for (const key in garCarInfoList.value) { | ||
| 338 | + garCarInfos.push(garCarInfoList.value[key]) | ||
| 339 | + } | ||
| 340 | + | ||
| 210 | let params = { | 341 | let params = { |
| 211 | /** | 342 | /** |
| 212 | * 派单地址 | 343 | * 派单地址 |
| @@ -222,8 +353,7 @@ const handleOderSure = () => { | @@ -222,8 +353,7 @@ const handleOderSure = () => { | ||
| 222 | * 派单姓名 | 353 | * 派单姓名 |
| 223 | */ | 354 | */ |
| 224 | garOrderContactName: userAddress.value.garUserContactName, | 355 | garOrderContactName: userAddress.value.garUserContactName, |
| 225 | - garOrderCarNumber: paramFrom.value.carNumber, | ||
| 226 | - garOrderCarType: paramFrom.value.carType, | 356 | + garCarInfoList: garCarInfos, |
| 227 | 357 | ||
| 228 | /** | 358 | /** |
| 229 | * 垃圾类型 | 359 | * 垃圾类型 |
| @@ -248,7 +378,7 @@ const handleOderSure = () => { | @@ -248,7 +378,7 @@ const handleOderSure = () => { | ||
| 248 | /** | 378 | /** |
| 249 | * 公司负责人电话 | 379 | * 公司负责人电话 |
| 250 | */ | 380 | */ |
| 251 | - garOrderCompanyTel: companyObj.value.safetyManagerPhone, | 381 | + garOrderCompanyTel: companyObj.value.servicePhone, |
| 252 | 382 | ||
| 253 | /** | 383 | /** |
| 254 | * 约定时间 | 384 | * 约定时间 |
| @@ -266,34 +396,32 @@ const handleOderSure = () => { | @@ -266,34 +396,32 @@ const handleOderSure = () => { | ||
| 266 | if (!validateParams(params)) { | 396 | if (!validateParams(params)) { |
| 267 | return; | 397 | return; |
| 268 | } | 398 | } |
| 399 | + | ||
| 269 | saveOrder(params).then(res => { | 400 | saveOrder(params).then(res => { |
| 270 | // TODO 派单详情 | 401 | // TODO 派单详情 |
| 271 | if (res.data.success) { | 402 | if (res.data.success) { |
| 272 | - uni.$u.route({ | ||
| 273 | - type: "redirect", | ||
| 274 | - url: `pages/order/detail/index`, | ||
| 275 | - params: { | ||
| 276 | - orderId: res.data.data | ||
| 277 | - } | ||
| 278 | - }) | 403 | + if (userType.value === "运输驾驶员") { |
| 404 | + uni.$u.toast("派单成功,请切换成且角色查看订单详情") | ||
| 405 | + setTimeout(() => { | ||
| 406 | + uni.navigateBack({ | ||
| 407 | + delta: 1, | ||
| 408 | + }) | ||
| 409 | + }, 50) | ||
| 410 | + } else { | ||
| 411 | + uni.$u.route({ | ||
| 412 | + type: "redirect", | ||
| 413 | + url: `pages/order/detail/index`, | ||
| 414 | + params: { | ||
| 415 | + orderId: res.data.data | ||
| 416 | + } | ||
| 417 | + }) | ||
| 418 | + uni.$u.toast(res.data.msg) | ||
| 419 | + } | ||
| 420 | + | ||
| 279 | } | 421 | } |
| 280 | - uni.$u.toast(res.data.msg) | ||
| 281 | }) | 422 | }) |
| 282 | - | ||
| 283 | } | 423 | } |
| 284 | 424 | ||
| 285 | -onMounted(() => { | ||
| 286 | - let areaHeight; | ||
| 287 | - // select中的参数就如css选择器一样选择元素 | ||
| 288 | - let movableArea = uni.createSelectorQuery().in(proxy).select(".movableArea"); | ||
| 289 | - movableArea.boundingClientRect(function (data) { | ||
| 290 | - // data - 包含元素的高度等信息 | ||
| 291 | - areaHeight = data.height; | ||
| 292 | - y.value = areaHeight > 20 ? (areaHeight - 20) : areaHeight; | ||
| 293 | - }).exec(function (res) { | ||
| 294 | - // 注意:exec方法必须执行,即便什么也不做,否则不会获取到任何数据 | ||
| 295 | - }) | ||
| 296 | -}) | ||
| 297 | 425 | ||
| 298 | /** | 426 | /** |
| 299 | * 校验参数 | 427 | * 校验参数 |
| @@ -310,15 +438,21 @@ const validateParams = (params) => { | @@ -310,15 +438,21 @@ const validateParams = (params) => { | ||
| 310 | case "garOrderAgreementTime": | 438 | case "garOrderAgreementTime": |
| 311 | jumpPrompt('请选择预约时间') | 439 | jumpPrompt('请选择预约时间') |
| 312 | break; | 440 | break; |
| 313 | - case "garOrderTrashType": | ||
| 314 | - jumpPrompt('请选择垃圾类型') | ||
| 315 | - break; | ||
| 316 | - case "garOrderCarType": | ||
| 317 | - jumpPrompt('请选择车辆类型') | ||
| 318 | - break; | 441 | + |
| 319 | } | 442 | } |
| 320 | return false; | 443 | return false; |
| 321 | } | 444 | } |
| 445 | + if (key === "garCarInfoList") { | ||
| 446 | + let count = 0; | ||
| 447 | + params[key].forEach(item => { | ||
| 448 | + count += item.garOrderCarNumber; | ||
| 449 | + }) | ||
| 450 | + if (count === 0) { | ||
| 451 | + jumpPrompt('请添加车辆数量') | ||
| 452 | + return false; | ||
| 453 | + } | ||
| 454 | + } | ||
| 455 | + | ||
| 322 | if (key == "imageUrls") { | 456 | if (key == "imageUrls") { |
| 323 | if (params[key].length == 0) { | 457 | if (params[key].length == 0) { |
| 324 | jumpPrompt('请上传现场图片') | 458 | jumpPrompt('请上传现场图片') |
| @@ -355,6 +489,31 @@ const validateImage = (fileList) => { | @@ -355,6 +489,31 @@ const validateImage = (fileList) => { | ||
| 355 | return true; | 489 | return true; |
| 356 | } | 490 | } |
| 357 | 491 | ||
| 492 | + | ||
| 493 | +// 开始执行一次 | ||
| 494 | +watch(carPopupShowFlag, (val) => { | ||
| 495 | + // console.log(val); | ||
| 496 | + // carPopupShowFlag.value = val | ||
| 497 | + if (!val) { | ||
| 498 | + setTimeout(() => { | ||
| 499 | + nextTick(() => { | ||
| 500 | + let areaHeight; | ||
| 501 | + // select中的参数就如css选择器一样选择元素 | ||
| 502 | + let movableArea = uni.createSelectorQuery().in(proxy).select(".movableArea"); | ||
| 503 | + movableArea.boundingClientRect(function (data) { | ||
| 504 | + // data - 包含元素的高度等信息 | ||
| 505 | + areaHeight = data.height; | ||
| 506 | + y.value = areaHeight > 40 ? (areaHeight - 40) : areaHeight; | ||
| 507 | + }).exec(function (res) { | ||
| 508 | + // 注意:exec方法必须执行,即便什么也不做,否则不会获取到任何数据 | ||
| 509 | + }) | ||
| 510 | + }) | ||
| 511 | + }, 0); | ||
| 512 | + } | ||
| 513 | +}, { | ||
| 514 | + immediate: true | ||
| 515 | +}) | ||
| 516 | + | ||
| 358 | </script> | 517 | </script> |
| 359 | 518 | ||
| 360 | <style lang="scss" scoped> | 519 | <style lang="scss" scoped> |
| @@ -363,6 +522,7 @@ $custom-page-padding: 20rpx; | @@ -363,6 +522,7 @@ $custom-page-padding: 20rpx; | ||
| 363 | $custom-border-radio: 20rpx; | 522 | $custom-border-radio: 20rpx; |
| 364 | $custom-bottom-height: 200rpx; | 523 | $custom-bottom-height: 200rpx; |
| 365 | 524 | ||
| 525 | + | ||
| 366 | .company-clean-container { | 526 | .company-clean-container { |
| 367 | height: 100%; | 527 | height: 100%; |
| 368 | width: 100%; | 528 | width: 100%; |
| @@ -546,6 +706,8 @@ $custom-bottom-height: 200rpx; | @@ -546,6 +706,8 @@ $custom-bottom-height: 200rpx; | ||
| 546 | // height: 100%; | 706 | // height: 100%; |
| 547 | bottom: 0; | 707 | bottom: 0; |
| 548 | left: 0; | 708 | left: 0; |
| 709 | + // 阴影 | ||
| 710 | + box-shadow: 0 0 10rpx 0 rgba(0, 0, 0, 0.1); | ||
| 549 | 711 | ||
| 550 | .movableArea { | 712 | .movableArea { |
| 551 | pointer-events: none; | 713 | pointer-events: none; |
| @@ -583,7 +745,12 @@ $custom-bottom-height: 200rpx; | @@ -583,7 +745,12 @@ $custom-bottom-height: 200rpx; | ||
| 583 | align-items: center; | 745 | align-items: center; |
| 584 | 746 | ||
| 585 | .company-clean-bottom-left { | 747 | .company-clean-bottom-left { |
| 586 | - transform: rotateY(180deg); | 748 | + display: flex; |
| 749 | + | ||
| 750 | + .company-clean-bottom-left-icon { | ||
| 751 | + transform: rotateY(180deg); | ||
| 752 | + } | ||
| 753 | + | ||
| 587 | } | 754 | } |
| 588 | 755 | ||
| 589 | .company-clean-bottom-right { | 756 | .company-clean-bottom-right { |
| @@ -594,5 +761,53 @@ $custom-bottom-height: 200rpx; | @@ -594,5 +761,53 @@ $custom-bottom-height: 200rpx; | ||
| 594 | } | 761 | } |
| 595 | 762 | ||
| 596 | 763 | ||
| 764 | + | ||
| 765 | +} | ||
| 766 | + | ||
| 767 | +.hoverClickStyle { | ||
| 768 | + @include handleClick; | ||
| 769 | +} | ||
| 770 | + | ||
| 771 | +// 弹出框 | ||
| 772 | +.company-clean-container-car-popup { | ||
| 773 | + min-height: 450rpx; | ||
| 774 | + padding: $custom-page-padding; | ||
| 775 | + box-sizing: border-box; | ||
| 776 | + | ||
| 777 | + .company-clean-container-car-popup-content { | ||
| 778 | + font-size: 28rpx; | ||
| 779 | + | ||
| 780 | + .company-clean-container-car-popup-content-box { | ||
| 781 | + box-sizing: border-box; | ||
| 782 | + padding: $custom-page-padding; | ||
| 783 | + border: 2rpx solid #a9e08f; | ||
| 784 | + border-radius: 10rpx; | ||
| 785 | + | ||
| 786 | + .company-clean-container-car-popup-content-box-item { | ||
| 787 | + display: flex; | ||
| 788 | + align-items: center; | ||
| 789 | + justify-content: space-between; | ||
| 790 | + margin: 20rpx 0; | ||
| 791 | + box-sizing: border-box; | ||
| 792 | + | ||
| 793 | + .company-clean-container-car-popup-content-box-item-text {} | ||
| 794 | + | ||
| 795 | + .company-clean-container-car-popup-content-box-item-number {} | ||
| 796 | + } | ||
| 797 | + } | ||
| 798 | + | ||
| 799 | + .company-clean-container-car-popup-content-title { | ||
| 800 | + color: $u-main-color; | ||
| 801 | + box-sizing: border-box; | ||
| 802 | + margin-bottom: 20rpx; | ||
| 803 | + font-size: 30rpx; | ||
| 804 | + font-weight: bold; | ||
| 805 | + } | ||
| 806 | + } | ||
| 807 | + | ||
| 808 | + .company-clean-container-car-popup-button-safe { | ||
| 809 | + width: 100%; | ||
| 810 | + height: $custom-bottom-height; | ||
| 811 | + } | ||
| 597 | } | 812 | } |
| 598 | </style> | 813 | </style> |
garbage-removal/src/pages/home/index.vue
| @@ -47,24 +47,25 @@ | @@ -47,24 +47,25 @@ | ||
| 47 | :src="item.carParkPanorama ? item.carParkPanorama : 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png'" /> | 47 | :src="item.carParkPanorama ? item.carParkPanorama : 'https://ijry.github.io/uview-plus/h5/assets/logo-8d54bbeb.png'" /> |
| 48 | </view> | 48 | </view> |
| 49 | <view class="company-list-item-main-right" | 49 | <view class="company-list-item-main-right" |
| 50 | - @click="handleDetailClick(item, item.legalRepresentativePhone, userAddress)"> | 50 | + @click="handleDetailClick(item, item.service_phone, userAddress)"> |
| 51 | <view class="company-list-item-main-right-name"> | 51 | <view class="company-list-item-main-right-name"> |
| 52 | {{ item.name }} | 52 | {{ item.name }} |
| 53 | </view> | 53 | </view> |
| 54 | <view class="company-list-item-main-right-score"> | 54 | <view class="company-list-item-main-right-score"> |
| 55 | <text class="company-list-item-main-right-text">评分:</text> | 55 | <text class="company-list-item-main-right-text">评分:</text> |
| 56 | <view v-if="item.score != 0" class="company-list-item-main-right-score-start"> | 56 | <view v-if="item.score != 0" class="company-list-item-main-right-score-start"> |
| 57 | - <u-icon v-for="todo in maxStar" :name="item.score > todo ? 'star-fill' : 'star'" :key="todo" | ||
| 58 | - color="#f9ae3d" size="28"></u-icon> | 57 | + <!-- <u-icon v-for="todo in maxStar" :name="item.score > todo ? 'star-fill' : 'star'" :key="todo" |
| 58 | + color="#f9ae3d" size="28"></u-icon> --> | ||
| 59 | + <u-rate activeColor="#f9ae3d" inactive-color="#f9ae3d" size="28" :modelValue="item.score" | ||
| 60 | + allowHalf readonly></u-rate> | ||
| 59 | </view> | 61 | </view> |
| 60 | <text v-if="item.score > 0" class="company-list-item-main-right-text" style="color: #fd5d00;">{{ | 62 | <text v-if="item.score > 0" class="company-list-item-main-right-text" style="color: #fd5d00;">{{ |
| 61 | item.score }}分</text> | 63 | item.score }}分</text> |
| 62 | <text v-else class="company-list-item-main-right-text" style="color: #fd5d00;">最近一月暂无评分</text> | 64 | <text v-else class="company-list-item-main-right-text" style="color: #fd5d00;">最近一月暂无评分</text> |
| 63 | </view> | 65 | </view> |
| 64 | <view class="company-list-item-main-right-price-number"> | 66 | <view class="company-list-item-main-right-price-number"> |
| 65 | - <view class="company-list-item-main-right-price">公司类型:{{ item.companyType == 0 ? "经营单位" : | ||
| 66 | - "运输公司" | ||
| 67 | - }} </view> | 67 | + <view class="company-list-item-main-right-price">报价:<text |
| 68 | + style="color: #fd5d00;">¥400起 </text></view> | ||
| 68 | <view class="company-list-item-main-right-number"> | 69 | <view class="company-list-item-main-right-number"> |
| 69 | 清运数:<text class="company-list-item-main-right-number-text">{{ item.cleanNumber }}</text> | 70 | 清运数:<text class="company-list-item-main-right-number-text">{{ item.cleanNumber }}</text> |
| 70 | </view> | 71 | </view> |
| @@ -76,12 +77,12 @@ | @@ -76,12 +77,12 @@ | ||
| 76 | </view> | 77 | </view> |
| 77 | <view class="company-list-item-bottom"> | 78 | <view class="company-list-item-bottom"> |
| 78 | <view class="company-list-item-bottom-contact-company"> | 79 | <view class="company-list-item-bottom-contact-company"> |
| 79 | - <u-button @click="handleContactClick(item.legalRepresentativePhone)" color="#a9e08f" size="normal" | 80 | + <u-button @click="handleContactClick(item.service_phone)" color="#a9e08f" size="normal" |
| 80 | type="success" :hairline="true" shape="circle" text="联系公司"></u-button> | 81 | type="success" :hairline="true" shape="circle" text="联系公司"></u-button> |
| 81 | </view> | 82 | </view> |
| 82 | <view class="company-list-item-bottom-button-clean"> | 83 | <view class="company-list-item-bottom-button-clean"> |
| 83 | - <u-button @click="handleCleanGarbage(item, item.legalRepresentativePhone, userAddress)" | ||
| 84 | - type="success" :hairline="true" size="normal" shape="circle" text="垃圾清运"></u-button> | 84 | + <u-button @click="handleCleanGarbage(item, item.service_phone, userAddress)" type="success" |
| 85 | + :hairline="true" size="normal" shape="circle" text="垃圾清运"></u-button> | ||
| 85 | </view> | 86 | </view> |
| 86 | </view> | 87 | </view> |
| 87 | </view> | 88 | </view> |
| @@ -281,7 +282,7 @@ const initData = () => { | @@ -281,7 +282,7 @@ const initData = () => { | ||
| 281 | } | 282 | } |
| 282 | const queryList = (pageNo, pageSize) => { | 283 | const queryList = (pageNo, pageSize) => { |
| 283 | // 查询公司信息 | 284 | // 查询公司信息 |
| 284 | - queryEnterpriseList({ companyType: 0, pageNum: pageNo, pageSize }).then(res => { | 285 | + queryEnterpriseList({ companyType: 1, pageNum: pageNo, pageSize }).then(res => { |
| 285 | paging.value.complete(res.data.data.list); | 286 | paging.value.complete(res.data.data.list); |
| 286 | }) | 287 | }) |
| 287 | } | 288 | } |
| @@ -510,6 +511,7 @@ const queryList = (pageNo, pageSize) => { | @@ -510,6 +511,7 @@ const queryList = (pageNo, pageSize) => { | ||
| 510 | } | 511 | } |
| 511 | 512 | ||
| 512 | .company-list-item-main-right { | 513 | .company-list-item-main-right { |
| 514 | + flex: auto; | ||
| 513 | display: flex; | 515 | display: flex; |
| 514 | flex-direction: column; | 516 | flex-direction: column; |
| 515 | flex-wrap: wrap; | 517 | flex-wrap: wrap; |
| @@ -543,14 +545,16 @@ const queryList = (pageNo, pageSize) => { | @@ -543,14 +545,16 @@ const queryList = (pageNo, pageSize) => { | ||
| 543 | 545 | ||
| 544 | .company-list-item-main-right-price-number { | 546 | .company-list-item-main-right-price-number { |
| 545 | display: flex; | 547 | display: flex; |
| 546 | - justify-content: space-around; | 548 | + justify-content: space-between; |
| 547 | align-items: center; | 549 | align-items: center; |
| 548 | 550 | ||
| 549 | .company-list-item-main-right-price {} | 551 | .company-list-item-main-right-price {} |
| 550 | 552 | ||
| 551 | .company-list-item-main-right-number { | 553 | .company-list-item-main-right-number { |
| 554 | + flex: auto; | ||
| 552 | font-size: small; | 555 | font-size: small; |
| 553 | 556 | ||
| 557 | + | ||
| 554 | .company-list-item-main-right-number-text { | 558 | .company-list-item-main-right-number-text { |
| 555 | color: $u-main-color; | 559 | color: $u-main-color; |
| 556 | } | 560 | } |
garbage-removal/src/pages/login/index.vue
garbage-removal/src/pages/order/detail/index.vue
| 1 | <template> | 1 | <template> |
| 2 | + <clashDispatch ref="clashDispatchRef" :valueKey="'licensePlateNumber'" :onconfirm="handleDispatchConfirm" | ||
| 3 | + :dataList="personnelList"> | ||
| 4 | + </clashDispatch> | ||
| 2 | <view class="order-detail-container" v-if="dataGram != null || dataGram != undefined"> | 5 | <view class="order-detail-container" v-if="dataGram != null || dataGram != undefined"> |
| 3 | <view class="order-detail-container-box"> | 6 | <view class="order-detail-container-box"> |
| 4 | <view class="order-detail-top"> | 7 | <view class="order-detail-top"> |
| @@ -46,12 +49,6 @@ | @@ -46,12 +49,6 @@ | ||
| 46 | </view> | 49 | </view> |
| 47 | </view> | 50 | </view> |
| 48 | <view class="order-detail-container-header-item"> | 51 | <view class="order-detail-container-header-item"> |
| 49 | - <text class="order-detail-container-header-title">车辆类型:</text> | ||
| 50 | - <view class="order-detail-container-header-content"> | ||
| 51 | - {{ dataGram.garOrderCarType }}({{ dataGram.garOrderCarNumber }}辆) | ||
| 52 | - </view> | ||
| 53 | - </view> | ||
| 54 | - <view class="order-detail-container-header-item"> | ||
| 55 | <text class="order-detail-container-header-title">垃圾类型:</text> | 52 | <text class="order-detail-container-header-title">垃圾类型:</text> |
| 56 | <view class="order-detail-container-header-content"> | 53 | <view class="order-detail-container-header-content"> |
| 57 | {{ dataGram.garOrderTrashType }} | 54 | {{ dataGram.garOrderTrashType }} |
| @@ -67,7 +64,23 @@ | @@ -67,7 +64,23 @@ | ||
| 67 | <view @click="handleQrCodeClick(orderId)" class="iconfont icon-erweima-xian"></view> | 64 | <view @click="handleQrCodeClick(orderId)" class="iconfont icon-erweima-xian"></view> |
| 68 | </view> | 65 | </view> |
| 69 | </view> | 66 | </view> |
| 70 | - | 67 | + </view> |
| 68 | + <!-- 车辆信息 --> | ||
| 69 | + <view class="order-detail-container-box-card"> | ||
| 70 | + <view class="order-detail-container-header-card-title"> | ||
| 71 | + <view class="order-detail-container-header-card-uicon"></view> | ||
| 72 | + 车辆信息 | ||
| 73 | + </view> | ||
| 74 | + <view class="order-detail-container-header-item" style="justify-content: space-between;" | ||
| 75 | + v-for="(item) in dataGram.garCarInfoList" :key="item.garId"> | ||
| 76 | + <text class="order-detail-container-header-title" style="color: #303133;">{{ item.garOrderCarType }} | ||
| 77 | + </text> | ||
| 78 | + <view class="order-detail-container-header-content"> | ||
| 79 | + <text class="order-detail-container-header-title"> | ||
| 80 | + {{ cleanStatus(dataGram.garOrderHandlerStatus) }} | ||
| 81 | + </text> | ||
| 82 | + </view> | ||
| 83 | + </view> | ||
| 71 | </view> | 84 | </view> |
| 72 | <!-- 派单记录 --> | 85 | <!-- 派单记录 --> |
| 73 | <view class="order-detail-container-box-card"> | 86 | <view class="order-detail-container-box-card"> |
| @@ -82,7 +95,7 @@ | @@ -82,7 +95,7 @@ | ||
| 82 | </view> | 95 | </view> |
| 83 | </view> --> | 96 | </view> --> |
| 84 | <view class="order-detail-container-header-item"> | 97 | <view class="order-detail-container-header-item"> |
| 85 | - <text class="order-detail-container-header-title">约定时间:</text> | 98 | + <text class="order-detail-container-header-title">预约时间:</text> |
| 86 | <view class="order-detail-container-header-content"> | 99 | <view class="order-detail-container-header-content"> |
| 87 | {{ dataGram.garOrderAgreementTime }} | 100 | {{ dataGram.garOrderAgreementTime }} |
| 88 | </view> | 101 | </view> |
| @@ -117,27 +130,27 @@ | @@ -117,27 +130,27 @@ | ||
| 117 | 处理信息 | 130 | 处理信息 |
| 118 | </view> | 131 | </view> |
| 119 | <view v-if="dataGram.garOrderHandlerId" style="width: 100%;"> | 132 | <view v-if="dataGram.garOrderHandlerId" style="width: 100%;"> |
| 120 | - <view class="order-detail-container-header-item"> | 133 | + <!-- <view class="order-detail-container-header-item"> |
| 121 | <text class="order-detail-container-header-title">负责人:</text> | 134 | <text class="order-detail-container-header-title">负责人:</text> |
| 122 | <view class="order-detail-container-header-content"> | 135 | <view class="order-detail-container-header-content"> |
| 123 | {{ dataGram.garOrderHandleName }} | 136 | {{ dataGram.garOrderHandleName }} |
| 124 | </view> | 137 | </view> |
| 125 | - </view> | 138 | + </view> --> |
| 126 | <view class="order-detail-container-header-item"> | 139 | <view class="order-detail-container-header-item"> |
| 127 | - <text class="order-detail-container-header-title">联系方式:</text> | 140 | + <text class="order-detail-container-header-title">服务电话:</text> |
| 128 | <view class="order-detail-container-header-content"> | 141 | <view class="order-detail-container-header-content"> |
| 129 | - {{ dataGram.garOrderHandleTel }} | 142 | + {{ dataGram.garOrderCompanyTel }} |
| 130 | </view> | 143 | </view> |
| 131 | </view> | 144 | </view> |
| 132 | <view class="order-detail-container-header-item"> | 145 | <view class="order-detail-container-header-item"> |
| 133 | - <text class="order-detail-container-header-title">装车照片:</text> | 146 | + <text class=" order-detail-container-header-title">装车照片:</text> |
| 134 | <view class="order-detail-container-header-content"> | 147 | <view class="order-detail-container-header-content"> |
| 135 | <u-upload width="180" height="130" :fileList="putOnImages" name="3" multiple :maxCount="20" | 148 | <u-upload width="180" height="130" :fileList="putOnImages" name="3" multiple :maxCount="20" |
| 136 | :previewFullImage="true" :isReadOnly="true"></u-upload> | 149 | :previewFullImage="true" :isReadOnly="true"></u-upload> |
| 137 | </view> | 150 | </view> |
| 138 | </view> | 151 | </view> |
| 139 | <view class="order-detail-container-header-item"> | 152 | <view class="order-detail-container-header-item"> |
| 140 | - <text class="order-detail-container-header-title">卸车照片:</text> | 153 | + <text class=" order-detail-container-header-title">卸车照片:</text> |
| 141 | <view class="order-detail-container-header-content"> | 154 | <view class="order-detail-container-header-content"> |
| 142 | <u-upload width="180" height="130" :fileList="putDownImages" name="3" multiple :maxCount="20" | 155 | <u-upload width="180" height="130" :fileList="putDownImages" name="3" multiple :maxCount="20" |
| 143 | :previewFullImage="true" :isReadOnly="true"></u-upload> | 156 | :previewFullImage="true" :isReadOnly="true"></u-upload> |
| @@ -150,38 +163,55 @@ | @@ -150,38 +163,55 @@ | ||
| 150 | </view> | 163 | </view> |
| 151 | </view> | 164 | </view> |
| 152 | <view class="space-box">{{ spaceStr }}</view> | 165 | <view class="space-box">{{ spaceStr }}</view> |
| 153 | - | ||
| 154 | </view> | 166 | </view> |
| 155 | <!-- 占位符 --> | 167 | <!-- 占位符 --> |
| 156 | <view class="order-detail-bottom"> | 168 | <view class="order-detail-bottom"> |
| 157 | <view class="order-detail-bottom-box"> | 169 | <view class="order-detail-bottom-box"> |
| 158 | <view class=" order-detail-bottom-left"> | 170 | <view class=" order-detail-bottom-left"> |
| 159 | - <u-button v-if="dataGram.garOrderHandlerStatus === 0 && userType == '司机'" @click="handleOderCancelClick()" | ||
| 160 | - shape="circle" color="#a9e08f" text="取消派单"></u-button> | 171 | + <u-button v-if="dataGram.garOrderHandlerStatus === 1 && dataGram.garCancelFlag === 0 && userType === '运输驾驶员'" |
| 172 | + @click="handleSubmitSuccess(orderId)" shape="circle" color="#a9e08f" text="完成派单"></u-button> | ||
| 173 | + <u-button v-if="dataGram.garOrderHandlerStatus === 0 && userType == '企业负责人' && dataGram.garCancelFlag === 0" | ||
| 174 | + @click="handleOderCancelClick()" shape="circle" color="#a9e08f" text="取消派单"></u-button> | ||
| 175 | + <u-button v-if="dataGram.garOrderHandlerStatus === 0 && userType == '运输驾驶员' && dataGram.garCancelFlag === 0" | ||
| 176 | + @click="handleOderCancelClick()" shape="circle" color="#a9e08f" text="取消派单"></u-button> | ||
| 177 | + <u-button v-if="dataGram.garOrderHandlerStatus === 1 && userType == '企业负责人'" | ||
| 178 | + @click="handleOrderDispatchClick(orderId)" shape="circle" color="#a9e08f" | ||
| 179 | + :text="dataGram.garOrderMatchFlag === 0 ? '派单下发' : '继续下发'"></u-button> | ||
| 161 | </view> | 180 | </view> |
| 162 | <view class="order-detail-bottom-right"> | 181 | <view class="order-detail-bottom-right"> |
| 163 | <u-button v-if="dataGram.garOrderHandlerStatus === 0 && userType == '居民用户' && dataGram.garCancelFlag === 0" | 182 | <u-button v-if="dataGram.garOrderHandlerStatus === 0 && userType == '居民用户' && dataGram.garCancelFlag === 0" |
| 164 | @click="handleOderCancelClick()" shape="circle" color="#a9e08f" text="取消派单"></u-button> | 183 | @click="handleOderCancelClick()" shape="circle" color="#a9e08f" text="取消派单"></u-button> |
| 184 | + <u-button @click="driverHandleOrder(orderId)" | ||
| 185 | + v-if="dataGram.garOrderHandlerStatus === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0 && userType === '运输驾驶员'" | ||
| 186 | + shape="circle" color="#a9e08f" text="处理派单"></u-button> | ||
| 165 | <u-button @click="handleOrder(orderId)" | 187 | <u-button @click="handleOrder(orderId)" |
| 166 | - v-if="dataGram.garOrderHandlerStatus === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0" | 188 | + v-if="dataGram.garOrderHandlerStatus === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0 && userType === '企业负责人'" |
| 167 | shape="circle" color="#a9e08f" text="处理派单"></u-button> | 189 | shape="circle" color="#a9e08f" text="处理派单"></u-button> |
| 168 | <u-button @click="handleUploadImage(orderId, 'putOnImages')" | 190 | <u-button @click="handleUploadImage(orderId, 'putOnImages')" |
| 169 | - v-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putOnImages.length === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0" | 191 | + v-if="dataGram.garOrderHandlerStatus === 1 && dataGram.garCancelFlag === 0 && userType === '运输驾驶员'" |
| 192 | + shape="circle" color="#a9e08f" text="上传图片"></u-button> | ||
| 193 | + <!-- <u-button @click="handleUploadImage(orderId, 'putOnImages')" | ||
| 194 | + v-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putOnImages.length === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0 && userType === '运输驾驶员'" | ||
| 170 | shape="circle" color="#a9e08f" text="装车照片"></u-button> | 195 | shape="circle" color="#a9e08f" text="装车照片"></u-button> |
| 171 | <u-button @click="handleUploadImage(orderId, 'putDownImages')" | 196 | <u-button @click="handleUploadImage(orderId, 'putDownImages')" |
| 172 | - v-else-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putDownImages.length === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0" | ||
| 173 | - shape="circle" color="#a9e08f" text="卸车照片"></u-button> | 197 | + v-else-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putDownImages.length === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0 && userType === '运输驾驶员'" |
| 198 | + shape="circle" color="#a9e08f" text="卸车照片"></u-button> --> | ||
| 199 | + <!-- <u-button @click="handleUploadImage(orderId, 'putDownImages')" | ||
| 200 | + v-else-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putDownImages.length === 0 && dataGram.handleFlag && dataGram.garCancelFlag === 0 && userType === '企业负责人'" | ||
| 201 | + shape="circle" color="#a9e08f" text="上传照片"></u-button> --> | ||
| 174 | <u-button @click="handleEvaluate(orderId, userType)" | 202 | <u-button @click="handleEvaluate(orderId, userType)" |
| 175 | v-if="dataGram.garEvaluateFlag === 0 && userType === '居民用户'" shape="circle" color="#a9e08f" | 203 | v-if="dataGram.garEvaluateFlag === 0 && userType === '居民用户'" shape="circle" color="#a9e08f" |
| 176 | text="去评价"></u-button> | 204 | text="去评价"></u-button> |
| 177 | <u-button @click="handleEvaluate(orderId, userType)" | 205 | <u-button @click="handleEvaluate(orderId, userType)" |
| 178 | - v-if="dataGram.garHandlerEvaluateFlag === 0 && userType === '司机'" shape="circle" color="#a9e08f" | 206 | + v-if="dataGram.garHandlerEvaluateFlag === 0 && userType === '企业负责人'" shape="circle" color="#a9e08f" |
| 179 | text="去评价"></u-button> | 207 | text="去评价"></u-button> |
| 180 | <u-button @click="handleEvaluateDetail(orderId, userType)" | 208 | <u-button @click="handleEvaluateDetail(orderId, userType)" |
| 181 | - v-if="dataGram.garHandlerEvaluateFlag === 1 && userType === '司机'" shape="circle" color="#a9e08f" | 209 | + v-if="dataGram.garHandlerEvaluateFlag === 1 && userType === '企业负责人'" shape="circle" color="#a9e08f" |
| 182 | text="查看评价"></u-button> | 210 | text="查看评价"></u-button> |
| 183 | - <u-button | ||
| 184 | - v-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putOnImages.length != 0 && dataGram.putDownImages.length != 0 && dataGram.garCancelFlag === 0" | 211 | + <u-button @click="handleEvaluateDetail(orderId, userType)" |
| 212 | + v-if="dataGram.garEvaluateFlag === 1 && userType === '居民用户'" shape="circle" color="#a9e08f" | ||
| 213 | + text="查看评价"></u-button> | ||
| 214 | + <u-button v-if="dataGram.garOrderHandlerStatus === 1 && dataGram.garCancelFlag === 0 && userType != '运输驾驶员'" | ||
| 185 | @click="handleSubmitSuccess(orderId)" shape="circle" color="#a9e08f" text="完成派单"></u-button> | 215 | @click="handleSubmitSuccess(orderId)" shape="circle" color="#a9e08f" text="完成派单"></u-button> |
| 186 | </view> | 216 | </view> |
| 187 | </view> | 217 | </view> |
| @@ -197,13 +227,16 @@ | @@ -197,13 +227,16 @@ | ||
| 197 | </template> | 227 | </template> |
| 198 | 228 | ||
| 199 | <script setup> | 229 | <script setup> |
| 200 | -import { queryOrderDetail, updateOrder } from "@/apis/order.js"; | 230 | +import { dispatchOrders, queryOrderDetail, queryOrderDispatch, updateOrder } from "@/apis/order.js"; |
| 201 | import { createQrCode } from '@/apis/qrcode.js'; | 231 | import { createQrCode } from '@/apis/qrcode.js'; |
| 202 | import uqrcode from '@/components/Sansnn-uQRCode_4.0.6/components/uqrcode/uqrcode.vue'; | 232 | import uqrcode from '@/components/Sansnn-uQRCode_4.0.6/components/uqrcode/uqrcode.vue'; |
| 233 | +import clashDispatch from '@/components/clash-dispatch/index.vue'; | ||
| 203 | import zStatic from '@/components/z-paging/js/z-paging-static'; | 234 | import zStatic from '@/components/z-paging/js/z-paging-static'; |
| 204 | import { useMainStore } from '@/stores/index.js'; | 235 | import { useMainStore } from '@/stores/index.js'; |
| 205 | -import { onLoad, onReady } from '@dcloudio/uni-app'; | ||
| 206 | -import { computed, nextTick, ref } from 'vue'; | 236 | +import { onLoad } from '@dcloudio/uni-app'; |
| 237 | +import { computed, ref } from 'vue'; | ||
| 238 | +const clashDispatchRef = ref() | ||
| 239 | +const personnelList = ref([]) | ||
| 207 | const store = useMainStore(); | 240 | const store = useMainStore(); |
| 208 | const userType = computed(() => store.userType) | 241 | const userType = computed(() => store.userType) |
| 209 | const dataGram = ref(); | 242 | const dataGram = ref(); |
| @@ -248,16 +281,8 @@ const createQrCodeLocal = (orderId) => { | @@ -248,16 +281,8 @@ const createQrCodeLocal = (orderId) => { | ||
| 248 | const protocol = window.location.protocol; | 281 | const protocol = window.location.protocol; |
| 249 | const localAddress = `${protocol}//${hostname}:${port}`; | 282 | const localAddress = `${protocol}//${hostname}:${port}`; |
| 250 | // const localAddress = `http://localhost:5173`; | 283 | // const localAddress = `http://localhost:5173`; |
| 251 | - qrCodeText.value = localAddress + "/pages/order/detail/index?orderId=" + orderId; | ||
| 252 | - console.log(qrCodeText.value); | ||
| 253 | - qrCodeRef.value.remake({ | ||
| 254 | - success: () => { | ||
| 255 | - console.log('生成成功'); | ||
| 256 | - }, | ||
| 257 | - fail: err => { | ||
| 258 | - console.log(err) | ||
| 259 | - } | ||
| 260 | - }); | 284 | + qrCodeText.value = localAddress + "/pages/order/guest/index?orderId=" + orderId; |
| 285 | + console.log(qrCodeRef.value); | ||
| 261 | } | 286 | } |
| 262 | // 获取二维码 | 287 | // 获取二维码 |
| 263 | const handleQrCodeClick = (orderId) => { | 288 | const handleQrCodeClick = (orderId) => { |
| @@ -286,6 +311,21 @@ const handleQrCodeClick = (orderId) => { | @@ -286,6 +311,21 @@ const handleQrCodeClick = (orderId) => { | ||
| 286 | // #endif | 311 | // #endif |
| 287 | } | 312 | } |
| 288 | 313 | ||
| 314 | +const handleOrderDispatchClick = (orderId) => { | ||
| 315 | + // 获取派单人员 | ||
| 316 | + queryOrderDispatch(orderId).then(res => { | ||
| 317 | + if (res.data.success) { | ||
| 318 | + personnelList.value = res.data.data | ||
| 319 | + clashDispatchRef.value.open(res.data.data) | ||
| 320 | + | ||
| 321 | + handleOrderDetail(orderId) | ||
| 322 | + } else { | ||
| 323 | + uni.$u.toast(res.data.message) | ||
| 324 | + } | ||
| 325 | + }) | ||
| 326 | +} | ||
| 327 | + | ||
| 328 | + | ||
| 289 | const handleClose = (e) => { | 329 | const handleClose = (e) => { |
| 290 | cancelShow.value = false | 330 | cancelShow.value = false |
| 291 | } | 331 | } |
| @@ -371,6 +411,8 @@ const handleSubmitSuccess = (orderId) => { | @@ -371,6 +411,8 @@ const handleSubmitSuccess = (orderId) => { | ||
| 371 | } | 411 | } |
| 372 | } | 412 | } |
| 373 | }); | 413 | }); |
| 414 | + // uni.$u.route(`pages/order/success/index?orderId=${orderId}`) | ||
| 415 | + | ||
| 374 | } | 416 | } |
| 375 | const handleEvaluate = (orderId, userType) => { | 417 | const handleEvaluate = (orderId, userType) => { |
| 376 | uni.$u.route(`pages/order/evaluate/index?orderId=${orderId}&userType=${userType}`) | 418 | uni.$u.route(`pages/order/evaluate/index?orderId=${orderId}&userType=${userType}`) |
| @@ -394,6 +436,24 @@ const handleOrder = (orderId) => { | @@ -394,6 +436,24 @@ const handleOrder = (orderId) => { | ||
| 394 | }) | 436 | }) |
| 395 | } | 437 | } |
| 396 | 438 | ||
| 439 | +// 接收派单 | ||
| 440 | +const driverHandleOrder = (orderId) => { | ||
| 441 | + updateOrder({ garOrderId: orderId, handleType: 0 }).then(res => { | ||
| 442 | + if (res.data.success) { | ||
| 443 | + if (res.data.data === "派单已经被别人接受啦") { | ||
| 444 | + uni.$u.toast(res.data.data) | ||
| 445 | + uni.$u.route({ | ||
| 446 | + type: "reLaunch", | ||
| 447 | + url: `pages/order/index`, | ||
| 448 | + }) | ||
| 449 | + } else { | ||
| 450 | + uni.$u.toast(res.data.data) | ||
| 451 | + handleOrderDetail(orderId) | ||
| 452 | + } | ||
| 453 | + } | ||
| 454 | + }) | ||
| 455 | +} | ||
| 456 | + | ||
| 397 | 457 | ||
| 398 | const currentStep = (step) => { | 458 | const currentStep = (step) => { |
| 399 | if (step > 2) { | 459 | if (step > 2) { |
| @@ -403,12 +463,65 @@ const currentStep = (step) => { | @@ -403,12 +463,65 @@ const currentStep = (step) => { | ||
| 403 | } | 463 | } |
| 404 | 464 | ||
| 405 | /** | 465 | /** |
| 466 | + * 清运状态 | ||
| 467 | + * @param {*} status | ||
| 468 | + */ | ||
| 469 | +const cleanStatus = (status) => { | ||
| 470 | + if (dataGram.garCancelFlag === 1) { | ||
| 471 | + return '取消清运'; | ||
| 472 | + } | ||
| 473 | + switch (status) { | ||
| 474 | + case 0: | ||
| 475 | + return '准备清运'; | ||
| 476 | + case 1: | ||
| 477 | + return '正在清运'; | ||
| 478 | + case 3: | ||
| 479 | + return '清运完成'; | ||
| 480 | + } | ||
| 481 | +} | ||
| 482 | + | ||
| 483 | +// /** | ||
| 484 | +// * 上传图片 | ||
| 485 | +// * @param {string} orderId | ||
| 486 | +// * @param {string} putType | ||
| 487 | +// */ | ||
| 488 | +// const handleUploadImage = (orderId, putType) => { | ||
| 489 | +// uni.$u.route(`pages/order/upload/index?orderId=${orderId}&putType=${putType}`) | ||
| 490 | +// } | ||
| 491 | + | ||
| 492 | +/** | ||
| 406 | * 上传图片 | 493 | * 上传图片 |
| 407 | * @param {string} orderId | 494 | * @param {string} orderId |
| 408 | * @param {string} putType | 495 | * @param {string} putType |
| 409 | */ | 496 | */ |
| 410 | const handleUploadImage = (orderId, putType) => { | 497 | const handleUploadImage = (orderId, putType) => { |
| 411 | - uni.$u.route(`pages/order/upload/index?orderId=${orderId}&putType=${putType}`) | 498 | + uni.$u.route(`pages/order/upload/index?orderId=${orderId}`) |
| 499 | +} | ||
| 500 | + | ||
| 501 | + | ||
| 502 | +const handleDispatchConfirm = (val) => { | ||
| 503 | + console.log(val); | ||
| 504 | + if (!val) { | ||
| 505 | + return | ||
| 506 | + } | ||
| 507 | + let data = { | ||
| 508 | + garOrderId: orderId.value, | ||
| 509 | + dispatchList: [] | ||
| 510 | + } | ||
| 511 | + for (const key in val) { | ||
| 512 | + data.dispatchList.push({ | ||
| 513 | + ...val[key] | ||
| 514 | + }); | ||
| 515 | + } | ||
| 516 | + console.log(data); | ||
| 517 | + dispatchOrders(data).then(res => { | ||
| 518 | + if (res.data.success) { | ||
| 519 | + uni.$u.toast(res.data.msg) | ||
| 520 | + } else { | ||
| 521 | + uni.$u.toast("派单下发失败,请重试") | ||
| 522 | + } | ||
| 523 | + clashDispatchRef.value.close() | ||
| 524 | + }) | ||
| 412 | } | 525 | } |
| 413 | 526 | ||
| 414 | /** | 527 | /** |
| @@ -418,14 +531,21 @@ onLoad((options) => { | @@ -418,14 +531,21 @@ onLoad((options) => { | ||
| 418 | orderId.value = options.orderId | 531 | orderId.value = options.orderId |
| 419 | handleOrderDetail(orderId.value) | 532 | handleOrderDetail(orderId.value) |
| 420 | }) | 533 | }) |
| 421 | -onReady(() => { | ||
| 422 | - // 生成二维码 | ||
| 423 | - nextTick(() => { | ||
| 424 | - | ||
| 425 | - }) | ||
| 426 | -}) | ||
| 427 | - | ||
| 428 | 534 | ||
| 535 | +// onShow(() => { | ||
| 536 | +// try { | ||
| 537 | +// let pages = getCurrentPages(); | ||
| 538 | +// let currPage = pages[pages.length - 1]; | ||
| 539 | +// if (currPage.__data__.isRefresh) { | ||
| 540 | +// // 重新获取数据 | ||
| 541 | +// this.getData(true)//获取列表数据 | ||
| 542 | +// // 每一次需要清除,否则会参数会缓存 | ||
| 543 | +// currPage.__data__.isRefresh = false | ||
| 544 | +// } | ||
| 545 | +// } catch (error) { | ||
| 546 | +// console.log(error); | ||
| 547 | +// } | ||
| 548 | +// }) | ||
| 429 | </script> | 549 | </script> |
| 430 | 550 | ||
| 431 | <style lang="scss" scoped> | 551 | <style lang="scss" scoped> |
garbage-removal/src/pages/order/evaluate-info/index.vue
| @@ -24,7 +24,7 @@ | @@ -24,7 +24,7 @@ | ||
| 24 | <view class="user-info-title"> | 24 | <view class="user-info-title"> |
| 25 | <u-avatar :src="pic" size="70"></u-avatar> | 25 | <u-avatar :src="pic" size="70"></u-avatar> |
| 26 | <view class="user-name"> | 26 | <view class="user-name"> |
| 27 | - 司机 | 27 | + 企业负责人 |
| 28 | </view> | 28 | </view> |
| 29 | </view> | 29 | </view> |
| 30 | <view v-if="evaluateManager" class="evaluate-content"> | 30 | <view v-if="evaluateManager" class="evaluate-content"> |
| @@ -55,7 +55,7 @@ const maxStar = ref([]) | @@ -55,7 +55,7 @@ const maxStar = ref([]) | ||
| 55 | 55 | ||
| 56 | // 用户评价对象 | 56 | // 用户评价对象 |
| 57 | const evaluateUser = ref() | 57 | const evaluateUser = ref() |
| 58 | -// 司机评价 | 58 | +// 企业负责人评价 |
| 59 | const evaluateManager = ref() | 59 | const evaluateManager = ref() |
| 60 | onLoad((options) => { | 60 | onLoad((options) => { |
| 61 | for (let index = 0; index < maxScore; index++) { | 61 | for (let index = 0; index < maxScore; index++) { |
garbage-removal/src/pages/order/success/index.vue
0 → 100644
| 1 | +<template> | ||
| 2 | + <view> | ||
| 3 | + 完成界面{{ orderId }} | ||
| 4 | + </view> | ||
| 5 | +</template> | ||
| 6 | + | ||
| 7 | +<script setup> | ||
| 8 | +import { | ||
| 9 | + onLoad | ||
| 10 | +} from '@dcloudio/uni-app'; | ||
| 11 | +import { ref } from 'vue'; | ||
| 12 | +const orderId = ref() | ||
| 13 | + | ||
| 14 | + | ||
| 15 | + | ||
| 16 | +onLoad((options) => { | ||
| 17 | + orderId.value = options.orderId | ||
| 18 | +}) | ||
| 19 | +</script> | ||
| 20 | + | ||
| 21 | +<style lang="scss" scoped> | ||
| 22 | +</style> |
garbage-removal/src/pages/order/swiper-list-item/index.vue
| @@ -10,16 +10,21 @@ | @@ -10,16 +10,21 @@ | ||
| 10 | <view class="store">{{ item.garOrderCompanyName }}</view> | 10 | <view class="store">{{ item.garOrderCompanyName }}</view> |
| 11 | <u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon> | 11 | <u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon> |
| 12 | </view> | 12 | </view> |
| 13 | - <view v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0" class="right">待清运 </view> | ||
| 14 | - <view v-if="item.garCancelFlag === 1" class="right">已取消 </view> | ||
| 15 | - <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0" class="right">清运中 </view> | 13 | + <view style="display: flex;align-items: center;"> |
| 14 | + <text v-if="item.garOrderHandlerStatus != 3 && item.garOrderStatus === 3 && userType === '运输驾驶员'" | ||
| 15 | + style="font-size: small;color: #f56c6c;">派单已经完成了。</text> | ||
| 16 | + <view v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0" class="right">待清运 </view> | ||
| 17 | + <view v-if="item.garCancelFlag === 1" class="right">已取消 </view> | ||
| 18 | + <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0" class="right">清运中 </view> | ||
| 19 | + <view v-if="item.garOrderHandlerStatus === 3 && userType === '运输驾驶员'" class="right">已完成 </view> | ||
| 20 | + </view> | ||
| 16 | <view v-if="item.garEvaluateFlag === 0 && userType === '居民用户'" class="right">待评价 | 21 | <view v-if="item.garEvaluateFlag === 0 && userType === '居民用户'" class="right">待评价 |
| 17 | </view> | 22 | </view> |
| 18 | - <view v-if="item.garHandlerEvaluateFlag === 0 && userType === '司机'" class="right">待评价 | 23 | + <view v-if="item.garHandlerEvaluateFlag === 0 && userType === '企业负责人'" class="right">待评价 |
| 19 | </view> | 24 | </view> |
| 20 | <view v-if="item.garEvaluateFlag === 1 && userType === '居民用户'" class="right">已评价 | 25 | <view v-if="item.garEvaluateFlag === 1 && userType === '居民用户'" class="right">已评价 |
| 21 | </view> | 26 | </view> |
| 22 | - <view v-if="item.garHandlerEvaluateFlag === 1 && userType === '司机'" class="right">已评价 | 27 | + <view v-if="item.garHandlerEvaluateFlag === 1 && userType === '企业负责人'" class="right">已评价 |
| 23 | </view> | 28 | </view> |
| 24 | </view> | 29 | </view> |
| 25 | <view class="item" @click="handleClick(item.garOrderId)"> | 30 | <view class="item" @click="handleClick(item.garOrderId)"> |
| @@ -49,7 +54,7 @@ | @@ -49,7 +54,7 @@ | ||
| 49 | </view> | 54 | </view> |
| 50 | <!-- 公司对用户评价 --> | 55 | <!-- 公司对用户评价 --> |
| 51 | <view class="bottom" | 56 | <view class="bottom" |
| 52 | - v-if="item.garHandlerEvaluateFlag === 0 && item.garOrderHandlerStatus === 3 && userType === '司机'"> | 57 | + v-if="item.garHandlerEvaluateFlag === 0 && item.garOrderHandlerStatus === 3 && userType === '企业负责人'"> |
| 53 | <view class="more"> | 58 | <view class="more"> |
| 54 | <!-- <u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon> --> | 59 | <!-- <u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon> --> |
| 55 | </view> | 60 | </view> |
garbage-removal/src/pages/order/upload/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <view class="upload-image-box"> | 2 | <view class="upload-image-box"> |
| 3 | <view class="upload-image-box-choose"> | 3 | <view class="upload-image-box-choose"> |
| 4 | - <text class="upload-image-box-choose-txt">请上传{{ putType }}图片类型:</text> | 4 | + <text class="upload-image-box-choose-txt">请选着上传图片类型:</text> |
| 5 | <view class="upload-image-box-choose-type"> | 5 | <view class="upload-image-box-choose-type"> |
| 6 | - | 6 | + <u-radio-group v-model="putType" @change="groupChange" placement="row"> |
| 7 | + <u-radio activeColor="#19be6b" :customStyle="{ marginBottom: '8px' }" size="28" labelSize="28" | ||
| 8 | + v-for="(item, index) in chooseList" :key="index" :label="item.name" :name="item.name" @change="radioChange"> | ||
| 9 | + </u-radio> | ||
| 10 | + </u-radio-group> | ||
| 7 | </view> | 11 | </view> |
| 8 | </view> | 12 | </view> |
| 9 | <view class="upload-image-box-bottom"> | 13 | <view class="upload-image-box-bottom"> |
| @@ -27,10 +31,11 @@ | @@ -27,10 +31,11 @@ | ||
| 27 | import { uploadFilePromise } from '@/apis/common.js'; | 31 | import { uploadFilePromise } from '@/apis/common.js'; |
| 28 | import { uploadImageUrlByType } from '@/apis/order.js'; | 32 | import { uploadImageUrlByType } from '@/apis/order.js'; |
| 29 | import { onLoad } from '@dcloudio/uni-app'; | 33 | import { onLoad } from '@dcloudio/uni-app'; |
| 30 | -import { ref } from 'vue'; | ||
| 31 | -const putType = ref("") | 34 | +import { reactive, ref } from 'vue'; |
| 35 | +const putType = ref("装车图片") | ||
| 32 | const orderId = ref(); | 36 | const orderId = ref(); |
| 33 | const fileList = ref([]) | 37 | const fileList = ref([]) |
| 38 | +const chooseList = reactive([{ name: "装车图片" }, { name: "卸车图片" }]) | ||
| 34 | // 删除图片 | 39 | // 删除图片 |
| 35 | const deletePic = (event) => { | 40 | const deletePic = (event) => { |
| 36 | fileList.value.splice(event.index, 1); | 41 | fileList.value.splice(event.index, 1); |
| @@ -71,15 +76,20 @@ const handleSubmit = (id, type) => { | @@ -71,15 +76,20 @@ const handleSubmit = (id, type) => { | ||
| 71 | } | 76 | } |
| 72 | let params = { | 77 | let params = { |
| 73 | garOrderId: id, | 78 | garOrderId: id, |
| 74 | - type: type == "装车照片" ? 1 : 2, | 79 | + type: type == "装车图片" ? 1 : 2, |
| 75 | imageUrls: fileList.value.map(item => item.url) | 80 | imageUrls: fileList.value.map(item => item.url) |
| 76 | } | 81 | } |
| 77 | uploadImageUrlByType(params).then(res => { | 82 | uploadImageUrlByType(params).then(res => { |
| 78 | if (res.data.success) { | 83 | if (res.data.success) { |
| 79 | uni.$u.toast("图片上传完毕!"); | 84 | uni.$u.toast("图片上传完毕!"); |
| 80 | - uni.$u.route({ | ||
| 81 | - type: "navigateBack", | ||
| 82 | - url: "pages/order/detail/index" | 85 | + let pages = getCurrentPages(); |
| 86 | + console.log(pages); | ||
| 87 | + uni.navigateBack({ | ||
| 88 | + delta: 1, | ||
| 89 | + success() { | ||
| 90 | + //pages.length-1 即最后一个为当前页,所以取当前页面的上一级 | ||
| 91 | + pages[pages.length - 2].$vm.handleOrderDetail(id); // init 是上一个页面的方法名称 | ||
| 92 | + } | ||
| 83 | }) | 93 | }) |
| 84 | } | 94 | } |
| 85 | }) | 95 | }) |
| @@ -97,7 +107,8 @@ const validateImage = () => { | @@ -97,7 +107,8 @@ const validateImage = () => { | ||
| 97 | 107 | ||
| 98 | onLoad((options) => { | 108 | onLoad((options) => { |
| 99 | orderId.value = options.orderId; | 109 | orderId.value = options.orderId; |
| 100 | - putType.value = options.putType === "putOnImages" ? "装车照片" : "卸车照片"; | 110 | + // putType.value = options.putType === "putOnImages" ? "装车图片" : "卸车图片"; |
| 111 | + | ||
| 101 | }) | 112 | }) |
| 102 | </script> | 113 | </script> |
| 103 | 114 |
garbage-removal/src/pages/wode/choose/index.vue
| @@ -2,21 +2,34 @@ | @@ -2,21 +2,34 @@ | ||
| 2 | <view class="wrap"> | 2 | <view class="wrap"> |
| 3 | <u-radio-group v-model="userType" placement="row" @change="groupChange"> | 3 | <u-radio-group v-model="userType" placement="row" @change="groupChange"> |
| 4 | <view class="choose-type" v-for="(item, index) in typeList"> | 4 | <view class="choose-type" v-for="(item, index) in typeList"> |
| 5 | - <u-radio :customStyle="{ marginBottom: '8px' }" size="28" labelSize="28" :key="index" :label="item.name" | ||
| 6 | - :name="item.name" @change="radioChange"> | 5 | + <u-radio size="28" labelSize="28" :key="index" :label="item.name" :name="item.name" @change="radioChange"> |
| 7 | </u-radio> | 6 | </u-radio> |
| 8 | - <view class="manager-info" v-if="item.name === '司机' && unitInfo.companyFlag"> | ||
| 9 | - <view class="manager-info-parent-company-name"> | ||
| 10 | - <text style="margin-right: 20rpx;">经营公司:</text> | ||
| 11 | - <text>{{ unitInfo.parentCompanyName }}</text> | ||
| 12 | - </view> | ||
| 13 | - <view class="manager-info-transport-company-name"> | ||
| 14 | - <text style="margin-right: 20rpx;">运输公司:</text> | ||
| 15 | - <text>{{ unitInfo.transportCompanyName }}</text> | ||
| 16 | - </view> | ||
| 17 | - </view> | ||
| 18 | </view> | 7 | </view> |
| 19 | </u-radio-group> | 8 | </u-radio-group> |
| 9 | + <!-- 角色信息匹配 --> | ||
| 10 | + <view class="rule-label-info-box"> | ||
| 11 | + <view class="manager-info" v-if="userType === '居民用户'"> | ||
| 12 | + <view class="manager-info-parent-company-name"> | ||
| 13 | + 派单前请输先完善地址信息~ | ||
| 14 | + </view> | ||
| 15 | + </view> | ||
| 16 | + <view class="manager-info" v-if="userType === '运输驾驶员'"> | ||
| 17 | + <view class="manager-info-parent-company-name"> | ||
| 18 | + 长沙有限运输运输公司-运输驾驶员-李伟 | ||
| 19 | + </view> | ||
| 20 | + <view class="manager-info-parent-company-name"> | ||
| 21 | + 未匹配到该手机号绑定的运输公司! | ||
| 22 | + </view> | ||
| 23 | + </view> | ||
| 24 | + <view class="manager-info" v-if="userType === '企业负责人'"> | ||
| 25 | + <view class="manager-info-parent-company-name"> | ||
| 26 | + 长沙有限运输运输公司公司服务账号! | ||
| 27 | + </view> | ||
| 28 | + <view class="manager-info-parent-company-name"> | ||
| 29 | + 未匹配到该手机号绑定运输公司公司服务账号! | ||
| 30 | + </view> | ||
| 31 | + </view> | ||
| 32 | + </view> | ||
| 20 | <view class="choose-button"> | 33 | <view class="choose-button"> |
| 21 | <u-button shape="circle" color="#a9e08f" @click="submit(userType)">确定</u-button> | 34 | <u-button shape="circle" color="#a9e08f" @click="submit(userType)">确定</u-button> |
| 22 | </view> | 35 | </view> |
| @@ -31,12 +44,13 @@ import { onLoad } from "@dcloudio/uni-app"; | @@ -31,12 +44,13 @@ import { onLoad } from "@dcloudio/uni-app"; | ||
| 31 | import { ref } from 'vue'; | 44 | import { ref } from 'vue'; |
| 32 | const store = useMainStore(); | 45 | const store = useMainStore(); |
| 33 | const userType = ref("居民用户") | 46 | const userType = ref("居民用户") |
| 34 | -const typeList = ref([{ name: "居民用户" }, { name: "司机" }]) | 47 | +const typeList = ref([{ name: "居民用户" }, { name: "运输驾驶员" }, { name: "企业负责人" }]) |
| 35 | const unitInfo = ref({}) | 48 | const unitInfo = ref({}) |
| 36 | const radioChange = (e) => { | 49 | const radioChange = (e) => { |
| 37 | } | 50 | } |
| 38 | const groupChange = (e) => { | 51 | const groupChange = (e) => { |
| 39 | } | 52 | } |
| 53 | + | ||
| 40 | const submit = (userType) => { | 54 | const submit = (userType) => { |
| 41 | setRequestToken(store.tempToken) | 55 | setRequestToken(store.tempToken) |
| 42 | updateUserInfo({ garUserType: userType }).then(res => { | 56 | updateUserInfo({ garUserType: userType }).then(res => { |
| @@ -56,10 +70,8 @@ const submit = (userType) => { | @@ -56,10 +70,8 @@ const submit = (userType) => { | ||
| 56 | } | 70 | } |
| 57 | onLoad((options) => { | 71 | onLoad((options) => { |
| 58 | unitInfo.value = options | 72 | unitInfo.value = options |
| 59 | - unitInfo.value.companyFlag = JSON.parse(options.companyFlag) | ||
| 60 | - if (unitInfo.value.companyFlag) { | ||
| 61 | - userType.value = "司机" | ||
| 62 | - } | 73 | + userType.value = options.userType |
| 74 | + // submit(options.userType) | ||
| 63 | }) | 75 | }) |
| 64 | </script> | 76 | </script> |
| 65 | 77 | ||
| @@ -72,36 +84,39 @@ onLoad((options) => { | @@ -72,36 +84,39 @@ onLoad((options) => { | ||
| 72 | background-color: $u-info-light; | 84 | background-color: $u-info-light; |
| 73 | 85 | ||
| 74 | .choose-type { | 86 | .choose-type { |
| 75 | - width: 100%; | 87 | + // width: 100%; |
| 76 | box-sizing: border-box; | 88 | box-sizing: border-box; |
| 77 | - padding: 30rpx; | 89 | + padding: 20rpx; |
| 78 | background-color: #ffffff; | 90 | background-color: #ffffff; |
| 79 | border-radius: 20rpx; | 91 | border-radius: 20rpx; |
| 92 | + margin-right: 20rpx; | ||
| 93 | + display: flex; | ||
| 94 | + align-items: center; | ||
| 95 | + justify-content: center; | ||
| 80 | 96 | ||
| 81 | - &:first-child { | 97 | + &:last-child { |
| 82 | margin-right: 20rpx; | 98 | margin-right: 20rpx; |
| 83 | } | 99 | } |
| 84 | 100 | ||
| 101 | + | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + .rule-label-info-box { | ||
| 105 | + box-sizing: border-box; | ||
| 106 | + margin-top: 20rpx; | ||
| 107 | + | ||
| 85 | .manager-info { | 108 | .manager-info { |
| 86 | font-size: 25rpx; | 109 | font-size: 25rpx; |
| 87 | color: $u-main-color; | 110 | color: $u-main-color; |
| 88 | box-sizing: border-box; | 111 | box-sizing: border-box; |
| 89 | 112 | ||
| 90 | .manager-info-parent-company-name { | 113 | .manager-info-parent-company-name { |
| 91 | - | ||
| 92 | - text { | ||
| 93 | - color: $u-info; | ||
| 94 | - } | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - .manager-info-transport-company-name { | ||
| 98 | - text { | ||
| 99 | - color: $u-info; | ||
| 100 | - } | 114 | + color: $u-info; |
| 101 | } | 115 | } |
| 102 | } | 116 | } |
| 103 | } | 117 | } |
| 104 | 118 | ||
| 119 | + | ||
| 105 | .choose-button { | 120 | .choose-button { |
| 106 | position: relative; | 121 | position: relative; |
| 107 | width: 100%; | 122 | width: 100%; |
garbage-removal/src/pages/wode/index.vue
| @@ -6,13 +6,15 @@ | @@ -6,13 +6,15 @@ | ||
| 6 | </view> | 6 | </view> |
| 7 | <view class="u-flex-1"> | 7 | <view class="u-flex-1"> |
| 8 | <view class="u-font-18 u-p-b-20">{{ userInfo.userType }}</view> | 8 | <view class="u-font-18 u-p-b-20">{{ userInfo.userType }}</view> |
| 9 | - <view class="manager-info" v-if="userInfo.companyFlag"> | ||
| 10 | - <view class="manager-info-parent-company-name"> | ||
| 11 | - <text style="margin-right: 20rpx;">经营公司:</text> | ||
| 12 | - <text>{{ userInfo.parentCompanyName }}</text> | 9 | + <view class="manager-info" v-if="userInfo.userType === '运输驾驶员'"> |
| 10 | + <view class="manager-info-transport-company-name"> | ||
| 11 | + <text style="margin-right: 20rpx;">所属运输公司:</text> | ||
| 12 | + <text>{{ userInfo.transportCompanyName }}</text> | ||
| 13 | </view> | 13 | </view> |
| 14 | + </view> | ||
| 15 | + <view class="manager-info" v-if="userInfo.userType === '企业负责人'"> | ||
| 14 | <view class="manager-info-transport-company-name"> | 16 | <view class="manager-info-transport-company-name"> |
| 15 | - <text style="margin-right: 20rpx;">运输公司:</text> | 17 | + <text style="margin-right: 20rpx;">所属运输公司:</text> |
| 16 | <text>{{ userInfo.transportCompanyName }}</text> | 18 | <text>{{ userInfo.transportCompanyName }}</text> |
| 17 | </view> | 19 | </view> |
| 18 | </view> | 20 | </view> |
garbage-removal/src/utils/request/request.js
| @@ -148,4 +148,7 @@ const handleGet = (config) => { | @@ -148,4 +148,7 @@ const handleGet = (config) => { | ||
| 148 | } | 148 | } |
| 149 | config.url += strUrl; | 149 | config.url += strUrl; |
| 150 | config.params = ""; | 150 | config.params = ""; |
| 151 | + if (config.url.startsWith("/order/webDetail/")) { | ||
| 152 | + config.headers["Authorization"] = ""; | ||
| 153 | + } | ||
| 151 | } | 154 | } |
garbage-removal/src/uview-plus/components/u-action-sheet/u-action-sheet.vue
| @@ -39,7 +39,7 @@ | @@ -39,7 +39,7 @@ | ||
| 39 | <!-- #endif --> | 39 | <!-- #endif --> |
| 40 | <view v-if="item.name == '其他'" class="u-action-sheet__item-wrap__item" :hover-stay-time="150"> | 40 | <view v-if="item.name == '其他'" class="u-action-sheet__item-wrap__item" :hover-stay-time="150"> |
| 41 | <view class="parent-box"> | 41 | <view class="parent-box"> |
| 42 | - <u-collapse> | 42 | + <u-collapse @open="handleOpenMethod" @close="handleCloseMethod"> |
| 43 | <u-collapse-item @selectHandler="selectHandler" :index="index" :name="item.name" ref="childRef" | 43 | <u-collapse-item @selectHandler="selectHandler" :index="index" :name="item.name" ref="childRef" |
| 44 | title="其他" name="其他"> | 44 | title="其他" name="其他"> |
| 45 | <view class="u-collapse-content" style="width: 97vw;text-align: left;"> | 45 | <view class="u-collapse-content" style="width: 97vw;text-align: left;"> |
| @@ -151,6 +151,14 @@ export default { | @@ -151,6 +151,14 @@ export default { | ||
| 151 | }, | 151 | }, |
| 152 | }, | 152 | }, |
| 153 | methods: { | 153 | methods: { |
| 154 | + handleOpenMethod(e) { | ||
| 155 | + // console.log("开启", e); | ||
| 156 | + this.accordion = true; | ||
| 157 | + }, | ||
| 158 | + handleCloseMethod(e) { | ||
| 159 | + // console.log("关闭", e); | ||
| 160 | + this.accordion = false; | ||
| 161 | + }, | ||
| 154 | closeHandler() { | 162 | closeHandler() { |
| 155 | // 允许点击遮罩关闭时,才发出close事件 | 163 | // 允许点击遮罩关闭时,才发出close事件 |
| 156 | if (this.closeOnClickOverlay) { | 164 | if (this.closeOnClickOverlay) { |
| @@ -162,6 +170,7 @@ export default { | @@ -162,6 +170,7 @@ export default { | ||
| 162 | this.$emit('actionSheetClose') | 170 | this.$emit('actionSheetClose') |
| 163 | }, | 171 | }, |
| 164 | selectHandler(index, name) { | 172 | selectHandler(index, name) { |
| 173 | + console.log(index, name); | ||
| 165 | if (name != "其他") { | 174 | if (name != "其他") { |
| 166 | if (this.accordion) { | 175 | if (this.accordion) { |
| 167 | this.$refs.childRef[0].clickHandler("抽屉"); | 176 | this.$refs.childRef[0].clickHandler("抽屉"); |
| @@ -169,9 +178,6 @@ export default { | @@ -169,9 +178,6 @@ export default { | ||
| 169 | } | 178 | } |
| 170 | this.otherReason = '' | 179 | this.otherReason = '' |
| 171 | } | 180 | } |
| 172 | - if (name == "其他") { | ||
| 173 | - this.accordion = true; | ||
| 174 | - } | ||
| 175 | this.currentSelect = index; | 181 | this.currentSelect = index; |
| 176 | const item = this.actions[index] | 182 | const item = this.actions[index] |
| 177 | if (item && !item.disabled && !item.loading) { | 183 | if (item && !item.disabled && !item.loading) { |
garbage-removal/src/uview-plus/components/u-checkbox-group/u-checkbox-group.vue
| @@ -97,6 +97,7 @@ export default { | @@ -97,6 +97,7 @@ export default { | ||
| 97 | values.push(child.name) | 97 | values.push(child.name) |
| 98 | } | 98 | } |
| 99 | }) | 99 | }) |
| 100 | + console.log(values); | ||
| 100 | // 发出事件 | 101 | // 发出事件 |
| 101 | this.$emit('change', values) | 102 | this.$emit('change', values) |
| 102 | // 修改通过v-model绑定的值 | 103 | // 修改通过v-model绑定的值 |
garbage-removal/src/uview-plus/components/u-number-box/u-number-box.vue
| 1 | <template> | 1 | <template> |
| 2 | <view class="u-number-box"> | 2 | <view class="u-number-box"> |
| 3 | - <view | ||
| 4 | - class="u-number-box__slot" | ||
| 5 | - @tap.stop="clickHandler('minus')" | ||
| 6 | - @touchstart="onTouchStart('minus')" | ||
| 7 | - @touchend.stop="clearTimeout" | ||
| 8 | - v-if="showMinus && $slots.minus" | ||
| 9 | - > | 3 | + <view class="u-number-box__slot" @tap.stop="clickHandler('minus')" @touchstart="onTouchStart('minus')" |
| 4 | + @touchend.stop="clearTimeout" v-if="showMinus && $slots.minus"> | ||
| 10 | <slot name="minus" /> | 5 | <slot name="minus" /> |
| 11 | </view> | 6 | </view> |
| 12 | - <view | ||
| 13 | - v-else-if="showMinus" | ||
| 14 | - class="u-number-box__minus" | ||
| 15 | - @tap.stop="clickHandler('minus')" | ||
| 16 | - @touchstart="onTouchStart('minus')" | ||
| 17 | - @touchend.stop="clearTimeout" | ||
| 18 | - hover-class="u-number-box__minus--hover" | ||
| 19 | - hover-stay-time="150" | ||
| 20 | - :class="{ 'u-number-box__minus--disabled': isDisabled('minus') }" | ||
| 21 | - :style="[buttonStyle('minus')]" | ||
| 22 | - > | ||
| 23 | - <u-icon | ||
| 24 | - name="minus" | ||
| 25 | - :color="isDisabled('minus') ? '#c8c9cc' : '#323233'" | ||
| 26 | - size="15" | ||
| 27 | - bold | ||
| 28 | - :customStyle="iconStyle" | ||
| 29 | - ></u-icon> | 7 | + <view v-else-if="showMinus" class="u-number-box__minus" @tap.stop="clickHandler('minus')" |
| 8 | + @touchstart="onTouchStart('minus')" @touchend.stop="clearTimeout" hover-class="u-number-box__minus--hover" | ||
| 9 | + hover-stay-time="150" :class="{ 'u-number-box__minus--disabled': isDisabled('minus') }" | ||
| 10 | + :style="[buttonStyle('minus')]"> | ||
| 11 | + <u-icon name="minus" :color="isDisabled('minus') ? '#c8c9cc' : '#323233'" size="15" bold | ||
| 12 | + :customStyle="iconStyle"></u-icon> | ||
| 30 | </view> | 13 | </view> |
| 31 | 14 | ||
| 32 | <slot name="input"> | 15 | <slot name="input"> |
| 33 | - <input | ||
| 34 | - :disabled="disabledInput || disabled" | ||
| 35 | - :cursor-spacing="getCursorSpacing" | ||
| 36 | - :class="{ 'u-number-box__input--disabled': disabled || disabledInput }" | ||
| 37 | - v-model="currentValue" | ||
| 38 | - class="u-number-box__input" | ||
| 39 | - @blur="onBlur" | ||
| 40 | - @focus="onFocus" | ||
| 41 | - @input="onInput" | ||
| 42 | - type="number" | ||
| 43 | - :style="[inputStyle]" | ||
| 44 | - /> | 16 | + <input :disabled="disabledInput || disabled" :cursor-spacing="getCursorSpacing" |
| 17 | + :class="{ 'u-number-box__input--disabled': disabled || disabledInput }" v-model="currentValue" | ||
| 18 | + class="u-number-box__input" @blur="onBlur" @focus="onFocus" @input="onInput" type="number" | ||
| 19 | + :style="[inputStyle]" /> | ||
| 45 | </slot> | 20 | </slot> |
| 46 | - <view | ||
| 47 | - class="u-number-box__slot" | ||
| 48 | - @tap.stop="clickHandler('plus')" | ||
| 49 | - @touchstart="onTouchStart('plus')" | ||
| 50 | - @touchend.stop="clearTimeout" | ||
| 51 | - v-if="showPlus && $slots.plus" | ||
| 52 | - > | 21 | + <view class="u-number-box__slot" @tap.stop="clickHandler('plus')" @touchstart="onTouchStart('plus')" |
| 22 | + @touchend.stop="clearTimeout" v-if="showPlus && $slots.plus"> | ||
| 53 | <slot name="plus" /> | 23 | <slot name="plus" /> |
| 54 | </view> | 24 | </view> |
| 55 | - <view | ||
| 56 | - v-else-if="showPlus" | ||
| 57 | - class="u-number-box__plus" | ||
| 58 | - @tap.stop="clickHandler('plus')" | ||
| 59 | - @touchstart="onTouchStart('plus')" | ||
| 60 | - @touchend.stop="clearTimeout" | ||
| 61 | - hover-class="u-number-box__plus--hover" | ||
| 62 | - hover-stay-time="150" | ||
| 63 | - :class="{ 'u-number-box__minus--disabled': isDisabled('plus') }" | ||
| 64 | - :style="[buttonStyle('plus')]" | ||
| 65 | - > | ||
| 66 | - <u-icon | ||
| 67 | - name="plus" | ||
| 68 | - :color="isDisabled('plus') ? '#c8c9cc' : '#323233'" | ||
| 69 | - size="15" | ||
| 70 | - bold | ||
| 71 | - :customStyle="iconStyle" | ||
| 72 | - ></u-icon> | 25 | + <view v-else-if="showPlus" class="u-number-box__plus" @tap.stop="clickHandler('plus')" |
| 26 | + @touchstart="onTouchStart('plus')" @touchend.stop="clearTimeout" hover-class="u-number-box__plus--hover" | ||
| 27 | + hover-stay-time="150" :class="{ 'u-number-box__minus--disabled': isDisabled('plus') }" | ||
| 28 | + :style="[buttonStyle('plus')]"> | ||
| 29 | + <u-icon name="plus" :color="isDisabled('plus') ? '#c8c9cc' : '#323233'" size="15" bold | ||
| 30 | + :customStyle="iconStyle"></u-icon> | ||
| 73 | </view> | 31 | </view> |
| 74 | </view> | 32 | </view> |
| 75 | </template> | 33 | </template> |
| 76 | 34 | ||
| 77 | <script> | 35 | <script> |
| 78 | - import props from './props.js'; | ||
| 79 | - import mpMixin from '../../libs/mixin/mpMixin.js'; | ||
| 80 | - import mixin from '../../libs/mixin/mixin.js'; | ||
| 81 | - /** | ||
| 82 | - * numberBox 步进器 | ||
| 83 | - * @description 该组件一般用于商城购物选择物品数量的场景。 | ||
| 84 | - * @tutorial https://uviewui.com/components/numberBox.html | ||
| 85 | - * @property {String | Number} name 步进器标识符,在change回调返回 | ||
| 86 | - * @property {String | Number} value 用于双向绑定的值,初始化时设置设为默认min值(最小值) (默认 0 ) | ||
| 87 | - * @property {String | Number} min 最小值 (默认 1 ) | ||
| 88 | - * @property {String | Number} max 最大值 (默认 Number.MAX_SAFE_INTEGER ) | ||
| 89 | - * @property {String | Number} step 加减的步长,可为小数 (默认 1 ) | ||
| 90 | - * @property {Boolean} integer 是否只允许输入整数 (默认 false ) | ||
| 91 | - * @property {Boolean} disabled 是否禁用,包括输入框,加减按钮 (默认 false ) | ||
| 92 | - * @property {Boolean} disabledInput 是否禁用输入框 (默认 false ) | ||
| 93 | - * @property {Boolean} asyncChange 是否开启异步变更,开启后需要手动控制输入值 (默认 false ) | ||
| 94 | - * @property {String | Number} inputWidth 输入框宽度,单位为px (默认 35 ) | ||
| 95 | - * @property {Boolean} showMinus 是否显示减少按钮 (默认 true ) | ||
| 96 | - * @property {Boolean} showPlus 是否显示增加按钮 (默认 true ) | ||
| 97 | - * @property {String | Number} decimalLength 显示的小数位数 | ||
| 98 | - * @property {Boolean} longPress 是否开启长按加减手势 (默认 true ) | ||
| 99 | - * @property {String} color 输入框文字和加减按钮图标的颜色 (默认 '#323233' ) | ||
| 100 | - * @property {String | Number} buttonSize 按钮大小,宽高等于此值,单位px,输入框高度和此值保持一致 (默认 30 ) | ||
| 101 | - * @property {String} bgColor 输入框和按钮的背景颜色 (默认 '#EBECEE' ) | ||
| 102 | - * @property {String | Number} cursorSpacing 指定光标于键盘的距离,避免键盘遮挡输入框,单位px (默认 100 ) | ||
| 103 | - * @property {Boolean} disablePlus 是否禁用增加按钮 (默认 false ) | ||
| 104 | - * @property {Boolean} disableMinus 是否禁用减少按钮 (默认 false ) | ||
| 105 | - * @property {Object | String} iconStyle 加减按钮图标的样式 | ||
| 106 | - * | ||
| 107 | - * @event {Function} onFocus 输入框活动焦点 | ||
| 108 | - * @event {Function} onBlur 输入框失去焦点 | ||
| 109 | - * @event {Function} onInput 输入框值发生变化 | ||
| 110 | - * @event {Function} onChange | ||
| 111 | - * @example <u-number-box v-model="value" @change="valChange"></u-number-box> | ||
| 112 | - */ | ||
| 113 | - export default { | ||
| 114 | - name: 'u-number-box', | ||
| 115 | - mixins: [mpMixin, mixin, props], | ||
| 116 | - data() { | ||
| 117 | - return { | ||
| 118 | - // 输入框实际操作的值 | ||
| 119 | - currentValue: '', | ||
| 120 | - // 定时器 | ||
| 121 | - longPressTimer: null | ||
| 122 | - } | 36 | +import mixin from '../../libs/mixin/mixin.js'; |
| 37 | +import mpMixin from '../../libs/mixin/mpMixin.js'; | ||
| 38 | +import props from './props.js'; | ||
| 39 | +/** | ||
| 40 | + * numberBox 步进器 | ||
| 41 | + * @description 该组件一般用于商城购物选择物品数量的场景。 | ||
| 42 | + * @tutorial https://uviewui.com/components/numberBox.html | ||
| 43 | + * @property {String | Number} name 步进器标识符,在change回调返回 | ||
| 44 | + * @property {String | Number} value 用于双向绑定的值,初始化时设置设为默认min值(最小值) (默认 0 ) | ||
| 45 | + * @property {String | Number} min 最小值 (默认 1 ) | ||
| 46 | + * @property {String | Number} max 最大值 (默认 Number.MAX_SAFE_INTEGER ) | ||
| 47 | + * @property {String | Number} step 加减的步长,可为小数 (默认 1 ) | ||
| 48 | + * @property {Boolean} integer 是否只允许输入整数 (默认 false ) | ||
| 49 | + * @property {Boolean} disabled 是否禁用,包括输入框,加减按钮 (默认 false ) | ||
| 50 | + * @property {Boolean} disabledInput 是否禁用输入框 (默认 false ) | ||
| 51 | + * @property {Boolean} asyncChange 是否开启异步变更,开启后需要手动控制输入值 (默认 false ) | ||
| 52 | + * @property {String | Number} inputWidth 输入框宽度,单位为px (默认 35 ) | ||
| 53 | + * @property {Boolean} showMinus 是否显示减少按钮 (默认 true ) | ||
| 54 | + * @property {Boolean} showPlus 是否显示增加按钮 (默认 true ) | ||
| 55 | + * @property {String | Number} decimalLength 显示的小数位数 | ||
| 56 | + * @property {Boolean} longPress 是否开启长按加减手势 (默认 true ) | ||
| 57 | + * @property {String} color 输入框文字和加减按钮图标的颜色 (默认 '#323233' ) | ||
| 58 | + * @property {String | Number} buttonSize 按钮大小,宽高等于此值,单位px,输入框高度和此值保持一致 (默认 30 ) | ||
| 59 | + * @property {String} bgColor 输入框和按钮的背景颜色 (默认 '#EBECEE' ) | ||
| 60 | + * @property {String | Number} cursorSpacing 指定光标于键盘的距离,避免键盘遮挡输入框,单位px (默认 100 ) | ||
| 61 | + * @property {Boolean} disablePlus 是否禁用增加按钮 (默认 false ) | ||
| 62 | + * @property {Boolean} disableMinus 是否禁用减少按钮 (默认 false ) | ||
| 63 | + * @property {Object | String} iconStyle 加减按钮图标的样式 | ||
| 64 | + * | ||
| 65 | + * @event {Function} onFocus 输入框活动焦点 | ||
| 66 | + * @event {Function} onBlur 输入框失去焦点 | ||
| 67 | + * @event {Function} onInput 输入框值发生变化 | ||
| 68 | + * @event {Function} onChange | ||
| 69 | + * @example <u-number-box v-model="value" @change="valChange"></u-number-box> | ||
| 70 | + */ | ||
| 71 | +export default { | ||
| 72 | + name: 'u-number-box', | ||
| 73 | + mixins: [mpMixin, mixin, props], | ||
| 74 | + data() { | ||
| 75 | + return { | ||
| 76 | + // 输入框实际操作的值 | ||
| 77 | + currentValue: '', | ||
| 78 | + // 定时器 | ||
| 79 | + longPressTimer: null | ||
| 80 | + } | ||
| 81 | + }, | ||
| 82 | + watch: { | ||
| 83 | + // 多个值之间,只要一个值发生变化,都要重新检查check()函数 | ||
| 84 | + watchChange(n) { | ||
| 85 | + this.check() | ||
| 123 | }, | 86 | }, |
| 124 | - watch: { | ||
| 125 | - // 多个值之间,只要一个值发生变化,都要重新检查check()函数 | ||
| 126 | - watchChange(n) { | ||
| 127 | - this.check() | ||
| 128 | - }, | ||
| 129 | - // #ifdef VUE2 | ||
| 130 | - // 监听v-mode的变化,重新初始化内部的值 | ||
| 131 | - value(n) { | ||
| 132 | - if (n !== this.currentValue) { | ||
| 133 | - this.currentValue = this.format(this.value) | ||
| 134 | - } | ||
| 135 | - }, | ||
| 136 | - // #endif | ||
| 137 | - // #ifdef VUE3 | ||
| 138 | - // 监听v-mode的变化,重新初始化内部的值 | ||
| 139 | - modelValue(n) { | ||
| 140 | - if (n !== this.currentValue) { | ||
| 141 | - this.currentValue = this.format(this.modelValue) | ||
| 142 | - } | 87 | + // #ifdef VUE2 |
| 88 | + // 监听v-mode的变化,重新初始化内部的值 | ||
| 89 | + value(n) { | ||
| 90 | + if (n !== this.currentValue) { | ||
| 91 | + this.currentValue = this.format(this.value) | ||
| 143 | } | 92 | } |
| 144 | - // #endif | ||
| 145 | }, | 93 | }, |
| 146 | - computed: { | ||
| 147 | - getCursorSpacing() { | ||
| 148 | - // 判断传入的单位,如果为px单位,需要转成px | ||
| 149 | - return uni.$u.getPx(this.cursorSpacing) | ||
| 150 | - }, | ||
| 151 | - // 按钮的样式 | ||
| 152 | - buttonStyle() { | ||
| 153 | - return (type) => { | ||
| 154 | - const style = { | ||
| 155 | - backgroundColor: this.bgColor, | ||
| 156 | - height: uni.$u.addUnit(this.buttonSize), | ||
| 157 | - color: this.color | ||
| 158 | - } | ||
| 159 | - if (this.isDisabled(type)) { | ||
| 160 | - style.backgroundColor = '#f7f8fa' | ||
| 161 | - } | ||
| 162 | - return style | 94 | + // #endif |
| 95 | + // 监听v-mode的变化,重新初始化内部的值 | ||
| 96 | + | ||
| 97 | + // #ifdef VUE3 | ||
| 98 | + // modelValue(n) { | ||
| 99 | + // console.log("n", n); | ||
| 100 | + // console.log("this.currentValue", this.currentValue); | ||
| 101 | + // if (n !== this.currentValue) { | ||
| 102 | + // this.currentValue = this.format(this.modelValue) | ||
| 103 | + // } | ||
| 104 | + // }, | ||
| 105 | + modelValue: { | ||
| 106 | + handler: function (newV, oldV) { | ||
| 107 | + if (newV !== this.currentValue) { | ||
| 108 | + this.currentValue = this.format(this.modelValue) | ||
| 163 | } | 109 | } |
| 164 | }, | 110 | }, |
| 165 | - // 输入框的样式 | ||
| 166 | - inputStyle() { | ||
| 167 | - const disabled = this.disabled || this.disabledInput | 111 | + immediate: true |
| 112 | + } | ||
| 113 | + // #endif | ||
| 114 | + }, | ||
| 115 | + computed: { | ||
| 116 | + getCursorSpacing() { | ||
| 117 | + // 判断传入的单位,如果为px单位,需要转成px | ||
| 118 | + return uni.$u.getPx(this.cursorSpacing) | ||
| 119 | + }, | ||
| 120 | + // 按钮的样式 | ||
| 121 | + buttonStyle() { | ||
| 122 | + return (type) => { | ||
| 168 | const style = { | 123 | const style = { |
| 169 | - color: this.color, | ||
| 170 | backgroundColor: this.bgColor, | 124 | backgroundColor: this.bgColor, |
| 171 | height: uni.$u.addUnit(this.buttonSize), | 125 | height: uni.$u.addUnit(this.buttonSize), |
| 172 | - width: uni.$u.addUnit(this.inputWidth) | 126 | + color: this.color |
| 127 | + } | ||
| 128 | + if (this.isDisabled(type)) { | ||
| 129 | + style.backgroundColor = '#f7f8fa' | ||
| 173 | } | 130 | } |
| 174 | return style | 131 | return style |
| 175 | - }, | ||
| 176 | - // 用于监听多个值发生变化 | ||
| 177 | - watchChange() { | ||
| 178 | - return [this.integer, this.decimalLength, this.min, this.max] | ||
| 179 | - }, | ||
| 180 | - isDisabled() { | ||
| 181 | - return (type) => { | ||
| 182 | - if (type === 'plus') { | ||
| 183 | - // 在点击增加按钮情况下,判断整体的disabled,是否单独禁用增加按钮,以及当前值是否大于最大的允许值 | ||
| 184 | - return ( | ||
| 185 | - this.disabled || | ||
| 186 | - this.disablePlus || | ||
| 187 | - this.currentValue >= this.max | ||
| 188 | - ) | ||
| 189 | - } | ||
| 190 | - // 点击减少按钮同理 | 132 | + } |
| 133 | + }, | ||
| 134 | + // 输入框的样式 | ||
| 135 | + inputStyle() { | ||
| 136 | + const disabled = this.disabled || this.disabledInput | ||
| 137 | + const style = { | ||
| 138 | + color: this.color, | ||
| 139 | + backgroundColor: this.bgColor, | ||
| 140 | + height: uni.$u.addUnit(this.buttonSize), | ||
| 141 | + width: uni.$u.addUnit(this.inputWidth) | ||
| 142 | + } | ||
| 143 | + return style | ||
| 144 | + }, | ||
| 145 | + // 用于监听多个值发生变化 | ||
| 146 | + watchChange() { | ||
| 147 | + return [this.integer, this.decimalLength, this.min, this.max] | ||
| 148 | + }, | ||
| 149 | + isDisabled() { | ||
| 150 | + return (type) => { | ||
| 151 | + if (type === 'plus') { | ||
| 152 | + // 在点击增加按钮情况下,判断整体的disabled,是否单独禁用增加按钮,以及当前值是否大于最大的允许值 | ||
| 191 | return ( | 153 | return ( |
| 192 | this.disabled || | 154 | this.disabled || |
| 193 | - this.disableMinus || | ||
| 194 | - this.currentValue <= this.min | 155 | + this.disablePlus || |
| 156 | + this.currentValue >= this.max | ||
| 195 | ) | 157 | ) |
| 196 | } | 158 | } |
| 197 | - }, | 159 | + // 点击减少按钮同理 |
| 160 | + return ( | ||
| 161 | + this.disabled || | ||
| 162 | + this.disableMinus || | ||
| 163 | + this.currentValue <= this.min | ||
| 164 | + ) | ||
| 165 | + } | ||
| 198 | }, | 166 | }, |
| 199 | - mounted() { | ||
| 200 | - this.init() | 167 | + }, |
| 168 | + mounted() { | ||
| 169 | + this.init() | ||
| 170 | + }, | ||
| 171 | + // #ifdef VUE3 | ||
| 172 | + emits: ['update:modelValue', 'focus', 'blur', 'overlimit', 'change', 'plus', 'minus'], | ||
| 173 | + // #endif | ||
| 174 | + methods: { | ||
| 175 | + init() { | ||
| 176 | + // #ifdef VUE3 | ||
| 177 | + this.currentValue = this.format(this.modelValue) | ||
| 178 | + // #endif | ||
| 179 | + // #ifdef VUE2 | ||
| 180 | + this.currentValue = this.format(this.value) | ||
| 181 | + // #endif | ||
| 201 | }, | 182 | }, |
| 202 | - // #ifdef VUE3 | ||
| 203 | - emits: ['update:modelValue', 'focus', 'blur', 'overlimit', 'change', 'plus', 'minus'], | ||
| 204 | - // #endif | ||
| 205 | - methods: { | ||
| 206 | - init() { | ||
| 207 | - // #ifdef VUE3 | ||
| 208 | - this.currentValue = this.format(this.modelValue) | ||
| 209 | - // #endif | ||
| 210 | - // #ifdef VUE2 | ||
| 211 | - this.currentValue = this.format(this.value) | ||
| 212 | - // #endif | ||
| 213 | - }, | ||
| 214 | - // 格式化整理数据,限制范围 | ||
| 215 | - format(value) { | ||
| 216 | - value = this.filter(value) | ||
| 217 | - // 如果为空字符串,那么设置为0,同时将值转为Number类型 | ||
| 218 | - value = value === '' ? 0 : +value | ||
| 219 | - // 对比最大最小值,取在min和max之间的值 | ||
| 220 | - value = Math.max(Math.min(this.max, value), this.min) | ||
| 221 | - // 如果设定了最大的小数位数,使用toFixed去进行格式化 | ||
| 222 | - if (this.decimalLength !== null) { | ||
| 223 | - value = value.toFixed(this.decimalLength) | ||
| 224 | - } | ||
| 225 | - return value | ||
| 226 | - }, | ||
| 227 | - // 过滤非法的字符 | ||
| 228 | - filter(value) { | ||
| 229 | - // 只允许0-9之间的数字,"."为小数点,"-"为负数时候使用 | ||
| 230 | - value = String(value).replace(/[^0-9.-]/g, '') | ||
| 231 | - // 如果只允许输入整数,则过滤掉小数点后的部分 | ||
| 232 | - if (this.integer && value.indexOf('.') !== -1) { | ||
| 233 | - value = value.split('.')[0] | ||
| 234 | - } | ||
| 235 | - return value; | ||
| 236 | - }, | ||
| 237 | - check() { | ||
| 238 | - // 格式化了之后,如果前后的值不相等,那么设置为格式化后的值 | ||
| 239 | - const val = this.format(this.currentValue); | ||
| 240 | - if (val !== this.currentValue) { | ||
| 241 | - this.currentValue = val | ||
| 242 | - } | ||
| 243 | - }, | ||
| 244 | - // 判断是否出于禁止操作状态 | ||
| 245 | - // isDisabled(type) { | ||
| 246 | - // if (type === 'plus') { | ||
| 247 | - // // 在点击增加按钮情况下,判断整体的disabled,是否单独禁用增加按钮,以及当前值是否大于最大的允许值 | ||
| 248 | - // return ( | ||
| 249 | - // this.disabled || | ||
| 250 | - // this.disablePlus || | ||
| 251 | - // this.currentValue >= this.max | ||
| 252 | - // ) | ||
| 253 | - // } | ||
| 254 | - // // 点击减少按钮同理 | ||
| 255 | - // return ( | ||
| 256 | - // this.disabled || | ||
| 257 | - // this.disableMinus || | ||
| 258 | - // this.currentValue <= this.min | ||
| 259 | - // ) | ||
| 260 | - // }, | ||
| 261 | - // 输入框活动焦点 | ||
| 262 | - onFocus(event) { | ||
| 263 | - this.$emit('focus', { | ||
| 264 | - ...event.detail, | ||
| 265 | - name: this.name, | 183 | + // 格式化整理数据,限制范围 |
| 184 | + format(value) { | ||
| 185 | + value = this.filter(value) | ||
| 186 | + // 如果为空字符串,那么设置为0,同时将值转为Number类型 | ||
| 187 | + value = value === '' ? 0 : +value | ||
| 188 | + // 对比最大最小值,取在min和max之间的值 | ||
| 189 | + value = Math.max(Math.min(this.max, value), this.min) | ||
| 190 | + // 如果设定了最大的小数位数,使用toFixed去进行格式化 | ||
| 191 | + if (this.decimalLength !== null) { | ||
| 192 | + value = value.toFixed(this.decimalLength) | ||
| 193 | + } | ||
| 194 | + return value | ||
| 195 | + }, | ||
| 196 | + // 过滤非法的字符 | ||
| 197 | + filter(value) { | ||
| 198 | + // 只允许0-9之间的数字,"."为小数点,"-"为负数时候使用 | ||
| 199 | + value = String(value).replace(/[^0-9.-]/g, '') | ||
| 200 | + // 如果只允许输入整数,则过滤掉小数点后的部分 | ||
| 201 | + if (this.integer && value.indexOf('.') !== -1) { | ||
| 202 | + value = value.split('.')[0] | ||
| 203 | + } | ||
| 204 | + return value; | ||
| 205 | + }, | ||
| 206 | + check() { | ||
| 207 | + // 格式化了之后,如果前后的值不相等,那么设置为格式化后的值 | ||
| 208 | + const val = this.format(this.currentValue); | ||
| 209 | + if (val !== this.currentValue) { | ||
| 210 | + this.currentValue = val | ||
| 211 | + } | ||
| 212 | + }, | ||
| 213 | + // 判断是否出于禁止操作状态 | ||
| 214 | + // isDisabled(type) { | ||
| 215 | + // if (type === 'plus') { | ||
| 216 | + // // 在点击增加按钮情况下,判断整体的disabled,是否单独禁用增加按钮,以及当前值是否大于最大的允许值 | ||
| 217 | + // return ( | ||
| 218 | + // this.disabled || | ||
| 219 | + // this.disablePlus || | ||
| 220 | + // this.currentValue >= this.max | ||
| 221 | + // ) | ||
| 222 | + // } | ||
| 223 | + // // 点击减少按钮同理 | ||
| 224 | + // return ( | ||
| 225 | + // this.disabled || | ||
| 226 | + // this.disableMinus || | ||
| 227 | + // this.currentValue <= this.min | ||
| 228 | + // ) | ||
| 229 | + // }, | ||
| 230 | + // 输入框活动焦点 | ||
| 231 | + onFocus(event) { | ||
| 232 | + this.$emit('focus', { | ||
| 233 | + ...event.detail, | ||
| 234 | + name: this.name, | ||
| 235 | + }) | ||
| 236 | + }, | ||
| 237 | + // 输入框失去焦点 | ||
| 238 | + onBlur(event) { | ||
| 239 | + // 对输入值进行格式化 | ||
| 240 | + const value = this.format(event.detail.value) | ||
| 241 | + // 发出blur事件 | ||
| 242 | + this.$emit( | ||
| 243 | + 'blur', { | ||
| 244 | + ...event.detail, | ||
| 245 | + name: this.name, | ||
| 246 | + } | ||
| 247 | + ) | ||
| 248 | + }, | ||
| 249 | + // 输入框值发生变化 | ||
| 250 | + onInput(e) { | ||
| 251 | + const { | ||
| 252 | + value = '' | ||
| 253 | + } = e.detail || {} | ||
| 254 | + // 为空返回 | ||
| 255 | + if (value === '') return | ||
| 256 | + let formatted = this.filter(value) | ||
| 257 | + // 最大允许的小数长度 | ||
| 258 | + if (this.decimalLength !== null && formatted.indexOf('.') !== -1) { | ||
| 259 | + const pair = formatted.split('.'); | ||
| 260 | + formatted = `${pair[0]}.${pair[1].slice(0, this.decimalLength)}` | ||
| 261 | + } | ||
| 262 | + formatted = this.format(formatted) | ||
| 263 | + this.emitChange(formatted); | ||
| 264 | + }, | ||
| 265 | + // 发出change事件 | ||
| 266 | + emitChange(value) { | ||
| 267 | + // 如果开启了异步变更值,则不修改内部的值,需要用户手动在外部通过v-model变更 | ||
| 268 | + if (!this.asyncChange) { | ||
| 269 | + this.$nextTick(() => { | ||
| 270 | + // #ifdef VUE3 | ||
| 271 | + this.$emit('update:modelValue', value) | ||
| 272 | + // #endif | ||
| 273 | + // #ifdef VUE2 | ||
| 274 | + this.$emit('input', value) | ||
| 275 | + // #endif | ||
| 276 | + this.currentValue = value | ||
| 277 | + this.$forceUpdate() | ||
| 266 | }) | 278 | }) |
| 267 | - }, | ||
| 268 | - // 输入框失去焦点 | ||
| 269 | - onBlur(event) { | ||
| 270 | - // 对输入值进行格式化 | ||
| 271 | - const value = this.format(event.detail.value) | ||
| 272 | - // 发出blur事件 | ||
| 273 | - this.$emit( | ||
| 274 | - 'blur',{ | ||
| 275 | - ...event.detail, | ||
| 276 | - name: this.name, | ||
| 277 | - } | ||
| 278 | - ) | ||
| 279 | - }, | ||
| 280 | - // 输入框值发生变化 | ||
| 281 | - onInput(e) { | ||
| 282 | - const { | ||
| 283 | - value = '' | ||
| 284 | - } = e.detail || {} | ||
| 285 | - // 为空返回 | ||
| 286 | - if (value === '') return | ||
| 287 | - let formatted = this.filter(value) | ||
| 288 | - // 最大允许的小数长度 | ||
| 289 | - if (this.decimalLength !== null && formatted.indexOf('.') !== -1) { | ||
| 290 | - const pair = formatted.split('.'); | ||
| 291 | - formatted = `${pair[0]}.${pair[1].slice(0, this.decimalLength)}` | ||
| 292 | - } | ||
| 293 | - formatted = this.format(formatted) | ||
| 294 | - this.emitChange(formatted); | ||
| 295 | - }, | ||
| 296 | - // 发出change事件 | ||
| 297 | - emitChange(value) { | ||
| 298 | - // 如果开启了异步变更值,则不修改内部的值,需要用户手动在外部通过v-model变更 | ||
| 299 | - if (!this.asyncChange) { | ||
| 300 | - this.$nextTick(() => { | ||
| 301 | - // #ifdef VUE3 | ||
| 302 | - this.$emit('update:modelValue', value) | ||
| 303 | - // #endif | ||
| 304 | - // #ifdef VUE2 | ||
| 305 | - this.$emit('input', value) | ||
| 306 | - // #endif | ||
| 307 | - this.currentValue = value | ||
| 308 | - this.$forceUpdate() | ||
| 309 | - }) | ||
| 310 | - } | ||
| 311 | - this.$emit('change', { | ||
| 312 | - value, | ||
| 313 | - name: this.name, | ||
| 314 | - }); | ||
| 315 | - }, | ||
| 316 | - onChange() { | ||
| 317 | - const { | ||
| 318 | - type | ||
| 319 | - } = this | ||
| 320 | - if (this.isDisabled(type)) { | ||
| 321 | - return this.$emit('overlimit', type) | ||
| 322 | - } | ||
| 323 | - const diff = type === 'minus' ? -this.step : +this.step | ||
| 324 | - const value = this.format(this.add(+this.currentValue, diff)) | ||
| 325 | - this.emitChange(value) | ||
| 326 | - this.$emit(type) | ||
| 327 | - }, | ||
| 328 | - // 对值扩大后进行四舍五入,再除以扩大因子,避免出现浮点数操作的精度问题 | ||
| 329 | - add(num1, num2) { | ||
| 330 | - const cardinal = Math.pow(10, 10); | ||
| 331 | - return Math.round((num1 + num2) * cardinal) / cardinal | ||
| 332 | - }, | ||
| 333 | - // 点击加减按钮 | ||
| 334 | - clickHandler(type) { | ||
| 335 | - this.type = type | ||
| 336 | - this.onChange() | ||
| 337 | - }, | ||
| 338 | - longPressStep() { | ||
| 339 | - // 每隔一段时间,重新调用longPressStep方法,实现长按加减 | ||
| 340 | - this.clearTimeout() | ||
| 341 | - this.longPressTimer = setTimeout(() => { | ||
| 342 | - this.onChange() | ||
| 343 | - this.longPressStep() | ||
| 344 | - }, 250); | ||
| 345 | - }, | ||
| 346 | - onTouchStart(type) { | ||
| 347 | - if (!this.longPress) return | ||
| 348 | - this.clearTimeout() | ||
| 349 | - this.type = type | ||
| 350 | - // 一定时间后,默认达到长按状态 | ||
| 351 | - this.longPressTimer = setTimeout(() => { | ||
| 352 | - this.onChange() | ||
| 353 | - this.longPressStep() | ||
| 354 | - }, 600) | ||
| 355 | - }, | ||
| 356 | - // 触摸结束,清除定时器,停止长按加减 | ||
| 357 | - onTouchEnd() { | ||
| 358 | - if (!this.longPress) return | ||
| 359 | - this.clearTimeout() | ||
| 360 | - }, | ||
| 361 | - // 清除定时器 | ||
| 362 | - clearTimeout() { | ||
| 363 | - clearTimeout(this.longPressTimer) | ||
| 364 | - this.longPressTimer = null | ||
| 365 | } | 279 | } |
| 280 | + this.$emit('change', { | ||
| 281 | + value, | ||
| 282 | + name: this.name, | ||
| 283 | + }); | ||
| 284 | + }, | ||
| 285 | + onChange() { | ||
| 286 | + const { | ||
| 287 | + type | ||
| 288 | + } = this | ||
| 289 | + if (this.isDisabled(type)) { | ||
| 290 | + return this.$emit('overlimit', type) | ||
| 291 | + } | ||
| 292 | + const diff = type === 'minus' ? -this.step : +this.step | ||
| 293 | + const value = this.format(this.add(+this.currentValue, diff)) | ||
| 294 | + this.emitChange(value) | ||
| 295 | + this.$emit(type) | ||
| 296 | + }, | ||
| 297 | + // 对值扩大后进行四舍五入,再除以扩大因子,避免出现浮点数操作的精度问题 | ||
| 298 | + add(num1, num2) { | ||
| 299 | + const cardinal = Math.pow(10, 10); | ||
| 300 | + return Math.round((num1 + num2) * cardinal) / cardinal | ||
| 301 | + }, | ||
| 302 | + // 点击加减按钮 | ||
| 303 | + clickHandler(type) { | ||
| 304 | + this.type = type | ||
| 305 | + this.onChange() | ||
| 306 | + }, | ||
| 307 | + longPressStep() { | ||
| 308 | + // 每隔一段时间,重新调用longPressStep方法,实现长按加减 | ||
| 309 | + this.clearTimeout() | ||
| 310 | + this.longPressTimer = setTimeout(() => { | ||
| 311 | + this.onChange() | ||
| 312 | + this.longPressStep() | ||
| 313 | + }, 250); | ||
| 314 | + }, | ||
| 315 | + onTouchStart(type) { | ||
| 316 | + if (!this.longPress) return | ||
| 317 | + this.clearTimeout() | ||
| 318 | + this.type = type | ||
| 319 | + // 一定时间后,默认达到长按状态 | ||
| 320 | + this.longPressTimer = setTimeout(() => { | ||
| 321 | + this.onChange() | ||
| 322 | + this.longPressStep() | ||
| 323 | + }, 600) | ||
| 324 | + }, | ||
| 325 | + // 触摸结束,清除定时器,停止长按加减 | ||
| 326 | + onTouchEnd() { | ||
| 327 | + if (!this.longPress) return | ||
| 328 | + this.clearTimeout() | ||
| 329 | + }, | ||
| 330 | + // 清除定时器 | ||
| 331 | + clearTimeout() { | ||
| 332 | + clearTimeout(this.longPressTimer) | ||
| 333 | + this.longPressTimer = null | ||
| 366 | } | 334 | } |
| 367 | } | 335 | } |
| 336 | +} | ||
| 368 | </script> | 337 | </script> |
| 369 | 338 | ||
| 370 | <style lang="scss" scoped> | 339 | <style lang="scss" scoped> |
| 371 | - @import '../../libs/css/components.scss'; | ||
| 372 | - | ||
| 373 | - $u-numberBox-hover-bgColor: #E6E6E6 !default; | ||
| 374 | - $u-numberBox-disabled-color: #c8c9cc !default; | ||
| 375 | - $u-numberBox-disabled-bgColor: #f7f8fa !default; | ||
| 376 | - $u-numberBox-plus-radius: 4px !default; | ||
| 377 | - $u-numberBox-minus-radius: 4px !default; | ||
| 378 | - $u-numberBox-input-text-align: center !default; | ||
| 379 | - $u-numberBox-input-font-size: 15px !default; | ||
| 380 | - $u-numberBox-input-padding: 0 !default; | ||
| 381 | - $u-numberBox-input-margin: 0 2px !default; | ||
| 382 | - $u-numberBox-input-disabled-color: #c8c9cc !default; | ||
| 383 | - $u-numberBox-input-disabled-bgColor: #f2f3f5 !default; | 340 | +@import '../../libs/css/components.scss'; |
| 384 | 341 | ||
| 385 | - .u-number-box { | ||
| 386 | - @include flex(row); | ||
| 387 | - align-items: center; | 342 | +$u-numberBox-hover-bgColor: #E6E6E6 !default; |
| 343 | +$u-numberBox-disabled-color: #c8c9cc !default; | ||
| 344 | +$u-numberBox-disabled-bgColor: #f7f8fa !default; | ||
| 345 | +$u-numberBox-plus-radius: 4px !default; | ||
| 346 | +$u-numberBox-minus-radius: 4px !default; | ||
| 347 | +$u-numberBox-input-text-align: center !default; | ||
| 348 | +$u-numberBox-input-font-size: 15px !default; | ||
| 349 | +$u-numberBox-input-padding: 0 !default; | ||
| 350 | +$u-numberBox-input-margin: 0 2px !default; | ||
| 351 | +$u-numberBox-input-disabled-color: #c8c9cc !default; | ||
| 352 | +$u-numberBox-input-disabled-bgColor: #f2f3f5 !default; | ||
| 388 | 353 | ||
| 389 | - &__slot { | ||
| 390 | - /* #ifndef APP-NVUE */ | ||
| 391 | - touch-action: none; | ||
| 392 | - /* #endif */ | ||
| 393 | - } | 354 | +.u-number-box { |
| 355 | + @include flex(row); | ||
| 356 | + align-items: center; | ||
| 394 | 357 | ||
| 395 | - &__plus, | ||
| 396 | - &__minus { | ||
| 397 | - width: 35px; | ||
| 398 | - @include flex; | ||
| 399 | - justify-content: center; | ||
| 400 | - align-items: center; | ||
| 401 | - /* #ifndef APP-NVUE */ | ||
| 402 | - touch-action: none; | ||
| 403 | - /* #endif */ | 358 | + &__slot { |
| 359 | + /* #ifndef APP-NVUE */ | ||
| 360 | + touch-action: none; | ||
| 361 | + /* #endif */ | ||
| 362 | + } | ||
| 404 | 363 | ||
| 405 | - &--hover { | ||
| 406 | - background-color: $u-numberBox-hover-bgColor !important; | ||
| 407 | - } | 364 | + &__plus, |
| 365 | + &__minus { | ||
| 366 | + width: 35px; | ||
| 367 | + @include flex; | ||
| 368 | + justify-content: center; | ||
| 369 | + align-items: center; | ||
| 370 | + /* #ifndef APP-NVUE */ | ||
| 371 | + touch-action: none; | ||
| 372 | + /* #endif */ | ||
| 408 | 373 | ||
| 409 | - &--disabled { | ||
| 410 | - color: $u-numberBox-disabled-color; | ||
| 411 | - background-color: $u-numberBox-disabled-bgColor; | ||
| 412 | - } | 374 | + &--hover { |
| 375 | + background-color: $u-numberBox-hover-bgColor !important; | ||
| 413 | } | 376 | } |
| 414 | 377 | ||
| 415 | - &__plus { | ||
| 416 | - border-top-right-radius: $u-numberBox-plus-radius; | ||
| 417 | - border-bottom-right-radius: $u-numberBox-plus-radius; | 378 | + &--disabled { |
| 379 | + color: $u-numberBox-disabled-color; | ||
| 380 | + background-color: $u-numberBox-disabled-bgColor; | ||
| 418 | } | 381 | } |
| 382 | + } | ||
| 419 | 383 | ||
| 420 | - &__minus { | ||
| 421 | - border-top-left-radius: $u-numberBox-minus-radius; | ||
| 422 | - border-bottom-left-radius: $u-numberBox-minus-radius; | ||
| 423 | - } | 384 | + &__plus { |
| 385 | + border-top-right-radius: $u-numberBox-plus-radius; | ||
| 386 | + border-bottom-right-radius: $u-numberBox-plus-radius; | ||
| 387 | + } | ||
| 388 | + | ||
| 389 | + &__minus { | ||
| 390 | + border-top-left-radius: $u-numberBox-minus-radius; | ||
| 391 | + border-bottom-left-radius: $u-numberBox-minus-radius; | ||
| 392 | + } | ||
| 424 | 393 | ||
| 425 | - &__input { | ||
| 426 | - position: relative; | ||
| 427 | - text-align: $u-numberBox-input-text-align; | ||
| 428 | - font-size: $u-numberBox-input-font-size; | ||
| 429 | - padding: $u-numberBox-input-padding; | ||
| 430 | - margin: $u-numberBox-input-margin; | ||
| 431 | - @include flex; | ||
| 432 | - align-items: center; | ||
| 433 | - justify-content: center; | 394 | + &__input { |
| 395 | + position: relative; | ||
| 396 | + text-align: $u-numberBox-input-text-align; | ||
| 397 | + font-size: $u-numberBox-input-font-size; | ||
| 398 | + padding: $u-numberBox-input-padding; | ||
| 399 | + margin: $u-numberBox-input-margin; | ||
| 400 | + @include flex; | ||
| 401 | + align-items: center; | ||
| 402 | + justify-content: center; | ||
| 434 | 403 | ||
| 435 | - &--disabled { | ||
| 436 | - color: $u-numberBox-input-disabled-color; | ||
| 437 | - background-color: $u-numberBox-input-disabled-bgColor; | ||
| 438 | - } | 404 | + &--disabled { |
| 405 | + color: $u-numberBox-input-disabled-color; | ||
| 406 | + background-color: $u-numberBox-input-disabled-bgColor; | ||
| 439 | } | 407 | } |
| 440 | } | 408 | } |
| 409 | +} | ||
| 441 | </style> | 410 | </style> |
garbage-removal/src/uview-plus/components/u-picker/u-picker.vue
| @@ -133,7 +133,6 @@ export default { | @@ -133,7 +133,6 @@ export default { | ||
| 133 | // 将当前的各项变化索引,设置为"上一次"的索引变化值 | 133 | // 将当前的各项变化索引,设置为"上一次"的索引变化值 |
| 134 | this.setLastIndex(value) | 134 | this.setLastIndex(value) |
| 135 | this.setIndexs(value) | 135 | this.setIndexs(value) |
| 136 | - | ||
| 137 | this.$emit('change', { | 136 | this.$emit('change', { |
| 138 | // #ifndef MP-WEIXIN || MP-LARK | 137 | // #ifndef MP-WEIXIN || MP-LARK |
| 139 | // 微信小程序不能传递this,会因为循环引用而报错 | 138 | // 微信小程序不能传递this,会因为循环引用而报错 |
| @@ -213,13 +212,17 @@ export default { | @@ -213,13 +212,17 @@ export default { | ||
| 213 | 212 | ||
| 214 | .u-picker { | 213 | .u-picker { |
| 215 | position: relative; | 214 | position: relative; |
| 215 | + box-sizing: border-box; | ||
| 216 | 216 | ||
| 217 | &__view { | 217 | &__view { |
| 218 | 218 | ||
| 219 | + box-sizing: border-box; | ||
| 220 | + | ||
| 219 | &__column { | 221 | &__column { |
| 220 | @include flex; | 222 | @include flex; |
| 221 | flex: 1; | 223 | flex: 1; |
| 222 | justify-content: center; | 224 | justify-content: center; |
| 225 | + box-sizing: border-box; | ||
| 223 | 226 | ||
| 224 | &__item { | 227 | &__item { |
| 225 | @include flex; | 228 | @include flex; |
| @@ -231,12 +234,14 @@ export default { | @@ -231,12 +234,14 @@ export default { | ||
| 231 | display: block; | 234 | display: block; |
| 232 | /* #endif */ | 235 | /* #endif */ |
| 233 | color: $u-main-color; | 236 | color: $u-main-color; |
| 237 | + box-sizing: border-box; | ||
| 234 | 238 | ||
| 235 | &--disabled { | 239 | &--disabled { |
| 236 | /* #ifndef APP-NVUE */ | 240 | /* #ifndef APP-NVUE */ |
| 237 | cursor: not-allowed; | 241 | cursor: not-allowed; |
| 238 | /* #endif */ | 242 | /* #endif */ |
| 239 | opacity: 0.35; | 243 | opacity: 0.35; |
| 244 | + box-sizing: border-box; | ||
| 240 | } | 245 | } |
| 241 | } | 246 | } |
| 242 | } | 247 | } |
| @@ -253,6 +258,7 @@ export default { | @@ -253,6 +258,7 @@ export default { | ||
| 253 | align-items: center; | 258 | align-items: center; |
| 254 | background-color: rgba(255, 255, 255, 0.87); | 259 | background-color: rgba(255, 255, 255, 0.87); |
| 255 | z-index: 1000; | 260 | z-index: 1000; |
| 261 | + box-sizing: border-box; | ||
| 256 | } | 262 | } |
| 257 | } | 263 | } |
| 258 | </style> | 264 | </style> |