pref: 优化日趋筛选

main
liyingang 2 years ago
parent 8cde0764cf
commit 1b5d5a0509
  1. 465
      components/u-view/v-date-picker/index.vue
  2. 124
      components/u-view/v-date-picker/props.js
  3. 266
      components/u-view/v-picker/index.vue
  4. 79
      components/u-view/v-picker/props.js
  5. 4
      manifest.json
  6. 152
      pages/approve/date-search.vue
  7. 6
      pages/approve/index.vue
  8. 7
      pages/governance/index.vue
  9. 3
      pages/investigation/complete.vue
  10. 17
      pages/investigation/index.vue
  11. 4
      pages/logIn/logIn.vue
  12. 19
      pages/mine/password.vue
  13. BIN
      static/time-search.png

@ -0,0 +1,465 @@
<template>
<vPicker ref="picker" :show="show" :closeOnClickOverlay="closeOnClickOverlay" :columns="columns" :title="title"
:itemHeight="itemHeight" :showToolbar="showToolbar" :visibleItemCount="visibleItemCount"
:defaultIndex="innerDefaultIndex" :cancelText="cancelText" :confirmText="confirmText" :cancelColor="cancelColor"
:confirmColor="confirmColor" @close="close" @cancel="cancel" @confirm="confirm" @change="change">
<view class="time-box">
<view :class="{
'time-box-item': true,
'time-box-item-check': dateCheck === 'start'
}" @click="handleCheck('start')">
{{start ? start : '开始时间'}}
<u-icon class="time-box-item-clear" v-show="start" @click="handleClear('start')" size="16"
name="close-circle"></u-icon>
</view>
<view class="date-split">
</view>
<view :class="{
'time-box-item': true,
'time-box-item-check': dateCheck === 'end',
}" @click="handleCheck('end')">
{{end ? end : '结束时间'}}
<u-icon class="time-box-item-clear" v-show="end" @click="handleClear('end')" size="16"
name="close-circle"></u-icon>
</view>
</view>
</vPicker>
</template>
<script>
function times(n, iteratee) {
let index = -1
const result = Array(n < 0 ? 0 : n)
while (++index < n) {
result[index] = iteratee(index)
}
return result
}
import props from './props.js';
import dayjs from '@/uni_modules/uview-ui/libs/util/dayjs.js';
import vPicker from '../v-picker/index.vue'
/**
* DatetimePicker 时间日期选择器
* @description 此选择器用于时间日期
* @tutorial https://www.uviewui.com/components/datetimePicker.html
* @property {Boolean} show 用于控制选择器的弹出与收起 ( 默认 false )
* @property {Boolean} showToolbar 是否显示顶部的操作栏 ( 默认 true )
* @property {String | Number} value 绑定值
* @property {String} title 顶部标题
* @property {String} mode 展示格式 mode=date为日期选择mode=time为时间选择mode=year-month为年月选择mode=datetime为日期时间选择 ( 默认 datetime )
* @property {Number} maxDate 可选的最大时间 默认值为后10年
* @property {Number} minDate 可选的最小时间 默认值为前10年
* @property {Number} minHour 可选的最小小时仅mode=time有效 ( 默认 0 )
* @property {Number} maxHour 可选的最大小时仅mode=time有效 ( 默认 23 )
* @property {Number} minMinute 可选的最小分钟仅mode=time有效 ( 默认 0 )
* @property {Number} maxMinute 可选的最大分钟仅mode=time有效 ( 默认 59 )
* @property {Function} filter 选项过滤函数
* @property {Function} formatter 选项格式化函数
* @property {Boolean} loading 是否显示加载中状态 ( 默认 false )
* @property {String | Number} itemHeight 各列中单个选项的高度 ( 默认 44 )
* @property {String} cancelText 取消按钮的文字 ( 默认 '取消' )
* @property {String} confirmText 确认按钮的文字 ( 默认 '确认' )
* @property {String} cancelColor 取消按钮的颜色 ( 默认 '#909193' )
* @property {String} confirmColor 确认按钮的颜色 ( 默认 '#3c9cff' )
* @property {String | Number} visibleItemCount 每列中可见选项的数量 ( 默认 5 )
* @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭选择器 ( 默认 false )
* @property {Array} defaultIndex 各列的默认索引
* @event {Function} close 关闭选择器时触发
* @event {Function} confirm 点击确定按钮返回当前选择的值
* @event {Function} change 当选择值变化时触发
* @event {Function} cancel 点击取消按钮
* @example <u-datetime-picker :show="show" :value="value1" mode="datetime" ></u-datetime-picker>
*/
export default {
name: 'datetime-picker',
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
components: {
vPicker
},
data() {
return {
columns: [],
innerDefaultIndex: [],
innerFormatter: (type, value) => value,
dateCheck: '',
start: '',
end: ''
}
},
watch: {
show(newValue, oldValue) {
if (newValue) {
this.start = this.startDate
this.end = this.endDate
this.handleCheck('start')
// this.updateColumnValue(this.innerValue)
} else {
this.dateCheck = null
}
},
propsChange() {
this.init()
}
},
computed: {
//
propsChange() {
return [this.mode, this.maxDate, this.minDate, this.minHour, this.maxHour, this.minMinute, this.maxMinute,
this.filter,
]
}
},
mounted() {
// this.init()
// this.handleCheck('startDate')
},
methods: {
handleClear(type) {
this[this.dateCheck] = ''
},
handleCheck(type) {
if (this.dateCheck !== type) {
this.dateCheck = type
if (!this[this.dateCheck]) {
this[this.dateCheck] = dayjs().format('YYYY-MM-DD')
}
this.$nextTick(() => {
this.init()
})
}
},
init() {
this.innerValue = this.correctValue(this[this.dateCheck])
this.updateColumnValue(this.innerValue)
},
// propsref
setFormatter(e) {
this.innerFormatter = e
},
//
close() {
if (this.closeOnClickOverlay) {
this.$emit('close')
}
},
//
cancel() {
this.$emit('cancel')
},
//
confirm() {
if (!this.start && this.end) {
return this.$.toast('请选择开始时间')
}
if (!this.end && this.start) {
return this.$.toast('请选择结束时间')
}
if (this.start && this.end && this.start > this.end) {
return this.$.toast('开始时间不能大于结束时间')
}
this.$emit('confirm-date', [this.start, this.end])
this.$emit('confirm', {
value: this.innerValue,
mode: this.mode
})
this.$emit('input', this.innerValue)
},
//,,
intercept(e, type) {
let judge = e.match(/\d+/g)
//
if (judge.length > 1) {
uni.$u.error("请勿在过滤或格式化函数时添加数字")
return 0
} else if (type && judge[0].length == 4) { //
return judge[0]
} else if (judge[0].length > 2) {
uni.$u.error("请勿在过滤或格式化函数时添加数字")
return 0
} else {
return judge[0]
}
},
//
change(e) {
const {
indexs,
values
} = e
let selectValue = ''
if (this.mode === 'time') {
// value
selectValue = `${this.intercept(values[0][indexs[0]])}:${this.intercept(values[1][indexs[1]])}`
} else {
// '03'3'2019'2019
const year = parseInt(this.intercept(values[0][indexs[0]], 'year'))
const month = parseInt(this.intercept(values[1][indexs[1]]))
let date = parseInt(values[2] ? this.intercept(values[2][indexs[2]]) : 1)
let hour = 0,
minute = 0
//
const maxDate = dayjs(`${year}-${month}`).daysInMonth()
// year-monthdate11
if (this.mode === 'year-month') {
date = 1
}
// maxDate
date = Math.min(maxDate, date)
if (this.mode === 'datetime') {
hour = parseInt(this.intercept(values[3][indexs[3]]))
minute = parseInt(this.intercept(values[4][indexs[4]]))
}
//
selectValue = Number(new Date(year, month - 1, date, hour, minute))
}
//
selectValue = this.correctValue(selectValue)
this.innerValue = selectValue
this.updateColumnValue(selectValue)
// changevalue
this.$emit('change', {
value: selectValue,
// #ifndef MP-WEIXIN
// this
picker: this.$refs.picker,
// #endif
mode: this.mode
})
this[this.dateCheck] = dayjs(selectValue).format('YYYY-MM-DD')
},
// 0
updateColumnValue(value) {
this.innerValue = value
this.updateColumns()
this.updateIndexs(value)
},
//
updateIndexs(value) {
let values = []
const formatter = this.formatter || this.innerFormatter
const padZero = uni.$u.padZero
if (this.mode === 'time') {
// time:
const timeArr = value.split(':')
// 使formatter
values = [formatter('hour', timeArr[0]), formatter('minute', timeArr[1])]
} else {
const date = new Date(value)
values = [
formatter('year', `${dayjs(value).year()}`),
// 0
formatter('month', padZero(dayjs(value).month() + 1))
]
if (this.mode === 'date') {
// date
values.push(formatter('day', padZero(dayjs(value).date())))
}
if (this.mode === 'datetime') {
// push
values.push(formatter('day', padZero(dayjs(value).date())), formatter('hour', padZero(dayjs(value)
.hour())), formatter('minute', padZero(dayjs(value).minute())))
}
}
//
const indexs = this.columns.map((column, index) => {
// -1
return Math.max(0, column.findIndex(item => item === values[index]))
})
this.innerDefaultIndex = indexs
},
//
updateColumns() {
const formatter = this.formatter || this.innerFormatter
// map0
const results = this.getOriginColumns().map((column) => column.values.map((value) => formatter(column.type,
value)))
this.columns = results
},
getOriginColumns() {
//
const results = this.getRanges().map(({
type,
range
}) => {
let values = times(range[1] - range[0] + 1, (index) => {
let value = range[0] + index
value = type === 'year' ? `${value}` : uni.$u.padZero(value)
return value
})
//
if (this.filter) {
values = this.filter(type, values)
}
return {
type,
values
}
})
return results
},
//
generateArray(start, end) {
return Array.from(new Array(end + 1).keys()).slice(start)
},
//
correctValue(value) {
const isDateMode = this.mode !== 'time'
if (isDateMode && !uni.$u.test.date(value)) {
// 使
value = this.minDate
} else if (!isDateMode && !value) {
//
value = `${uni.$u.padZero(this.minHour)}:${uni.$u.padZero(this.minMinute)}`
}
//
if (!isDateMode) {
if (String(value).indexOf(':') === -1) return uni.$u.error('时间错误,请传递如12:24的格式')
let [hour, minute] = value.split(':')
//
hour = uni.$u.padZero(uni.$u.range(this.minHour, this.maxHour, Number(hour)))
minute = uni.$u.padZero(uni.$u.range(this.minMinute, this.maxMinute, Number(minute)))
return `${ hour }:${ minute }`
} else {
//
value = dayjs(value).isBefore(dayjs(this.minDate)) ? this.minDate : value
value = dayjs(value).isAfter(dayjs(this.maxDate)) ? this.maxDate : value
return value
}
},
//
getRanges() {
if (this.mode === 'time') {
return [{
type: 'hour',
range: [this.minHour, this.maxHour],
},
{
type: 'minute',
range: [this.minMinute, this.maxMinute],
},
];
}
const {
maxYear,
maxDate,
maxMonth,
maxHour,
maxMinute,
} = this.getBoundary('max', this.innerValue);
const {
minYear,
minDate,
minMonth,
minHour,
minMinute,
} = this.getBoundary('min', this.innerValue);
const result = [{
type: 'year',
range: [minYear, maxYear],
},
{
type: 'month',
range: [minMonth, maxMonth],
},
{
type: 'day',
range: [minDate, maxDate],
},
{
type: 'hour',
range: [minHour, maxHour],
},
{
type: 'minute',
range: [minMinute, maxMinute],
},
];
if (this.mode === 'date')
result.splice(3, 2);
if (this.mode === 'year-month')
result.splice(2, 3);
return result;
},
// minDatemaxDateminHourmaxHour
getBoundary(type, innerValue) {
const value = new Date(innerValue)
const boundary = new Date(this[`${type}Date`])
const year = dayjs(boundary).year()
let month = 1
let date = 1
let hour = 0
let minute = 0
if (type === 'max') {
month = 12
//
date = dayjs(value).daysInMonth()
hour = 23
minute = 59
}
// ()
if (dayjs(value).year() === year) {
month = dayjs(boundary).month() + 1
if (dayjs(value).month() + 1 === month) {
date = dayjs(boundary).date()
if (dayjs(value).date() === date) {
hour = dayjs(boundary).hour()
if (dayjs(value).hour() === hour) {
minute = dayjs(boundary).minute()
}
}
}
}
return {
[`${type}Year`]: year,
[`${type}Month`]: month,
[`${type}Date`]: date,
[`${type}Hour`]: hour,
[`${type}Minute`]: minute
}
},
},
}
</script>
<style lang="scss" scoped>
@import '@/uni_modules/uview-ui/libs/css/components.scss';
.time-box {
display: flex !important;
align-items: center;
justify-content: space-between;
flex-direction: row;
border-top: 1px solid rgba(230, 230, 230, 1);
padding: 20px 12px;
.date-split {
padding: 0 12px;
}
&-item {
flex: 1;
background: rgba(240, 243, 247, 1);
display: flex;
align-items: center;
justify-content: center;
height: 32px;
border-radius: 4px;
border: 1px solid transparent;
position: relative;
&-check {
background: rgba(38, 99, 191, 0.1);
color: rgba(54, 63, 77, 1);
border: 1px solid #2663BF;
}
&-clear {
position: absolute;
right: 5px;
top: 9px;
z-index: 999;
}
}
}
</style>

