Browse Source

任务详情

master
parent
commit
c222cfd49a
  1. 21
      App.vue
  2. 22
      components/cs-page/index.vue
  3. 12
      pages.json
  4. 36
      pages/enterprise.vue
  5. 186
      pages/task.vue
  6. 3
      static/scss/global.scss
  7. 2
      store/modules/user.js
  8. 2
      sub/chat/index.vue
  9. 2
      sub/enterprise/detail.vue
  10. 487
      sub/task/detail.vue
  11. 1
      uni.scss
  12. 15
      uni_modules/s-components/s-tabber/index.vue
  13. 418
      wxcomponents/vant/circle/index.js
  14. 2
      wxcomponents/vant/circle/index.wxml
  15. 17
      wxcomponents/vant/circle/index.wxss
  16. 285
      wxcomponents/vant/dropdown-item/index.js
  17. 252
      wxcomponents/vant/dropdown-menu/index.js
  18. 3
      wxcomponents/vant/dropdown-menu/index.wxml
  19. 25
      wxcomponents/vant/dropdown-menu/index.wxs
  20. 43
      wxcomponents/vant/dropdown-menu/index.wxss

21
App.vue

@ -23,12 +23,29 @@ export default {
animation: false
})
//
this.initConfig()
await this.initConfig()
//
this.checkLogin()
},
initConfig() {
async initConfig() {
this.globalData.config = config
uni.requestSubscribeMessage({
//ID
tmplIds: ['E8RK91cPLMios6ZHoKx6FJOV4H2kodx6yPWYp7jpLJY'],
success(res) {
console.log('requestSubscribeMessage', res)
}
})
uni.getSystemInfoAsync({
success: res => {
uni.setStorageSync('MOBILE', res.model)
uni.setStorageSync('SYSTEM', res.system)
uni.setStorageSync('PIXELRATIO', res.pixelRatio)
},
fail: err => {
console.error('获取设备信息失败:', err)
}
})
},
checkLogin() {
if (!getAccessToken()) {

22
components/cs-page/index.vue

@ -1,6 +1,6 @@
<template>
<view class="">
<view class="container" v-if="isTab">
<view class="container" v-if="isTab" :style="{ height: viewHeight }">
<s-header :title="title" :isTab="isTab" :isCustom="isCustom" @goback="$emit('goback')">
<slot name="header"></slot>
</s-header>
@ -33,7 +33,21 @@ export default {
}
},
data() {
return {}
return {
viewHeight: '0px'
}
},
created() {
this.getViewHeight()
},
methods: {
getViewHeight() {
uni.getSystemInfoAsync({
success: res => {
this.viewHeight = `${res.screenHeight}px`
}
})
}
}
}
</script>
@ -43,9 +57,6 @@ export default {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto;
height: 100vh;
width: 100vw;
overflow: hidden;
.view {
position: relative;
width: 100%;
@ -54,6 +65,7 @@ export default {
position: absolute;
overflow: hidden;
inset: 0;
background-color: #f9f9f9;
}
}
}

12
pages.json

@ -93,7 +93,17 @@
}, {
"path": "task/detail",
"style": {
"navigationBarTitleText": "任务详情"
"navigationBarTitleText": "任务详情",
"onReachBottonDistance": 50,
"enablePullDownRefresh": true,
"usingComponents": {
"van-dropdown-menu": "/wxcomponents/vant/dropdown-menu/index",
"van-dropdown-item": "/wxcomponents/vant/dropdown-item/index"
},
"componentPlaceholder": {
"u-modal": "view",
"u-sticky": "view"
}
}
}]
}],

36
pages/enterprise.vue