@ -0,0 +1,124 @@
export default {
props: {
// 是否打开组件
show: {
type: Boolean,
default: uni.$u.props.datetimePicker.show
},
// 是否展示顶部的操作栏
showToolbar: {
type: Boolean,
default: uni.$u.props.datetimePicker.showToolbar
},
startDate: {
type: [String, Number],
default: uni.$u.props.datetimePicker.value
},
endDate: {
type: [String, Number],
default: uni.$u.props.datetimePicker.value
},
// 绑定值
value: {
type: [String, Number],
default: uni.$u.props.datetimePicker.value
},
// 顶部标题
title: {
type: String,
default: uni.$u.props.datetimePicker.title
},
// 展示格式,mode=date为日期选择,mode=time为时间选择,mode=year-month为年月选择,mode=datetime为日期时间选择
mode: {
type: String,
default: uni.$u.props.datetimePicker.mode
},
// 可选的最大时间
maxDate: {
type: Number,
// 最大默认值为后10年
default: uni.$u.props.datetimePicker.maxDate
},
// 可选的最小时间
minDate: {
type: Number,
// 最小默认值为前10年
default: uni.$u.props.datetimePicker.minDate
},
// 可选的最小小时,仅mode=time有效
minHour: {
type: Number,
default: uni.$u.props.datetimePicker.minHour
},
// 可选的最大小时,仅mode=time有效
maxHour: {
type: Number,
default: uni.$u.props.datetimePicker.maxHour
},
// 可选的最小分钟,仅mode=time有效
minMinute: {
type: Number,
default: uni.$u.props.datetimePicker.minMinute
},
// 可选的最大分钟,仅mode=time有效
maxMinute: {
type: Number,
default: uni.$u.props.datetimePicker.maxMinute
},
// 选项过滤函数
filter: {
type: [Function, null],
default: uni.$u.props.datetimePicker.filter
},
// 选项格式化函数
formatter: {
type: [Function, null],
default: uni.$u.props.datetimePicker.formatter
},
// 是否显示加载中状态
loading: {
type: Boolean,
default: uni.$u.props.datetimePicker.loading
},
// 各列中,单个选项的高度
itemHeight: {
type: [String, Number],
default: uni.$u.props.datetimePicker.itemHeight
},
// 取消按钮的文字
cancelText: {
type: String,
default: uni.$u.props.datetimePicker.cancelText
},
// 确认按钮的文字
confirmText: {
type: String,
default: uni.$u.props.datetimePicker.confirmText
},
// 取消按钮的颜色
cancelColor: {
type: String,
default: uni.$u.props.datetimePicker.cancelColor
},
// 确认按钮的颜色
confirmColor: {
type: String,
default: uni.$u.props.datetimePicker.confirmColor
},
// 每列中可见选项的数量
visibleItemCount: {
type: [String, Number],
default: uni.$u.props.datetimePicker.visibleItemCount
},
// 是否允许点击遮罩关闭选择器
closeOnClickOverlay: {
type: Boolean,
default: uni.$u.props.datetimePicker.closeOnClickOverlay
},
// 各列的默认索引
defaultIndex: {
type: Array,
default: uni.$u.props.datetimePicker.defaultIndex
}
}
}

@ -0,0 +1,266 @@
<template>
<u-popup :show="show" @close="closeHandler">
<view class="u-picker">
<u-toolbar class="v-toolbar" v-if="showToolbar" :cancelColor="cancelColor" :confirmColor="confirmColor"
:cancelText="cancelText" :confirmText="confirmText" :title="title" @cancel="cancel"
@confirm="confirm"></u-toolbar>
<slot></slot>
<picker-view class="u-picker__view" :indicatorStyle="`height: ${$u.addUnit(itemHeight)}`"
:value="innerIndex" :immediateChange="immediateChange" :style="{
height: `${$u.addUnit(visibleItemCount * itemHeight)}`
}" @change="changeHandler">
<picker-view-column v-for="(item, index) in innerColumns" :key="index" class="u-picker__view__column">
<text v-if="$u.test.array(item)" class="u-picker__view__column__item u-line-1"
v-for="(item1, index1) in item" :key="index1" :style="{
height: $u.addUnit(itemHeight),
lineHeight: $u.addUnit(itemHeight),
fontWeight: index1 === innerIndex[index] ? 'bold' : 'normal'
}">{{ getItemText(item1) }}</text>
</picker-view-column>
</picker-view>
<view v-if="loading" class="u-picker--loading">
<u-loading-icon mode="circle"></u-loading-icon>
</view>
</view>
</u-popup>
</template>
<script>
/**
* u-picker
* @description 选择器
* @property {Boolean} show 是否显示picker弹窗默认 false
* @property {Boolean} showToolbar 是否显示顶部的操作栏默认 true
* @property {String} title 顶部标题
* @property {Array} columns 对象数组设置每一列的数据
* @property {Boolean} loading 是否显示加载中状态默认 false
* @property {String | Number} itemHeight 各列中单个选项的高度默认 44
* @property {String} cancelText 取消按钮的文字默认 '取消'
* @property {String} confirmText 确认按钮的文字默认 '确定'
* @property {String} cancelColor 取消按钮的颜色默认 '#909193'
* @property {String} confirmColor 确认按钮的颜色默认 '#3c9cff'
* @property {String | Number} visibleItemCount 每列中可见选项的数量默认 5
* @property {String} keyName 选项对象中需要展示的属性键名默认 'text'
* @property {Boolean} closeOnClickOverlay 是否允许点击遮罩关闭选择器默认 false
* @property {Array} defaultIndex 各列的默认索引
* @property {Boolean} immediateChange 是否在手指松开时立即触发change事件默认 false
* @event {Function} close 关闭选择器时触发
* @event {Function} cancel 点击取消按钮触发
* @event {Function} change 当选择值变化时触发
* @event {Function} confirm 点击确定按钮返回当前选择的值
*/
import props from './props.js';
export default {
name: 'u-picker',
mixins: [uni.$u.mpMixin, uni.$u.mixin, props],
data() {
return {
//
lastIndex: [],
// picker-viewvalue
innerIndex: [],
//
innerColumns: [],
//
columnIndex: 0
}
},
watch: {
//
defaultIndex: {
immediate: true,
handler(n) {
this.setIndexs(n, true)
}
},
// columns
columns: {
immediate: true,
handler(n) {
this.setColumns(n)
}
},
},
methods: {
// item
getItemText(item) {
if (uni.$u.test.object(item)) {
return item[this.keyName]
} else {
return item
}
},
//
closeHandler() {
if (this.closeOnClickOverlay) {
this.$emit('close')
}
},
//
cancel() {
this.$emit('cancel')
},
//
confirm() {
this.$emit('confirm', {
indexs: this.innerIndex,
value: this.innerColumns.map((item, index) => item[this.innerIndex[index]]),
values: this.innerColumns
})
},
//
changeHandler(e) {
const {
value
} = e.detail
let index = 0,
columnIndex = 0
//
for (let i = 0; i < value.length; i++) {
let item = value[i]
if (item !== (this.lastIndex[i] || 0)) { // undefined0
// columnIndex
columnIndex = i
// index
index = item
break // 使
}
}
this.columnIndex = columnIndex
const values = this.innerColumns
// ""
this.setLastIndex(value)
this.setIndexs(value)
this.$emit('change', {
// #ifndef MP-WEIXIN || MP-LARK
// this
picker: this,
// #endif
value: this.innerColumns.map((item, index) => item[value[index]]),
index,
indexs: value,
// values
values,
columnIndex
})
},
// index
setIndexs(index, setLastIndex) {
this.innerIndex = uni.$u.deepClone(index)
if (setLastIndex) {
this.setLastIndex(index)
}
},
//
setLastIndex(index) {
// changeHandler
//
this.lastIndex = uni.$u.deepClone(index)
},
//
setColumnValues(columnIndex, values) {
// innerColumnscolumnIndexvalues使splice
this.innerColumns.splice(columnIndex, 1, values)
// innerIndex0
let tmpIndex = uni.$u.deepClone(this.innerIndex)
for (let i = 0; i < this.innerColumns.length; i++) {
if (i > this.columnIndex) {
tmpIndex[i] = 0
}
}
//
this.setIndexs(tmpIndex)
},
//
getColumnValues(columnIndex) {
// changesetColumnValues
// changegetColumnValues
(async () => {
await uni.$u.sleep()
})()
return this.innerColumns[columnIndex]
},
// columns
setColumns(columns) {
this.innerColumns = uni.$u.deepClone(columns)
// defaultIndex0
if (this.innerIndex.length === 0) {
this.innerIndex = new Array(columns.length).fill(0)
}
},
//
getIndexs() {
return this.innerIndex
},
//
getValues() {
// changesetColumnValues
// changegetValues
(async () => {
await uni.$u.sleep()
})()
return this.innerColumns.map((item, index) => item[this.innerIndex[index]])
}
},
}
</script>
<style lang="scss" scoped>
@import "@/uni_modules/uview-ui/libs/css/components.scss";
.v-toolbar {
/deep/ .u-toolbar__title {
font-weight: bold !important;
color: rgba(54, 63, 77, 1);
}
}
.u-picker {
position: relative;
&__view {
&__column {
@include flex;
flex: 1;
justify-content: center;
&__item {
@include flex;
justify-content: center;
align-items: center;
font-size: 16px;
text-align: center;
/* #ifndef APP-NVUE */
display: block;
/* #endif */
color: $u-main-color;
&--disabled {
/* #ifndef APP-NVUE */
cursor: not-allowed;
/* #endif */
opacity: 0.35;
}
}
}
}
&--loading {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
@include flex;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.87);
z-index: 1000;
}
}
</style>