@ -1,11 +1,12 @@
<template>
<cs-page :selected="3" title="企业档案" isTab>
<view class="page-container">
<view class="page-container" id="page">
<van-search
:value="queryParams.enterprisesName"
placeholder="输入企业名称或类型查询"
@sreach="queryEnterprise"
@clear="resetQuery('enterpriseName')"
id="sreach"
/>
<van-dropdown-menu safe-area-tab-bar active-color="#17C653">
<van-dropdown-item
@ -53,6 +54,7 @@
@refresherpulling="refresherpulling"
@scrolltolower="loadMore"
class="list"
:style="{ maxHeight: `${listHeight - sreachHeight}px` }"
>
<view
v-for="enterprise in list"
@ -81,7 +83,7 @@
{{ $dict.echoDicValue(dictMap.user_audit_type, enterprise.audit) }}
</view>
</view>
<u-loadmore :status="load" marginTop="20" />
<u-loadmore :status="load" marginTop="12" marginBottom="12" />
</scroll-view>
</view>
</cs-page>
@ -103,6 +105,8 @@ export default {
enterprisesName: '',
tagList: ''
},
listHeight: 0,
sreachHeight: 0,
refresherTriggered: false,
list: [],
load: 'loadmore',
@ -115,7 +119,25 @@ export default {
onShow() {
this.queryEnterprise()
},
onReady() {
this.getPageHeight()
},
methods: {
getPageHeight() {
const query = uni.createSelectorQuery().in(this)
query
.select('#sreach')
.boundingClientRect(data => {
this.sreachHeight = data.height
})
.exec()
query
.select('#page')
.boundingClientRect(data => {
this.listHeight = data.height - 35
})
.exec()
},
async getList() {
uni.showToast({
title: '加载中',
@ -227,8 +249,10 @@ export default {
overflow: hidden;
}
.list {
height: 67vh;
padding: 12px;
display: flex;
flex-flow: column nowrap;
gap: 12px;
padding: 0 12px;
}
.enterprise {
padding: 12px;
@ -242,6 +266,9 @@ export default {
.address {
color: $uni-text-color-grey;
}
&:active {
background-color: $cs-color-touch;
}
.tagList {
margin-top: 8px;
display: flex;
@ -273,6 +300,7 @@ export default {
box-shadow: none;
height: 35px;
font-size: 13px;
border-bottom: 1px solid #f1f1f4;
}
::v-deep .u-list {

186
pages/task.vue

@ -1,40 +1,40 @@
<template>
<cs-page :selected="1" title="执法任务" isTab>
<view class="page-container">
<view class="page-container page">
<van-dropdown-menu safe-area-tab-bar active-color="#17C653">
<van-dropdown-item
:value="queryParams.dept"
:options="getDropdownOption('dept')"
:value="queryParams.status"
:options="getDropdownOption('task_state')"
@change="
v => {
querySelect(v, 'dept')
querySelect(v, 'status')
}
"
/>
<van-dropdown-item
:value="queryParams.hy"
:options="getDropdownOption('hy')"
:value="queryParams.zf_qy"
:options="getDropdownOption('zf_qy')"
@change="
v => {
querySelect(v, 'hy')
querySelect(v, 'zf_qy')
}
"
/>
<van-dropdown-item
:value="queryParams.st"
:options="getDropdownOption('st')"
:value="queryParams.zf_lx"
:options="getDropdownOption('zf_lx')"
@change="
v => {
querySelect(v, 'st')
querySelect(v, 'zf_lx')
}
"
/>
<van-dropdown-item
:value="queryParams.wr"
:options="getDropdownOption('wr')"
:value="queryParams.select_week"
:options="getDropdownOption('select_week')"
@change="
v => {
querySelect(v, 'wr')
querySelect(v, 'select_week')
}
"
/>
@ -47,61 +47,69 @@
@refresherpulling="refresherpulling"
@scrolltolower="loadMore"
class="list"
:enable-flex="true"
:style="{ maxHeight: `${listHeight}px` }"
>
<view
v-for="enterprise in list"
:key="enterprise.id"
class="wd-flex wd-items-center enterprise"
@click="goDetail(enterprise.id)"
>
<van-circle :value="Math.random() * 100" size="56" color="#17c653" layer-color="#F1F1F4">
<template>
<u-count-to :startVal="0" :endVal="Math.random() * 100" fontSize="16" bold duration="1000"></u-count-to>
%
</template>
</van-circle>
<view v-for="task in list" :key="task.id" class="wd-flex wd-items-center enterprise" @click="goDetail(task.id)">
<view class="rate">
<van-circle
:value="task.status == '3' ? 0 : task.pace"
size="56"
type="2d"
color="#17c653"
:layer-color="task.status == '2' ? '#EAFFF1' : '#F1F1F4'"
:canvasId="`canvas-${task.id}`"
>
<template>
<u-count-to :startVal="0" :endVal="task.pace" fontSize="16" bold duration="1000"></u-count-to>
%
</template>
</van-circle>
</view>
<view class="wd-flex wd-flex-col" style="gap: 4px">
<text class="wd-font-800 wd-text-15 wd-pb-2px">{{ enterprise.enterprisesName }}</text>
<text class="wd-font-800 wd-text-15 wd-pb-2px">{{ task.title }}</text>
<view class="wd-flex wd-pb-8px">
<u-icon name="clock" size="14" color="#17C653"></u-icon>
<text class="address wd-text-12" style="margin-left: 4px">于2024年12月15日结束</text>
<u-icon name="calendar" size="18" :color="task.status == '2' ? '#17C653' : '#78829D'"></u-icon>
<text
class="address wd-text-12"
style="margin-left: 4px"
:style="{ color: task.status == '2' ? '#17C653' : '#78829D' }"
>
{{ $util.formatDate(task.endDate, 'YYYY年MM月DD日') }}结束
</text>
</view>
<view class="tagList">
<view class="tag" v-for="(tag, index) in enterprise.tagList" :key="index">
<view class="tag" v-for="(tag, index) in task.tagList" :key="index">
{{ tag }}
</view>
</view>
</view>
<view
class="audit"
v-if="enterprise.audit != 2"
:style="{ color: enterprise.audit == 1 ? '#F6B100' : '#ea000c', backgroundColor: '#FFF8DD' }"
>
{{ $dict.echoDicValue(dictMap.user_audit_type, enterprise.audit) }}
<view class="audit">
<cs-dict-tag :dict="dictMap.task_state" :value="task.status"></cs-dict-tag>
</view>
</view>
<u-loadmore :status="load" marginTop="20" />
<u-loadmore :status="load" marginTop="12" marginBottom="12" />
</scroll-view>
</view>
</cs-page>
</template>
<script>
import { getEnterPriseList } from '@/api/enterprise/index.js'
import { getDictBatchByType, getDeptTree, getTagData } from '@/api/system/dict.js'
import { TaskApi } from '@/api/task/index.js'
export default {
data() {
return {
queryParams: {
pageSize: 10,
pageNo: 1,
qy: '',
hy: '',
st: '',
wr: '',
dept: '',
zf_lx: '',
zf_qy: '',
status: '',
select_week: '',
tagList: ''
},
listHeight: 0,
refresherTriggered: false,
list: [],
load: 'loadmore',
@ -111,10 +119,20 @@ export default {
async onLoad() {
await this.getDict()
},
onShow() {
onReady() {
this.getPageHeight()
this.queryEnterprise()
},
methods: {
getPageHeight() {
const query = uni.createSelectorQuery().in(this)
query
.select('.page')
.boundingClientRect(data => {
this.listHeight = data.height - 55
})
.exec()
},
async getList() {
uni.showToast({
title: '加载中',
@ -122,8 +140,15 @@ export default {
icon: 'loading'
})
this.load = 'loading'
const res = await getEnterPriseList(this.queryParams)
this.list.push(...res.data.list)
const res = await TaskApi.getList(this.queryParams)
this.list.push(
...res.data.list.map((i, index) => {
return {
...i,
pace: (i.taskFinishNum / i.taskExecNum) * 100
}
})
)
this.load = 'loadmore'
if (this.list.length == res.data.total) {
this.load = 'nomore'
@ -131,37 +156,26 @@ export default {
uni.hideToast()
},
async getDict() {
const tags = await getTagData(['qy', ' hy', 'st', 'wr'].join(','))
const dict = await getDictBatchByType({ type: ['user_audit_type'].join(',') })
const dept = await getDeptTree()
const tags = await getTagData(['zf_lx', 'zf_qy'].join(','))
const dict = await getDictBatchByType({ type: ['select_week', 'task_state'].join(',') })
let tagMap = {}
tags.data.forEach(t => {
tagMap[t.tagCode] = t.children
})
this.dictMap = {
...tagMap,
...dict.data,
dept: dept.data.map(i => {
return {
...i,
text: i.name,
value: i.id
}
})
...dict.data
}
},
getDropdownOption(key) {
if (!this.dictMap[key]) return []
const keyMap = {
qy: '区域',
hy: '行业',
st: '生态',
wr: '污染',
dept: '全部部门'
zf_qy: '按区域',
zf_lx: '按类型',
task_state: '按状态',
select_week: '按周期'
}
if (key == 'dept') {
return [...this.dictMap[key], { value: '', text: keyMap[key] }]
} else {
if (['zf_qy', 'zf_lx'].includes(key)) {
return [
...this.dictMap[key].map(d => {
return {
@ -171,6 +185,16 @@ export default {
}),
{ value: '', text: keyMap[key] }
]
} else {
return [
...this.dictMap[key].map(d => {
return {
value: d.value,
text: d.label
}
}),
{ value: '', text: keyMap[key] }
]
}
},
querySelect(v, key) {
@ -181,9 +205,7 @@ export default {
this.queryParams.pageNo = 1
this.load = 'loadmore'
this.list = []
this.queryParams.tagList = [this.queryParams.qy, this.queryParams.hy, this.queryParams.st, this.queryParams.wr]
.filter(i => i != '')
.join()
this.queryParams.tagList = [this.queryParams.zf_qy, this.queryParams.zf_lx].filter(i => i != '').join()
this.getList()
},
loadMore() {
@ -213,11 +235,10 @@ export default {
this.queryParams = {
pageSize: 10,
pageNo: 1,
qy: '',
hy: '',
st: '',
wr: '',
dept: '',
zf_lx: '',
zf_qy: '',
status: '',
select_week: '',
tagList: ''
}
await this.queryEnterprise()
@ -237,8 +258,7 @@ export default {
overflow: hidden;
}
.list {
height: 75vh;
padding: 12px;
padding: 0 12px;
}
.enterprise {
padding: 12px;
@ -249,6 +269,9 @@ export default {
position: relative;
overflow: hidden;
font-size: 12px;
&:active {
background-color: $cs-color-touch;
}
.address {
color: $uni-text-color-grey;
}
@ -270,19 +293,20 @@ export default {
}
.audit {
position: absolute;
right: -19px;
top: 6px;
transform: rotateZ(45deg);
right: 0;
top: 0;
transform-origin: 50% 50%;
padding: 4px 20px;
font-size: 12px;
text-align: center;
transform: translateX(28px) translateY(9px) rotateZ(45deg);
}
.rate {
position: relative;
}
}
::v-deep .van-dropdown-menu {
box-shadow: none;
height: 35px;
height: 35px !important;
font-size: 13px;
border-bottom: 1px solid #f1f1f4;
}
::v-deep .u-list {

3
static/scss/global.scss

@ -0,0 +1,3 @@
page {
background-color: #f9f9f9;
}

2
store/modules/user.js

@ -75,7 +75,7 @@ const user = {
return new Promise((resolve, reject) => {
getInfo().then(res => {
const user = res.data.user
if (res.roles && res.roles.length > 0) {
if (res.data.roles && res.data.roles.length > 0) {
commit('SET_ROLES', res.roles)
commit('SET_PERMISSIONS', res.permissions)
} else {

2
sub/chat/index.vue

@ -1,5 +1,5 @@
<template>
<web-view src="https://mb.jzce.com/chat/313cf9e35628923a"></web-view>
<web-view src="https://mb.jzce.com/chat/f07644a8e53c750a"></web-view>
</template>
<script>

2
sub/enterprise/detail.vue

@ -57,7 +57,7 @@
</view>
<view class="box">
<view class="wd-font-800">检查记录</view>
<view class="wd-font-800">执法记录</view>
</view>
<view class="button-box">

487
sub/task/detail.vue

@ -1,85 +1,306 @@
<template>
<cs-page>
<view class="detail-container">
<view class="detail-container" :style="{ paddingBottom: isSelect.length > 0 ? '70px' : '20px' }">
<view class="box detail">
<text class="wd-font-800 wd-text-16" style="margin-bottom: 4px">xxxx</text>
<text class="wd-font-800 wd-text-16" style="margin-bottom: 4px">{{ detail.title }}</text>
<view class="tagList">
<view v-for="(item, index) in 3" :key="index" class="tag">标签{{ index }}</view>
<view v-for="(tag, index) in detail.tagList" :key="index" class="tag">{{ tag }}</view>
</view>
<view class="wd-flex wd-text-13" style="justify-content: space-between">
<view class="wd-flex" style="align-items: center; gap: 4px">
<u-icon name="calendar" color="#17C653" />
<text class="wd-text-13 wd-ml-4px">2024/12/15~2025/12/15</text>
<text class="wd-text-13 wd-ml-4px">
{{ $util.formatDate(detail.startDate, 'YYYY/M/D') }} ~ {{ $util.formatDate(detail.endDate, 'YYYY/M/D') }}
</text>
</view>
<view class="wd-flex" style="align-items: center; gap: 4px">
<u-icon name="account" color="#17C653" />
<text class="wd-text-13 wd-font-800">姓名</text>
<text class="wd-text-13">部门</text>
</view>
<view
style="font-size: 13px; line-height: 160%; position: relative; transform: 0.2s all"
v-if="detail.description.length < 20"
>
{{ detail.description }}
</view>
<view
v-else
style="font-size: 13px; line-height: 160%; position: relative; transform: 0.2s all"
@tap="isShowAllText = !isShowAllText"
>
{{ isShowAllText ? detail.description : `${detail.description.slice(1, 20)}...` }}
<text style="color: #17c653; padding-left: 4px">{{ isShowAllText ? '收起' : '展开' }}</text>
</view>
<view class="audit">
<cs-dict-tag :dict="dictMap.task_state" :value="detail.status"></cs-dict-tag>
</view>
</view>
<u-sticky>
<view :class="['options-container', OptionsOffset.isTop ? 'isTop' : '']" ref="optionRef" id="options">
<van-dropdown-menu safe-area-tab-bar active-color="#17C653" style="flex: 1">
<van-dropdown-item
:value="queryParams.dept"
:options="getDropdownOption('dept')"
@change="
v => {
querySelect(v, 'dept')
}
"
/>
<van-dropdown-item
:value="queryParams.Inspections_status"
:options="getDropdownOption('Inspections_status')"
@change="
v => {
querySelect(v, 'Inspections_status')
}
"
/>
</van-dropdown-menu>
<view class="wd-font-600">
(当前
<text style="color: #17c653">{{ list.length }}</text>
条记录)
</view>
</view>
<view class="" style="font-size: 13px; line-height: 160%">
任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求任务要求
</u-sticky>
<view class="record" v-for="record in list" :key="record.id">
<view
:class="{ select: true, isSelect: isSelect.includes(record.id) }"
@tap.self="select(record.id)"
v-if="[3, null].includes(record.inspectionStatus)"
>
<u-icon name="checkbox-mark" size="16px" color="#fff"></u-icon>
</view>
<view class="disable" v-else></view>
<view class="info">
<view class="name">{{ record.enterpriseAddress }}</view>
<view style="font-size: 1 3px">{{ record.enterpriseAddress }}</view>
<view class="tagList" style="margin-top: 8px">
<view v-for="(item, index) in record.tagList" :key="index" class="tag">{{ item }}</view>
</view>
</view>
<view class="audit">111</view>
<view class="audit" v-show="record.inspectionStatus">
<cs-dict-tag :dict="dictMap.Inspections_status" :value="record.inspectionStatus"></cs-dict-tag>
</view>
</view>
<u-loadmore :status="load" marginTop="12" marginBottom="12" />
<view class="btn-box" v-if="isSelect.length > 0">
<view class="confirm-btn" @tap="replay">已选择({{ isSelect.length }})</view>
</view>
<scroll-view scroll-y="true" class="list">
<view class="record" v-for="record in 10" :key="record.id">
<view :class="{ select: true, isSelect: false }" @tap="select()">
<u-icon name="checkbox-mark" size="16px" color="#fff"></u-icon>
<u-modal :show="model.show" closeOnClickOverlay @close="closeModel">
<view class="wd-flex wd-flex-col" style="gap: 20px">
<view class="header">
<view class="row-1">
已选择
<text class="num">{{ isSelect.length }}项记录</text>
转移给
</view>
<view class="row-2">每次只能选择一人</view>
</view>
<view class="info">
<view class="name">义县某某环保企业名称</view>
<view style="font-size: 13px">某某区工业产业园5-182</view>
<view class="tagList" style="margin-top: 8px">
<view v-for="(item, index) in 3" :key="index" class="tag">标签{{ index }}</view>
<view class="staff-list">
<view
class="staff"
v-for="(staff, index) in 10"
:key="staff.id"
:style="{ '--select-color': index == 0 ? '#17c653' : '#f1f1f4' }"
>
<u-avatar size="40" shape="circle"></u-avatar>
<view class="info">
<view class="name">姓名</view>
<view class="dept">部门</view>
</view>
<view class="isSelect">
<u-icon name="checkbox-mark" size="16px" color="#fff"></u-icon>
</view>
</view>
</view>
<view class="audit">111</view>
</view>
<u-loadmore :status="load" marginTop="20" />
</scroll-view>
<template #confirmButton>
<view class="wd-flex wd-flex-center">
<view class="confirm-btn">转移给TA</view>
</view>
</template>
</u-modal>
</view>
</cs-page>
</template>
<script>
import { getEnterPrise } from '@/api/enterprise/index.js'
import { getDictBatchByType } from '@/api/system/dict.js'
import { getDeptTree, getDictBatchByType } from '@/api/system/dict.js'
import { TaskApi } from '@/api/task/index.js'
import { InspectionsApi } from '@/api/inspections/index.js'
export default {
data() {
return {
//
detail: {
id: ''
id: '',
description: ''
},
list: [],
//
isShowAllText: false,
//
isSelect: [],
dictMap: {},
//u-sticky
OptionsOffset: {
top: 0,
isTop: false
},
isSelect: false,
dictMap: {}
//
queryParams: {
dept: '',
Inspections_status: '',
pageSize: 8,
pageNo: 1,
taskId: ''
},
load: 'loadmore',
model: {
show: false
}
}
},
onLoad(res) {
if (res.id) {
this.detail.id = res.id
}
// this.getDict()
this.queryParams.taskId = res.id
this.getDict()
this.init()
},
onPageScroll(e) {
this.OptionsOffset.isTop = e.scrollTop + 10 > this.OptionsOffset.top
},
onReady() {
this.getOptionOffset()
},
onReachBottom() {
this.loadMore()
},
onPullDownRefresh() {
this.reset()
},
methods: {
getOptionOffset() {
const query = uni.createSelectorQuery().in(this)
query
.select('#options')
.boundingClientRect(data => {
this.OptionsOffset.top = data.top
})
.exec()
},
/**
* 获取字典
*/
async getDict() {
const dict = await getDictBatchByType({ type: ['enterprises_type', 'enterprise_qua'].join(',') })
const dict = await getDictBatchByType({ type: ['task_state', 'Inspections_status'].join(',') })
const dept = await getDeptTree()
this.dictMap = {
...dict.data
...dict.data,
dept: dept.data
}
},
getDropdownOption(key) {
const keyMap = {
dept: '按部门',
Inspections_status: '按状态'
}
if (!this.dictMap[key]) return []
if (key == 'dept') {
return [
...this.dictMap[key].map(d => {
return {
...d,
value: d.id,
text: d.name
}
}),
{
value: '',
text: keyMap[key]
}
]
}
return [
...this.dictMap[key].map(d => {
return {
value: d.value,
text: d.label
}
}),
{ value: '', text: keyMap[key] }
]
},
querySelect(v, key) {
this.queryParams[key] = v.detail
// this.queryEnterprise()
},
async init() {
const res = await TaskApi.getDetail(this.queryParams.taskId)
this.detail = res.data
this.getList()
},
async getList() {
uni.showToast({
title: '加载中',
mask: true,
icon: 'loading'
})
this.load = 'loading'
const { data } = await InspectionsApi.getList(this.queryParams)
this.list.push(...data.list)
this.load = 'loadmore'
if (this.list.length == data.total) {
this.load = 'nomore'
}
uni.hideToast()
},
async init() {},
goBack() {
uni.switchTab({
url: '/pages/task'
})
},
select() {
this.isSelect = !this.isSelect
loadMore() {
if (this.load == 'nomore') {
uni.showToast({
title: '没有更多了',
icon: 'none'
})
return
}
this.queryParams.pageNo++
this.getList()
},
select(id) {
if (this.isSelect.includes(id)) {
this.isSelect = this.isSelect.filter(i => i != id)
} else {
this.isSelect.push(id)
}
},
async reset() {
this.queryParams = {
dept: '',
Inspections_status: '',
pageSize: 8,
pageNo: 1,
taskId: ''
}
await this.queryList()
},
queryList() {
this.queryParams.pageNo = 1
this.load = 'loadmore'
this.list = []
this.getList()
},
replay() {
this.model.show = true
},
closeModel() {
this.model.show = false
}
}
}
@ -87,11 +308,10 @@ export default {
<style lang="scss" scoped>
.detail-container {
padding: 12px;
position: relative;
color: $cs-color-grey;
.box {
margin-bottom: 12px;
margin: 12px;
background-color: #fff;
border-radius: $cs-border-radius;
padding: 16px;
@ -101,6 +321,14 @@ export default {
flex-flow: column nowrap;
gap: 12px;
position: relative;
overflow: hidden;
.audit {
position: absolute;
right: 0;
top: 0;
transform: translateX(23px) translateY(16px) rotateZ(45deg);
transform-origin: 50% 50%;
}
}
.tagList {
display: flex;
@ -122,52 +350,165 @@ export default {
line-height: normal;
}
}
.list {
height: 65vh;
padding-bottom: 30px;
.record {
background-color: #fff;
.record {
background-color: #fff;
display: flex;
padding: 12px 16px;
align-items: center;
border-radius: var(--Number-8px, 8px);
border: 1px solid var(--LightMode-Grey-Grey-100, #f9f9f9);
margin: 12px;
margin-top: 0;
position: relative;
overflow: hidden;
.audit {
position: absolute;
right: 0;
top: 0;
transform-origin: 50% 50%;
transform: translateX(30px) translateY(10px) rotateZ(45deg);
}
.select {
width: 24px;
height: 24px;
border: 2px solid $cs-color-main;
border-radius: 6px;
display: flex;
padding: var(--Number-12px, 12px);
align-items: center;
border-radius: var(--Number-8px, 8px);
border: 1px solid var(--LightMode-Grey-Grey-100, #f9f9f9);
margin-bottom: 12px;
justify-content: center;
transition: 0.2s all;
margin-right: 16px;
}
.disable {
width: 24px;
height: 24px;
border: 2px solid #dbdfe9;
margin-right: 16px;
border-radius: 100%;
position: relative;
.select {
width: 24px;
height: 24px;
border: 2px solid $cs-color-main;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
transition: 0.2s all;
margin-right: 16px;
&::after {
content: '';
position: absolute;
inset: 0;
border-left: 2px solid #dbdfe9;
transform-origin: 0 50%;
transform: translateX(calc(50% - 1px)) rotateZ(45deg);
}
.isSelect {
background-color: $cs-color-main;
}
.isSelect {
background-color: $cs-color-main;
}
.info {
font-size: 13px;
.name {
font-size: 16px;
font-weight: 600;
color: #071437;
margin-bottom: 4px;
}
}
&:active {
background-color: $cs-color-touch;
}
}
.btn-box {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 30px;
position: fixed;
bottom: 0;
left: 0;
}
.confirm-btn {
background-color: $cs-color-main;
padding: 12px 40px;
color: #fff;
font-size: 16px;
font-weight: 600;
border-radius: 120px;
}
.header {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
gap: 4px;
.row-1 {
font-size: 16px;
font-weight: 600;
color: #071437;
.num {
color: $cs-color-main;
padding: 0 4px;
}
}
.row-2 {
color: $cs-color-grey;
}
}
.staff-list {
width: 70vw;
display: flex;
flex-flow: row wrap;
gap: 12px;
max-height: 30vh;
overflow-y: scroll;
.staff {
width: calc(50% - 6px);
padding: 12px;
border-radius: 6px;
border: 1px solid var(--select-color, #dbdfe9);
position: relative;
gap: 8px;
display: flex;
.info {
font-size: 13px;
.name {
font-size: 16px;
font-weight: 600;
color: #071437;
margin-bottom: 4px;
font-weight: bold;
}
.dept {
color: $cs-color-grey;
}
}
.isSelect {
position: absolute;
right: 0;
top: 0;
width: 30px;
height: 30px;
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0) 50%, var(--select-color, #f1f1f4) 50%);
display: flex;
justify-content: flex-end;
align-items: flex-start;
}
}
}
.audit {
position: absolute;
right: -10px;
top: 6px;
transform: rotateZ(45deg);
transform-origin: 50% 50%;
padding: 4px 20px;
font-size: 12px;
text-align: center;
}
.options-container {
overflow: hidden;
margin: 12px;
border-radius: 8px;
transition: 0.1s all;
display: flex;
padding: 0 12px;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
background-color: #fff;
border-bottom: 1px solid #f1f1f4;
color: #071437;
::v-deep .van-dropdown-menu {
background-color: transparent;
box-shadow: none;
--dropdown-menu-title-font-size: 13px;
--dropdown-menu-title-text-color: #071437;
}
}
.isTop {
margin: 12px 0;
border-radius: 0px;
}
</style>

1
uni.scss

@ -68,3 +68,4 @@ $cs-border-radius: 8px;
$cs-gap: 10px;
$cs-color-main: #17c653;
$cs-color-grey: #4b5675;
$cs-color-touch: #f9f9f9;

15
uni_modules/s-components/s-tabber/index.vue

@ -19,7 +19,7 @@
</view>
</view>
</view>
<view class="fit-content"></view>
<view :style="{ height: isFit ? '25px' : '12px' }"></view>
</view>
</template>
@ -43,7 +43,7 @@ export default {
code: 0
},
{
name: '任务',
name: '执法',
path: '/pages/task',
icon: '/static/images/tabbers/task.png',
selectIcon: '/static/images/tabbers/task-select.png',
@ -77,6 +77,9 @@ export default {
computed: {
setClass() {
return this.$props.isTab ? 'container' : 'noTab'
},
isFit() {
return uni.getStorageSync('SYSTEM').includes('iOS')
}
},
methods: {
@ -95,20 +98,16 @@ export default {
<style lang="scss">
.container {
background-color: #fff;
// box-shadow: 0 -1px 2px 1px $cs-shadow-color;
}
.noTab {
// background-color: #fff;
}
.fit-content {
height: 20px;
}
.tabber {
height: 60px;
display: flex;
flex-flow: row nowrap;
justify-content: space-around;
align-items: center;
border-top: 1px solid #f1f1f4;
padding: 12px 32px 0px 32px;
.tab {
transition: 0.2s all;
}

418
wxcomponents/vant/circle/index.js

@ -1,197 +1,233 @@
import { BLUE, WHITE } from '../common/color';
import { VantComponent } from '../common/component';
import { getSystemInfoSync } from '../common/utils';
import { isObj } from '../common/validator';
import { canIUseCanvas2d } from '../common/version';
import { adaptor } from './canvas';
import {
BLUE,
WHITE
} from '../common/color';
import {
VantComponent
} from '../common/component';
import {
getSystemInfoSync
} from '../common/utils';
import {
isObj
} from '../common/validator';
import {
canIUseCanvas2d
} from '../common/version';
import {
adaptor
} from './canvas';
function format(rate) {
return Math.min(Math.max(rate, 0), 100);
return Math.min(Math.max(rate, 0), 100);
}
const PERIMETER = 2 * Math.PI;
const BEGIN_ANGLE = -Math.PI / 2;
const STEP = 1;
VantComponent({
props: {
text: String,
lineCap: {
type: String,
value: 'round',
},
value: {
type: Number,
value: 0,
observer: 'reRender',
},
speed: {
type: Number,
value: 50,
},
size: {
type: Number,
value: 100,
observer() {
this.drawCircle(this.currentValue);
},
},
fill: String,
layerColor: {
type: String,
value: WHITE,
},
color: {
type: null,
value: BLUE,
observer() {
this.setHoverColor().then(() => {
this.drawCircle(this.currentValue);
});
},
},
type: {
type: String,
value: '',
},
strokeWidth: {
type: Number,
value: 4,
},
clockwise: {
type: Boolean,
value: true,
},
},
data: {
hoverColor: BLUE,
},
methods: {
getContext() {
const { type, size } = this.data;
if (type === '' || !canIUseCanvas2d()) {
const ctx = wx.createCanvasContext('van-circle', this);
return Promise.resolve(ctx);
}
const dpr = getSystemInfoSync().pixelRatio;
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(this)
.select('#van-circle')
.node()
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext(type);
if (!this.inited) {
this.inited = true;
canvas.width = size * dpr;
canvas.height = size * dpr;
ctx.scale(dpr, dpr);
}
resolve(adaptor(ctx));
});
});
},
setHoverColor() {
const { color, size } = this.data;
if (isObj(color)) {
return this.getContext().then((context) => {
if (!context)
return;
const LinearColor = context.createLinearGradient(size, 0, 0, 0);
Object.keys(color)
.sort((a, b) => parseFloat(a) - parseFloat(b))
.map((key) => LinearColor.addColorStop(parseFloat(key) / 100, color[key]));
this.hoverColor = LinearColor;
});
}
this.hoverColor = color;
return Promise.resolve();
},
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
const { strokeWidth, lineCap, clockwise, size } = this.data;
const position = size / 2;
const radius = position - strokeWidth / 2;
context.setStrokeStyle(strokeStyle);
context.setLineWidth(strokeWidth);
context.setLineCap(lineCap);
context.beginPath();
context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
context.stroke();
if (fill) {
context.setFillStyle(fill);
context.fill();
}
},
renderLayerCircle(context) {
const { layerColor, fill } = this.data;
this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
},
renderHoverCircle(context, formatValue) {
const { clockwise } = this.data;
// 结束角度
const progress = PERIMETER * (formatValue / 100);
const endAngle = clockwise
? BEGIN_ANGLE + progress
: 3 * Math.PI - (BEGIN_ANGLE + progress);
this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
},
drawCircle(currentValue) {
const { size } = this.data;
this.getContext().then((context) => {
if (!context)
return;
context.clearRect(0, 0, size, size);
this.renderLayerCircle(context);
const formatValue = format(currentValue);
if (formatValue !== 0) {
this.renderHoverCircle(context, formatValue);
}
context.draw();
});
},
reRender() {
// tofector 动画暂时没有想到好的解决方案
const { value, speed } = this.data;
if (speed <= 0 || speed > 1000) {
this.drawCircle(value);
return;
}
this.clearMockInterval();
this.currentValue = this.currentValue || 0;
const run = () => {
this.interval = setTimeout(() => {
if (this.currentValue !== value) {
if (Math.abs(this.currentValue - value) < STEP) {
this.currentValue = value;
}
else if (this.currentValue < value) {
this.currentValue += STEP;
}
else {
this.currentValue -= STEP;
}
this.drawCircle(this.currentValue);
run();
}
else {
this.clearMockInterval();
}
}, 1000 / speed);
};
run();
},
clearMockInterval() {
if (this.interval) {
clearTimeout(this.interval);
this.interval = null;
}
},
},
mounted() {
this.currentValue = this.data.value;
this.setHoverColor().then(() => {
this.drawCircle(this.currentValue);
});
},
destroyed() {
this.clearMockInterval();
},
});
props: {
text: String,
lineCap: {
type: String,
value: 'round',
},
value: {
type: Number,
value: 0,
observer: 'reRender',
},
speed: {
type: Number,
value: 50,
},
size: {
type: Number,
value: 100,
observer() {
this.drawCircle(this.currentValue);
},
},
fill: String,
layerColor: {
type: String,
value: WHITE,
},
color: {
type: null,
value: BLUE,
observer() {
this.setHoverColor().then(() => {
this.drawCircle(this.currentValue);
});
},
},
type: {
type: String,
value: '',
},
strokeWidth: {
type: Number,
value: 4,
},
clockwise: {
type: Boolean,
value: true,
},
canvasId: {
type: String,
value: ''
}
},
data: {
hoverColor: BLUE,
},
methods: {
getContext() {
const {
type,
size
} = this.data;
if (type === '' || !canIUseCanvas2d()) {
const ctx = wx.createCanvasContext('van-circle', this);
return Promise.resolve(ctx);
}
const dpr = getSystemInfoSync().pixelRatio;
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(this)
.select('#van-circle')
.node()
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext(type);
if (!this.inited) {
this.inited = true;
canvas.width = size * dpr;
canvas.height = size * dpr;
ctx.scale(dpr, dpr);
}
resolve(adaptor(ctx));
});
});
},
setHoverColor() {
const {
color,
size
} = this.data;
if (isObj(color)) {
return this.getContext().then((context) => {
if (!context)
return;
const LinearColor = context.createLinearGradient(size, 0, 0, 0);
Object.keys(color)
.sort((a, b) => parseFloat(a) - parseFloat(b))
.map((key) => LinearColor.addColorStop(parseFloat(key) / 100, color[key]));
this.hoverColor = LinearColor;
});
}
this.hoverColor = color;
return Promise.resolve();
},
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
const {
strokeWidth,
lineCap,
clockwise,
size
} = this.data;
const position = size / 2;
const radius = position - strokeWidth / 2;
context.setStrokeStyle(strokeStyle);
context.setLineWidth(strokeWidth);
context.setLineCap(lineCap);
context.beginPath();
context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
context.stroke();
if (fill) {
context.setFillStyle(fill);
context.fill();
}
},
renderLayerCircle(context) {
const {
layerColor,
fill
} = this.data;
this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
},
renderHoverCircle(context, formatValue) {
const {
clockwise
} = this.data;
// 结束角度
const progress = PERIMETER * (formatValue / 100);
const endAngle = clockwise ?
BEGIN_ANGLE + progress :
3 * Math.PI - (BEGIN_ANGLE + progress);
this.presetCanvas(context, this.hoverColor, BEGIN_ANGLE, endAngle);
},
drawCircle(currentValue) {
const {
size
} = this.data;
this.getContext().then((context) => {
if (!context)
return;
context.clearRect(0, 0, size, size);
this.renderLayerCircle(context);
const formatValue = format(currentValue);
if (formatValue !== 0) {
this.renderHoverCircle(context, formatValue);
}
context.draw();
});
},
reRender() {
// tofector 动画暂时没有想到好的解决方案
const {
value,
speed
} = this.data;
if (speed <= 0 || speed > 1000) {
this.drawCircle(value);
return;
}
this.clearMockInterval();
this.currentValue = this.currentValue || 0;
const run = () => {
this.interval = setTimeout(() => {
if (this.currentValue !== value) {
if (Math.abs(this.currentValue - value) < STEP) {
this.currentValue = value;
} else if (this.currentValue < value) {
this.currentValue += STEP;
} else {
this.currentValue -= STEP;
}
this.drawCircle(this.currentValue);
run();
} else {
this.clearMockInterval();
}
}, 1000 / speed);
};
run();
},
clearMockInterval() {
if (this.interval) {
clearTimeout(this.interval);
this.interval = null;
}
},
},
mounted() {
this.currentValue = this.data.value;
this.setHoverColor().then(() => {
this.drawCircle(this.currentValue);
});
},
destroyed() {
this.clearMockInterval();
},
});

2
wxcomponents/vant/circle/index.wxml

@ -1,7 +1,7 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-circle">
<canvas class="van-circle__canvas" type="{{ type }}" style="width: {{ utils.addUnit(size) }};height:{{ utils.addUnit(size) }}" id="van-circle" canvas-id="van-circle"></canvas>
<canvas class="van-circle__canvas" type="{{ type }}" style="width: {{ utils.addUnit(size) }};height:{{ utils.addUnit(size) }}" id="van-circle" canvas-id="{{canvasId}}"></canvas>
<view wx:if="{{ !text }}" class="van-circle__text">
<slot></slot>
</view>

17
wxcomponents/vant/circle/index.wxss

@ -1 +1,16 @@
@import '../common/index.wxss';.van-circle{display:inline-block;position:relative;text-align:center}.van-circle__text{color:var(--circle-text-color,#323233);left:0;position:absolute;top:50%;transform:translateY(-50%);width:100%}
@import '../common/index.wxss';
.van-circle {
display: inline-block;
position: relative;
text-align: center
}
.van-circle__text {
color: var(--circle-text-color, #323233);
left: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%
}

285
wxcomponents/vant/dropdown-item/index.js

@ -1,130 +1,157 @@
import { useParent } from '../common/relation';
import { VantComponent } from '../common/component';
import {
useParent
} from '../common/relation';
import {
VantComponent
} from '../common/component';
VantComponent({
classes: ['item-title-class'],
field: true,
relation: useParent('dropdown-menu', function () {
this.updateDataFromParent();
}),
props: {
value: {
type: null,
observer: 'rerender',
},
title: {
type: String,
observer: 'rerender',
},
disabled: Boolean,
titleClass: {
type: String,
observer: 'rerender',
},
options: {
type: Array,
value: [],
observer: 'rerender',
},
popupStyle: String,
useBeforeToggle: {
type: Boolean,
value: false,
},
rootPortal: {
type: Boolean,
value: false,
},
},
data: {
transition: true,
showPopup: false,
showWrapper: false,
displayTitle: '',
safeAreaTabBar: false,
},
methods: {
rerender() {
wx.nextTick(() => {
var _a;
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.updateItemListData();
});
},
updateDataFromParent() {
if (this.parent) {
const { overlay, duration, activeColor, closeOnClickOverlay, direction, safeAreaTabBar, } = this.parent.data;
this.setData({
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
safeAreaTabBar,
});
}
},
onOpen() {
this.$emit('open');
},
onOpened() {
this.$emit('opened');
},
onClose() {
this.$emit('close');
},
onClosed() {
this.$emit('closed');
this.setData({ showWrapper: false });
},
onOptionTap(event) {
const { option } = event.currentTarget.dataset;
const { value } = option;
const shouldEmitChange = this.data.value !== value;
this.setData({ showPopup: false, value });
this.$emit('close');
this.rerender();
if (shouldEmitChange) {
this.$emit('change', value);
}
},
toggle(show, options = {}) {
const { showPopup } = this.data;
if (typeof show !== 'boolean') {
show = !showPopup;
}
if (show === showPopup) {
return;
}
this.onBeforeToggle(show).then((status) => {
var _a;
if (!status) {
return;
}
this.setData({
transition: !options.immediate,
showPopup: show,
});
if (show) {
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.getChildWrapperStyle().then((wrapperStyle) => {
this.setData({ wrapperStyle, showWrapper: true });
this.rerender();
});
}
else {
this.rerender();
}
});
},
onBeforeToggle(status) {
const { useBeforeToggle } = this.data;
if (!useBeforeToggle) {
return Promise.resolve(true);
}
return new Promise((resolve) => {
this.$emit('before-toggle', {
status,
callback: (value) => resolve(value),
});
});
},
},
});
classes: ['item-title-class'],
field: true,
relation: useParent('dropdown-menu', function() {
this.updateDataFromParent();
}),
props: {
value: {
type: null,
observer: 'rerender',
},
title: {
type: String,
observer: 'rerender',
},
disabled: Boolean,
titleClass: {
type: String,
observer: 'rerender',
},
options: {
type: Array,
value: [],
observer: 'rerender',
},
popupStyle: String,
useBeforeToggle: {
type: Boolean,
value: false,
},
rootPortal: {
type: Boolean,
value: false,
},
},
data: {
transition: true,
showPopup: false,
showWrapper: false,
displayTitle: '',
safeAreaTabBar: false,
},
methods: {
rerender() {
wx.nextTick(() => {
var _a;
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.updateItemListData();
});
},
updateDataFromParent() {
if (this.parent) {
const {
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
safeAreaTabBar,
} = this.parent.data;
this.setData({
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
safeAreaTabBar,
});
}
},
onOpen() {
this.$emit('open');
},
onOpened() {
this.$emit('opened');
},
onClose() {
this.$emit('close');
},
onClosed() {
this.$emit('closed');
this.setData({
showWrapper: false
});
},
onOptionTap(event) {
const {
option
} = event.currentTarget.dataset;
const {
value
} = option;
const shouldEmitChange = this.data.value !== value;
this.setData({
showPopup: false,
value
});
this.$emit('close');
this.rerender();
if (shouldEmitChange) {
this.$emit('change', value);
}
},
toggle(show, options = {}) {
const {
showPopup
} = this.data;
if (typeof show !== 'boolean') {
show = !showPopup;
}
if (show === showPopup) {
return;
}
this.onBeforeToggle(show).then((status) => {
var _a;
if (!status) {
return;
}
this.setData({
transition: !options.immediate,
showPopup: show,
});
if (show) {
(_a = this.parent) === null || _a === void 0 ? void 0 : _a.getChildWrapperStyle().then((
wrapperStyle) => {
this.setData({
wrapperStyle,
showWrapper: true
});
this.rerender();
});
} else {
this.rerender();
}
});
},
onBeforeToggle(status) {
const {
useBeforeToggle
} = this.data;
if (!useBeforeToggle) {
return Promise.resolve(true);
}
return new Promise((resolve) => {
this.$emit('before-toggle', {
status,
callback: (value) => resolve(value),
});
});
},
},
});

252
wxcomponents/vant/dropdown-menu/index.js

@ -1,117 +1,139 @@
import { VantComponent } from '../common/component';
import { useChildren } from '../common/relation';
import { addUnit, getRect, getSystemInfoSync } from '../common/utils';
import {
VantComponent
} from '../common/component';
import {
useChildren
} from '../common/relation';
import {
addUnit,
getRect,
getSystemInfoSync
} from '../common/utils';
let ARRAY = [];
VantComponent({
field: true,
classes: ['title-class'],
relation: useChildren('dropdown-item', function () {
this.updateItemListData();
}),
props: {
activeColor: {
type: String,
observer: 'updateChildrenData',
},
overlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
zIndex: {
type: Number,
value: 10,
},
duration: {
type: Number,
value: 200,
observer: 'updateChildrenData',
},
direction: {
type: String,
value: 'down',
observer: 'updateChildrenData',
},
safeAreaTabBar: {
type: Boolean,
value: false,
},
closeOnClickOverlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
closeOnClickOutside: {
type: Boolean,
value: true,
},
},
data: {
itemListData: [],
},
beforeCreate() {
const { windowHeight } = getSystemInfoSync();
this.windowHeight = windowHeight;
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter((item) => item !== this);
},
methods: {
updateItemListData() {
this.setData({
itemListData: this.children.map((child) => child.data),
});
},
updateChildrenData() {
this.children.forEach((child) => {
child.updateDataFromParent();
});
},
toggleItem(active) {
this.children.forEach((item, index) => {
const { showPopup } = item.data;
if (index === active) {
item.toggle();
}
else if (showPopup) {
item.toggle(false, { immediate: true });
}
});
},
close() {
this.children.forEach((child) => {
child.toggle(false, { immediate: true });
});
},
getChildWrapperStyle() {
const { zIndex, direction } = this.data;
return getRect(this, '.van-dropdown-menu').then((rect) => {
const { top = 0, bottom = 0 } = rect;
const offset = direction === 'down' ? bottom : this.windowHeight - top;
let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`;
}
else {
wrapperStyle += `bottom: ${addUnit(offset)};`;
}
return wrapperStyle;
});
},
onTitleTap(event) {
const { index } = event.currentTarget.dataset;
const child = this.children[index];
if (!child.data.disabled) {
ARRAY.forEach((menuItem) => {
if (menuItem &&
menuItem.data.closeOnClickOutside &&
menuItem !== this) {
menuItem.close();
}
});
this.toggleItem(index);
}
},
},
});
field: true,
classes: ['title-class'],
relation: useChildren('dropdown-item', function() {
this.updateItemListData();
}),
props: {
activeColor: {
type: String,
observer: 'updateChildrenData',
},
overlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
zIndex: {
type: Number,
value: 10,
},
duration: {
type: Number,
value: 200,
observer: 'updateChildrenData',
},
direction: {
type: String,
value: 'down',
observer: 'updateChildrenData',
},
safeAreaTabBar: {
type: Boolean,
value: false,
},
closeOnClickOverlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData',
},
closeOnClickOutside: {
type: Boolean,
value: true,
},
},
data: {
itemListData: [],
currentValue: ''
},
beforeCreate() {
const {
windowHeight
} = getSystemInfoSync();
this.windowHeight = windowHeight;
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter((item) => item !== this);
},
methods: {
updateItemListData() {
this.setData({
itemListData: this.children.map((child) => child.data),
});
},
updateChildrenData() {
this.children.forEach((child) => {
child.updateDataFromParent();
});
},
toggleItem(active) {
this.children.forEach((item, index) => {
const {
showPopup
} = item.data;
if (index === active) {
item.toggle();
} else if (showPopup) {
item.toggle(false, {
immediate: true
});
}
});
},
close() {
this.children.forEach((child) => {
child.toggle(false, {
immediate: true
});
});
},
getChildWrapperStyle() {
const {
zIndex,
direction
} = this.data;
return getRect(this, '.van-dropdown-menu').then((rect) => {
const {
top = 0, bottom = 0
} = rect;
const offset = direction === 'down' ? bottom : this.windowHeight - top;
let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`;
} else {
wrapperStyle += `bottom: ${addUnit(offset)};`;
}
return wrapperStyle;
});
},
onTitleTap(event) {
const {
index
} = event.currentTarget.dataset;
const child = this.children[index];
if (!child.data.disabled) {
ARRAY.forEach((menuItem) => {
if (menuItem &&
menuItem.data.closeOnClickOutside &&
menuItem !== this) {
menuItem.close();
}
});
this.toggleItem(index);
}
},
},
});

3
wxcomponents/vant/dropdown-menu/index.wxml

@ -14,7 +14,8 @@
style="{{ item.showPopup ? 'color:' + activeColor : '' }}"
>
<view class="van-ellipsis">
{{ computed.displayTitle(item) }}
<text class="select-title" style="color:{{computed.setTitleColor(item)}}"> {{ computed.displayTitle(item) }}</text>
<text class='arrow' style="border-color:#17c653"></text>
</view>
</view>
</view>

25
wxcomponents/vant/dropdown-menu/index.wxs

@ -1,16 +1,21 @@
/* eslint-disable */
function displayTitle(item) {
if (item.title) {
return item.title;
}
if (item.title) {
return item.title;
}
var match = item.options.filter(function(option) {
return option.value === item.value;
});
var displayTitle = match.length ? match[0].text : '';
return displayTitle;
var match = item.options.filter(function(option) {
return option.value === item.value;
});
var displayTitle = match.length ? match[0].text : '';
return displayTitle;
}
function setTitleColor(item) {
return item.value != '' ? '#17c653' : ''
}
module.exports = {
displayTitle: displayTitle
};
displayTitle: displayTitle,
setTitleColor: setTitleColor
};

43
wxcomponents/vant/dropdown-menu/index.wxss

@ -33,13 +33,13 @@
box-sizing: border-box;
color: var(--dropdown-menu-title-text-color, #323233);
font-size: var(--dropdown-menu-title-font-size, 15px);
line-height: var(--dropdown-menu-title-line-height, 18px);
max-width: 100%;
padding: var(--dropdown-menu-title-padding, 0 24px 0 8px);
/* line-height: var(--dropdown-menu-title-line-height, 18px); */
width: 100%;
/* padding: var(--dropdown-menu-title-padding, 0 24px 0 8px); */
position: relative;
}
.van-dropdown-menu__title:after {
/* .van-dropdown-menu__title:after {
border-color: transparent transparent currentcolor currentcolor;
border-style: solid;
border-width: 3px;
@ -50,13 +50,42 @@
right: 11px;
top: 50%;
transform: rotate(-45deg)
}
} */
.van-dropdown-menu__title--active {
color: var(--dropdown-menu-title-active-text-color, #ee0a24)
}
.van-dropdown-menu__title--down:after {
.van-ellipsis {
display: flex;
flex: row nowrap;
justify-content: center;
align-items: center;
gap: 4px;
}
.select-title {
font-weight: 600;
transition: .2s all;
}
.van-dropdown-menu__title .arrow {
border-style: solid;
border-color: #000;
border-width: 0 1px 1px 0;
display: inline-block;
padding: 3px;
transform: rotate(45deg) translateY(-30%);
transform-origin: 50% 50%;
transition: .2s all;
}
.van-dropdown-menu__title--down .arrow {
transform: rotate(45deg) rotateZ(180deg) translateY(30%) translate(-4px);
}
/* .van-dropdown-menu__title--down:after {
margin-top: -1px;
transform: rotate(135deg)
}
} */
Loading…
Cancel
Save