@ -0,0 +1,79 @@
export default {
props: {
// 是否展示picker弹窗
show: {
type: Boolean,
default: uni.$u.props.picker.show
},
// 是否展示顶部的操作栏
showToolbar: {
type: Boolean,
default: uni.$u.props.picker.showToolbar
},
// 顶部标题
title: {
type: String,
default: uni.$u.props.picker.title
},
// 对象数组,设置每一列的数据
columns: {
type: Array,
default: uni.$u.props.picker.columns
},
// 是否显示加载中状态
loading: {
type: Boolean,
default: uni.$u.props.picker.loading
},
// 各列中,单个选项的高度
itemHeight: {
type: [String, Number],
default: uni.$u.props.picker.itemHeight
},
// 取消按钮的文字
cancelText: {
type: String,
default: uni.$u.props.picker.cancelText
},
// 确认按钮的文字
confirmText: {
type: String,
default: uni.$u.props.picker.confirmText
},
// 取消按钮的颜色
cancelColor: {
type: String,
default: uni.$u.props.picker.cancelColor
},
// 确认按钮的颜色
confirmColor: {
type: String,
default: uni.$u.props.picker.confirmColor
},
// 每列中可见选项的数量
visibleItemCount: {
type: [String, Number],
default: uni.$u.props.picker.visibleItemCount
},
// 选项对象中,需要展示的属性键名
keyName: {
type: String,
default: uni.$u.props.picker.keyName
},
// 是否允许点击遮罩关闭选择器
closeOnClickOverlay: {
type: Boolean,
default: uni.$u.props.picker.closeOnClickOverlay
},
// 各列的默认索引
defaultIndex: {
type: Array,
default: uni.$u.props.picker.defaultIndex
},
// 是否在手指松开时立即触发 change 事件。若不开启则会在滚动动画结束后触发 change 事件,只在微信2.21.1及以上有效
immediateChange: {
type: Boolean,
default: uni.$u.props.picker.immediateChange
}
}
}

@ -2,8 +2,8 @@
"name" : "隐患排查",
"appid" : "__UNI__F12FECC",
"description" : "",
"versionName" : "1.0.1.3",
"versionCode" : 1013,
"versionName" : "1.0.1.4",
"versionCode" : 1014,
"transformPx" : false,
/* 5+App */
"app-plus" : {

@ -1,36 +1,45 @@
<template>
<view class="">
<view class="date-content">
<view class="date-item">
<view class="date-item-label">
开始时间
<view class="search-content">
<view class="search-box">
<view class="tab-content">
<view :class="{
'tab-item': true,
'tab-item-active': tabActive == item.active
}" v-for="(item, index) in tabList" :key="item.active" @click="handleClick(item.active)">
{{item.name}}
</view>
<view class="date-item-value" @click="handleOpen('startShow')">
{{startDate || '请选择'}}
</view>
<u-icon v-show="startDate" @click="handleClear('start')" size="16" name="close-circle"></u-icon>
</view>
<view class="date-item">
<view class="date-item-label">
结束时间
</view>
<view class="date-item-value" @click="handleOpen('endShow')">
{{endDate || '请选择'}}
</view>
<u-icon v-show="endDate" @click="handleClear('end')" size="16" name="close-circle"></u-icon>
<view class="date-btn" @click="handleOpenDate">
时间
<image class="date-btn-icon" src="/static/time-search.png" mode=""></image>
</view>
</view>
<u-datetime-picker :show="startShow" title="开始时间" :value="start" mode="date" @cancel="startShow = false"
@confirm="changeDate.call(this,$event, 'startDate')" :max-date="getCurTimeForX()"></u-datetime-picker>
<u-datetime-picker :show="endShow" title="结束时间" :value="end" mode="date" @cancel="endShow = false"
@confirm="changeDate.call(this,$event, 'endDate')" :max-date="getCurTimeForX()"></u-datetime-picker>
<view class="">
<VdatePicker :show="timeShow" :formatter="formatter" title="时间选择" :visibleItemCount="3"
:startDate.sync="start" :endDate.sync="end" mode="date" @cancel="timeShow = false"
@confirm-date="changeDate" :min-date="getMinTimeForX()" :max-date="getCurTimeForX()">
</VdatePicker>
</view>
</view>
</template>
<script>
import VdatePicker from '@/components/u-view/v-date-picker/index.vue'
export default {
name: 'date-search',
components: {
VdatePicker
},
props: {
tabList: {
type: Array,
default: () => ([])
},
tabActive: {
type: [Number, String],
default: 0
},
startDate: {
type: String,
default: ''
@ -43,7 +52,7 @@
computed: {
start: {
get() {
return this.startDate || this.formatTime(this.$moment().subtract(7, 'd'))
return this.startDate
},
set(value) {
this.$emit('update:startDate', value)
@ -51,7 +60,7 @@
},
end: {
get() {
return this.endDate || this.formatTime()
return this.endDate
},
set(value) {
this.$emit('update:endDate', value)
@ -60,14 +69,36 @@
},
data() {
return {
startShow: false,
endShow: false
timeShow: false,
}
},
methods: {
formatter(type, value) {
if (type === 'year') {
return `${value}`
}
if (type === 'month') {
return `${value}`
}
if (type === 'day') {
return `${value}`
}
return value
},
handleClick(active) {
if (this.tabActive != active) {
this.$emit('tabChange', active)
}
},
handleOpenDate() {
this.timeShow = true
},
getCurTimeForX() {
return (new Date()).getTime()
},
getMinTimeForX() {
return this.$moment('2021-01-01').valueOf()
},
formatTime(time) {
return this.$moment(time).format('YYYY-MM-DD')
},
@ -84,53 +115,58 @@
}
})
},
changeDate(dateEvent, key) {
if (key === 'startDate') {
if (this.endDate && this.endDate < this.formatTime(dateEvent.value)) {
this.$.toast('开始时间不能大于结束时间')
return
} else {
this.start = this.formatTime(dateEvent.value)
}
} else {
if (this.startDate && this.startDate > this.formatTime(dateEvent.value)) {
this.$.toast('结束时间不能小于开始时间')
return
} else {
this.end = this.formatTime(dateEvent.value)
}
}
this.startShow = false
this.endShow = false
changeDate(timeArr) {
const [start, end] = timeArr
this.start = start
this.end = end
this.timeShow = false
this.$nextTick(() => {
if (this.endDate && this.startDate) {
this.$emit('handleSearch')
}
this.$emit('handleSearch')
})
},
}
}
</script>
<style lang="scss">
.date-content {
display: flex;
align-items: center;
padding: 10px 10px;
justify-content: space-between;
.search-content {
padding-top: 12px;
font-size: 14px;
.search-box {
display: flex;
align-items: center;
justify-content: space-between;
height: 27px;
}
.date-item {
.tab-content {
display: flex;
align-items: center;
&-label {
margin-right: 3px;
.tab-item {
border-radius: 4px;
padding: 4px 10px;
background: rgba(208, 222, 245, 1);
margin-right: 12px;
color: rgba(54, 63, 77, 1);
&-active {
background: rgba(60, 109, 196, 1);
color: rgba(255, 255, 255, 1);
}
}
}
.date-btn {
display: flex;
align-items: center;
&-value {
width: 185rpx;
text-align: right;
margin-right: 2px;
&-icon {
width: 16px;
height: 16px;
margin-left: 5px;
}
}
}

@ -9,7 +9,7 @@
</template> -->
</top-title>
</view>
<view class="query-form" :class="approve==2?'query-form2':''">
<view class="query-form">
<view class="search-box">
<u-search placeholder="请输入名称" v-model="searchValue" actionText="" :showAction="false"
@search="handleSearch" @clear="handleSearch"></u-search>
@ -23,8 +23,6 @@
<text class="number">{{tabItem.number}}</text>
</view>
</view>
<dateSearch :startDate.sync="startDate" :endDate.sync="endDate" @handleSearch="handleSearch"
v-if="approve == 2" />
<!-- <view class="type-box" v-show="approve==2">
<view v-for="item in tabTypeList" :key="item.active" :class="{
'type-item': true,
@ -35,6 +33,8 @@
</view> -->
</view>
<view class="Content MarginAuto BorderBox">
<dateSearch :showTab="false" :startDate.sync="startDate" :endDate.sync="endDate"
@handleSearch="handleSearch" v-if="approve == 2" />
<no-data v-if="isEmpty" />
<view v-else class="List Width100 BorderBox">
<view class="Unit FontBold BorderBox Width100 MarginT_30rpx BG_FFFFFF" v-for="item in list"

@ -9,7 +9,7 @@
</template> -->
</top-title>
</view>
<view class="query-form" :class="approve==2?'query-form2':''">
<view class="query-form">
<view class="search-box">
<u-search placeholder="请输入名称" v-model="searchValue" actionText="" :showAction="false"
@search="handleSearch" @clear="handleSearch"></u-search>
@ -31,10 +31,11 @@
{{item.name}}
</view>
</view> -->
<dateSearch :startDate.sync="startDate" :endDate.sync="endDate" @handleSearch="handleSearch"
v-if="approve == 2" />
</view>
<view class="Content MarginAuto BorderBox">
<dateSearch :showTab="false" :startDate.sync="startDate" :endDate.sync="endDate"
@handleSearch="handleSearch" v-if="approve == 2" />
<no-data v-if="isEmpty" />
<view v-else class="List Width100 BorderBox">
<view class="Unit FontBold BorderBox Width100 MarginT_30rpx BG_FFFFFF" v-for="item in list"

@ -677,8 +677,7 @@
console.log('this.checked', this.checked, index)
if (this.checked.length - 1 == index) {
// alert(1111)
this.initCheckedSelect(index)
// this.initCheckedSelect(index)
}
});

@ -11,7 +11,7 @@
</template>
</top-title>
</view>
<view class="query-form" :class="approve==2?'query-form2':''">
<view class="query-form">
<view class="search-box">
<u-search placeholder="请输入名称" v-model="searchValue" actionText="" :showAction="false"
@search="handleSearch" @clear="handleSearch"></u-search>
@ -25,18 +25,11 @@
<text class="number">{{tabItem.number}}</text>
</view>
</view>
<view class="type-box" v-show="approve==2">
<view v-for="item in tabTypeList" :key="item.active" :class="{
'type-item': true,
'type-active': classification == item.active
}" @click="queryTypeChange(item.active)">
{{item.name}}
</view>
</view>
<dateSearch :startDate.sync="startDate" :endDate.sync="endDate" @handleSearch="handleSearch"
v-if="approve == 2" />
</view>
<view class="Content MarginAuto BorderBox">
<dateSearch :tabList="tabTypeList" :tabActive="classification" :startDate.sync="startDate"
:endDate.sync="endDate" @handleSearch="handleSearch" v-if="approve == 2"
@tabChange="queryTypeChange" />
<no-data v-if="isEmpty" />
<view v-else class="List Width100 BorderBox">
<view class="Unit FontBold BorderBox Width100 MarginT_30rpx BG_FFFFFF" v-for="(item,index) in list"
@ -358,7 +351,7 @@
}
.query-form {
width: 100%;
font-size: 16px;
height: 91px;
background: #ffffff;

@ -262,8 +262,10 @@
// #endif
this.$.setData('isAgree', true)
this.$.setData('appVersion', myAppVersion)
const sessionIdStr = `${res.result.nuserid}-${(new Date()).getTime()}`
const timestamp = (new Date()).getTime()
const sessionIdStr = `${res.result.nuserid}-${timestamp}`
const sessionId = sha512(sessionIdStr)
this.$.setData('timestamp', timestamp)
this.$.setData('sessionId', sessionId)
setTimeout(() => {
this.$.hideLoading('登录中...')

@ -21,9 +21,9 @@
<!-- <u-icon size="20" name="eye-off" v-if="isPassword" @click.native="isPassword=!isPassword" style="position: absolute;right: 30rpx;"></u-icon>
<u-icon size="20" name="eye-fill" v-else @click.native="isPassword=!isPassword" style="position: absolute;right: 30rpx;"></u-icon> -->
</u-form-item>
<text class="tip"> 密码需要包含数字大小写字母特殊符号中3种以上组合</text>
<text class="tip"> 密码需要包含数字大小写字母特殊符号中3种以上组合</text>
</u--form>
<view @click="submit"
class="Unit FontBold BorderBox TextCenter Width100 MarginT_30rpx BorderR_30rpx submit">
提交
@ -108,7 +108,7 @@
submit() {
if (!this.form.password) {
this.$.toast('请输入密码')
} else if(!this.isValidPassword(this.form.password)){
} else if (!this.isValidPassword(this.form.password)) {
this.$.toast('密码格式不正确')
} else if (this.form.password != this.form.confirmPassword) {
this.$.toast('两次密码不一致')
@ -119,6 +119,8 @@
cusername: this.$.getData('userInfo').username,
nuserid: this.$.getData("token"),
nuserpwd: this.form.password,
sessionId: this.$.getData("sessionId"),
timestamp: this.$.getData("timestamp")
},
"POST",
true
@ -167,11 +169,12 @@
.form {
width: 690rpx;
}
.tip{
font-size:24rpx;
top:10rpx;
position:relative;
color:#e01515;
.tip {
font-size: 24rpx;
top: 10rpx;
position: relative;
color: #e01515;
}
/deep/ .u-form-item__body {

Binary file not shown.

After

Width:  |  Height:  |  Size: 594 B

Loading…
Cancel
Save