firstcommit
This commit is contained in:
commit
966e6449d1
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/node_modules
|
||||||
|
/unpackage
|
27
.hbuilderx/launch.json
Normal file
27
.hbuilderx/launch.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
// launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||||
|
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||||
|
"version" : "0.0",
|
||||||
|
"configurations" : [
|
||||||
|
{
|
||||||
|
"app-plus" : {
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"default" : {
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"mp-weixin" : {
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"type" : "uniCloud"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"playground" : "custom",
|
||||||
|
"type" : "uni-app:app-android"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"playground" : "custom",
|
||||||
|
"type" : "uni-app:app-ios"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
28
App.vue
Normal file
28
App.vue
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
onLaunch: function () {
|
||||||
|
console.log("App onLaunch");
|
||||||
|
},
|
||||||
|
ononReady: function () {
|
||||||
|
console.log("App Ready");
|
||||||
|
},
|
||||||
|
onShow: function () {
|
||||||
|
|
||||||
|
},
|
||||||
|
onHide: function () {
|
||||||
|
console.log("App Hide");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* 引入的uview-ui的index.scss放第一行引入 */
|
||||||
|
@import "uview-ui/index.scss";
|
||||||
|
@import "common/index.scss";
|
||||||
|
/*每个页面公共css */
|
||||||
|
page {
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-attachment: fixed;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
</style>
|
125
common/index.js
Normal file
125
common/index.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* 通用消息框
|
||||||
|
* @param content string 消息内容
|
||||||
|
* @param fn function 回调
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
import api from "@/http/";
|
||||||
|
import apiUrl from "../http/api.js";
|
||||||
|
const msgToast = (content, fn, type = "none") => {
|
||||||
|
uni.showToast({
|
||||||
|
title: content,
|
||||||
|
duration: 2000,
|
||||||
|
icon: type,
|
||||||
|
success: fn
|
||||||
|
? () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
fn();
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
: function () {},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 手机号验证 */
|
||||||
|
const vefTel = (key) => {
|
||||||
|
let reg_tel =
|
||||||
|
/^1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$/;
|
||||||
|
///^(((13[0-9]{1})|(15[0-9]{1})|(16[0-9]{1})|(17[3-8]{1})|(18[0-9]{1})|(19[0-9]{1})|(14[5-7]{1}))+\d{8})$/; // 11位手机号
|
||||||
|
if (key === "" || key === undefined || key === null) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "请输入手机号",
|
||||||
|
duration: 2000,
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} else if (!reg_tel.test(key)) {
|
||||||
|
uni.showToast({
|
||||||
|
title: "手机号码格式不正确",
|
||||||
|
duration: 2000,
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* 非空验证 */
|
||||||
|
const vefEmpty = (key, msg) => {
|
||||||
|
if (key === "" || key === undefined || key === null) {
|
||||||
|
uni.showToast({
|
||||||
|
title: msg,
|
||||||
|
duration: 2000,
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const logout = () => {
|
||||||
|
msgToast("登录已过期,请重新登录", () => {
|
||||||
|
uni.removeStorageSync("userInfo");
|
||||||
|
uni.redirectTo({
|
||||||
|
url: "../login/login",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @description: H5 App通用方案 解决H5刷新返回失败问题
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
const navigateBack = (params) => {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
if (pages.length === 1) {
|
||||||
|
if (typeof params === "number") {
|
||||||
|
history.go(-params);
|
||||||
|
} else {
|
||||||
|
history.back();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @description: 获取url参数
|
||||||
|
* @param {*} params
|
||||||
|
*/
|
||||||
|
const getLocationParams = (name) => {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
const curPage = pages[pages.length - 1];
|
||||||
|
return name ? curPage.options[name] : curPage.options;
|
||||||
|
};
|
||||||
|
const getOpenId = async () => {
|
||||||
|
const res = await api.request("/api/appointment/wx/info", null, "GET");
|
||||||
|
console.log(res);
|
||||||
|
if (res.status === 0) {
|
||||||
|
uni.setStorageSync("open_id", res.data.wxUser.openID);
|
||||||
|
} else {
|
||||||
|
console.log("没有open_id");
|
||||||
|
if (!document.cookie) {
|
||||||
|
console.log("没有cookie");
|
||||||
|
// 设置cookie
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.href = `${
|
||||||
|
apiUrl.backUrl
|
||||||
|
}/api/appointment/wx?notifyUrl=${encodeURIComponent(
|
||||||
|
window.location.href
|
||||||
|
)}`;
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
msgToast,
|
||||||
|
vefTel,
|
||||||
|
vefEmpty,
|
||||||
|
logout,
|
||||||
|
navigateBack,
|
||||||
|
getLocationParams,
|
||||||
|
getOpenId,
|
||||||
|
};
|
1248
common/index.scss
Normal file
1248
common/index.scss
Normal file
File diff suppressed because it is too large
Load Diff
416
components/inputSelect/inputSelect.vue
Normal file
416
components/inputSelect/inputSelect.vue
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
<template>
|
||||||
|
<view class="superwei-combox" :class="border ? '' : 'superwei-combox__no-border'">
|
||||||
|
<view v-if="label" class="superwei-combox__label" :style="labelStyle">
|
||||||
|
<text>{{label}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="superwei-combox__input-box">
|
||||||
|
<input class="superwei-combox__input" type="text" :placeholder="placeholder"
|
||||||
|
placeholder-class="superwei-combox__input-plac" v-model="inputVal" @input="onInput" @focus="onFocus"
|
||||||
|
@blur="onBlur" />
|
||||||
|
<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" @click="toggleSelector" v-if="!inputVal"></uni-icons>
|
||||||
|
<image src="@/static/image/close-icon.png" mode="" style="width: 28upx;height: 28upx;" v-if="inputVal" @click="clear"></image>
|
||||||
|
</view>
|
||||||
|
<view class="superwei-combox__selector" v-if="showSelector">
|
||||||
|
<view class="uni-popper__arrow"></view>
|
||||||
|
<scroll-view scroll-y="true" class="superwei-combox__selector-scroll">
|
||||||
|
<view class="superwei-combox__selector-empty" v-if="filterCandidatesLength === 0">
|
||||||
|
<text>{{emptyTips}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="superwei-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index">
|
||||||
|
<template v-if="(isJSON?(item.disabled?true:false):false)">
|
||||||
|
<text
|
||||||
|
:style="'color:'+disabledColor+';cursor: not-allowed;'">{{isJSON?item[keyName]?item[keyName]:'字段'+keyName+'不存在':item}}</text>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<text @click="onSelectorClick(index)"
|
||||||
|
:style="(isJSON?item[keyName]?item[keyName]==inputVal:false:item==inputVal)?'font-weight: bold;background-color: '+selectedBackground+';color: '+selectedColor:''">{{isJSON?item[keyName]?item[keyName]:'字段'+keyName+'不存在':item}}</text>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- <view class="search-combox">
|
||||||
|
<view class="uni-combox__input-box" :style="showSelector ?'z-index: 997;': ''">
|
||||||
|
<input class="uni-combox__input" type="text" :placeholder="placeholder" placeholder-class="uni-combox__input-plac"
|
||||||
|
v-model="inputVal" @input="onInput" @focus="onFocus" @blur="onBlur" />
|
||||||
|
<view class="icon-box">
|
||||||
|
<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#fff" @click="toggleSelector" v-if="!inputVal && icon=='icon'"></uni-icons>
|
||||||
|
<image src="@/static/image/order/search.png" mode="" style="width: 28upx;height: 28upx;" v-if="iconShow && icon =='search'" @click="searchGet"></image>
|
||||||
|
<image src="@/static/image/close-icon.png" mode="" style="width: 28upx;height: 28upx;" v-if="inputVal" @click="clear"></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="uni-combox__selector" v-if="showSelector">
|
||||||
|
<view class="uni-popper__arrow"></view>
|
||||||
|
<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
|
||||||
|
<view class="uni-combox__selector-empty" v-if="searchList.length == 0">
|
||||||
|
<text>{{emptyTips}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-combox__selector-item" v-for="(item,index) in searchList" :key="index" @click="onSelectorClick(index)">
|
||||||
|
<text>{{item.value}}</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Combox 组合输入框
|
||||||
|
* @description 组合输入框一般用于既可以输入也可以选择的场景
|
||||||
|
* @property {String} label 左侧文字
|
||||||
|
* @property {String} labelWidth 左侧内容宽度
|
||||||
|
* @property {String} placeholder 输入框占位符
|
||||||
|
* @property {Array} candidates 候选项列表
|
||||||
|
* @property {String} emptyTips 筛选结果为空时显示的文字
|
||||||
|
* @property {String} value 组合框的值
|
||||||
|
* @property {String} selectedBackground 选中项背景颜色
|
||||||
|
* @property {String} selectedColor 选中项文字颜色
|
||||||
|
* @property {Boolean} isJSON 是否是json数组
|
||||||
|
* @property {String} keyName json数组显示的字段值
|
||||||
|
* @property {String} disabledColor 禁用项文字颜色
|
||||||
|
* @property {Boolean} isAllowCreate 是否允许用户创建新条目
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name:"inputSelect",
|
||||||
|
emits: ['input', 'update:modelValue', 'select'],
|
||||||
|
props: {
|
||||||
|
isAllowCreate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
disabledColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#ababac'
|
||||||
|
},
|
||||||
|
isJSON: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
keyName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
selectedBackground: {
|
||||||
|
type: String,
|
||||||
|
default: '#f5f7fa'
|
||||||
|
},
|
||||||
|
selectedColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#409eff'
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: String,
|
||||||
|
default: 'auto'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
candidates: {
|
||||||
|
type: Array,
|
||||||
|
default () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emptyTips: {
|
||||||
|
type: String,
|
||||||
|
default: '无匹配项'
|
||||||
|
},
|
||||||
|
// #ifndef VUE3
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isInput: false,
|
||||||
|
showSelector: false,
|
||||||
|
isSelector: false,
|
||||||
|
inputVal: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
labelStyle() {
|
||||||
|
if (this.labelWidth === 'auto') {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return `width: ${this.labelWidth}`
|
||||||
|
},
|
||||||
|
filterCandidates() {
|
||||||
|
if (this.isInput) {
|
||||||
|
if (this.isJSON) {
|
||||||
|
return this.candidates.filter((item) => {
|
||||||
|
return item[this.keyName].toString().indexOf(this.inputVal) > -1
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return this.candidates.filter((item) => {
|
||||||
|
return item.toString().indexOf(this.inputVal) > -1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this.candidates
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterCandidatesLength() {
|
||||||
|
return this.filterCandidates.length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// #ifndef VUE3
|
||||||
|
value: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.inputVal = newVal
|
||||||
|
this.isInput = true
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.inputVal = newVal
|
||||||
|
this.isInput = true
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleSelector() {
|
||||||
|
this.showSelector = !this.showSelector
|
||||||
|
this.isInput = false
|
||||||
|
},
|
||||||
|
onFocus() {
|
||||||
|
this.showSelector = true
|
||||||
|
this.isInput = false
|
||||||
|
},
|
||||||
|
onChange() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showSelector = false
|
||||||
|
this.isInput = false
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
|
onBlur() {
|
||||||
|
if (!this.isInput) {
|
||||||
|
this.onChange()
|
||||||
|
} else {
|
||||||
|
if (this.inputVal && !this.isAllowCreate) {
|
||||||
|
let index = this.candidates.findIndex((item) => {
|
||||||
|
if (this.isJSON) {
|
||||||
|
return item[this.keyName].toString() == this.inputVal && !item.disabled
|
||||||
|
} else {
|
||||||
|
return item.toString() == this.inputVal
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (index == -1) {
|
||||||
|
if (this.filterCandidatesLength > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showSelector = false
|
||||||
|
this.isInput = false
|
||||||
|
if (!this.isSelector) {
|
||||||
|
this.inputVal = ''
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
}
|
||||||
|
}, 200)
|
||||||
|
this.isSelector = false
|
||||||
|
} else {
|
||||||
|
this.showSelector = false
|
||||||
|
this.isInput = false
|
||||||
|
this.inputVal = ''
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelectorClick(index) {
|
||||||
|
let item = this.filterCandidates[index]
|
||||||
|
if (this.isJSON) {
|
||||||
|
this.inputVal = item[this.keyName]
|
||||||
|
} else {
|
||||||
|
this.inputVal = item
|
||||||
|
}
|
||||||
|
this.showSelector = false
|
||||||
|
this.isSelector = true
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
this.$emit('select', item)
|
||||||
|
},
|
||||||
|
onInput() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
searchGet() {
|
||||||
|
this.iconShow = false
|
||||||
|
this.$emit('search',true)
|
||||||
|
},
|
||||||
|
clear() {
|
||||||
|
this.inputVal = '';
|
||||||
|
this.iconShow = true;
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
this.$emit('select', {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.superwei-combox {
|
||||||
|
font-size: 24upx;
|
||||||
|
// border: 1px solid #DCDFE6;
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
// height: 40px;
|
||||||
|
flex-direction: row;
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 32upx;
|
||||||
|
height: 60upx;
|
||||||
|
padding: 0 20upx;
|
||||||
|
background: #FFFFFF;
|
||||||
|
z-index: 99999999999;
|
||||||
|
// border-bottom: solid 1px #DDDDDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__label {
|
||||||
|
font-size: 24upx;
|
||||||
|
line-height: 22px;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__input-box {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 24upx;
|
||||||
|
height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__input-plac {
|
||||||
|
font-size: 24upx;
|
||||||
|
color: #ccc; //placeholder-style="color:#FFFFFF"
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 12px);
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 2;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-scroll {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
max-height: 200px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-empty,
|
||||||
|
.superwei-combox__selector-item {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
line-height: 36px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
// border-bottom: solid 1px #DDDDDD;
|
||||||
|
padding: 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-empty text,
|
||||||
|
.superwei-combox__selector-item text {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-item:hover {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-empty:last-child,
|
||||||
|
.superwei-combox__selector-item:last-child {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
border-bottom: none;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
// picker 弹出层通用的指示小三角
|
||||||
|
.uni-popper__arrow,
|
||||||
|
.uni-popper__arrow::after {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-color: transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popper__arrow {
|
||||||
|
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
|
||||||
|
top: -6px;
|
||||||
|
left: 10%;
|
||||||
|
margin-right: 3px;
|
||||||
|
border-top-width: 0;
|
||||||
|
border-bottom-color: #EBEEF5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popper__arrow::after {
|
||||||
|
content: " ";
|
||||||
|
top: 1px;
|
||||||
|
margin-left: -6px;
|
||||||
|
border-top-width: 0;
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__no-border {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
113
components/navBar/navBar.vue
Normal file
113
components/navBar/navBar.vue
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="status_bar">
|
||||||
|
<!-- 这里是状态栏 -->
|
||||||
|
</view>
|
||||||
|
<view style="height: 86upx">
|
||||||
|
<u-sticky offset-top="0" v-if="stickyShow">
|
||||||
|
<u-navbar
|
||||||
|
:is-back="false"
|
||||||
|
:title="navTitle"
|
||||||
|
:bgColor="background"
|
||||||
|
:titleStyle="titleStyle"
|
||||||
|
>
|
||||||
|
<view slot="left">
|
||||||
|
<u-icon
|
||||||
|
name="arrow-left"
|
||||||
|
v-if="isBack"
|
||||||
|
color="#fff"
|
||||||
|
size="26"
|
||||||
|
@click="navigateBack"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
<view v-if="slotRight" slot="right">
|
||||||
|
<slot name="right"></slot>
|
||||||
|
</view>
|
||||||
|
</u-navbar>
|
||||||
|
</u-sticky>
|
||||||
|
<u-navbar
|
||||||
|
:is-back="false"
|
||||||
|
:title="navTitle"
|
||||||
|
:bgColor="background1"
|
||||||
|
:titleStyle="titleStyle"
|
||||||
|
>
|
||||||
|
<view slot="left">
|
||||||
|
<u-icon
|
||||||
|
name="arrow-left"
|
||||||
|
v-if="isBack"
|
||||||
|
color="#fff"
|
||||||
|
size="26"
|
||||||
|
@click="navigateBack"
|
||||||
|
></u-icon>
|
||||||
|
</view>
|
||||||
|
<view v-if="slotRight" slot="right">
|
||||||
|
<slot name="right"></slot>
|
||||||
|
</view>
|
||||||
|
</u-navbar>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "navBar",
|
||||||
|
props: {
|
||||||
|
isBack: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
navTitle: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
stickyShow: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
backToUrl: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
slotRight: false,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
background: "rgb(16,16,16,0.2)",
|
||||||
|
background1: "rgb(16,16,16,0.2)",
|
||||||
|
titleStyle: {
|
||||||
|
color: "#fff",
|
||||||
|
fontSize: "36upx",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
navigateBack(params) {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
if (this.backToUrl.length > 0) {
|
||||||
|
console.log(this.backToUrl);
|
||||||
|
uni.navigateTo({
|
||||||
|
url: this.backToUrl,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (pages.length === 1) {
|
||||||
|
if (typeof params === "number") {
|
||||||
|
history.go(-params);
|
||||||
|
} else {
|
||||||
|
history.back();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.navigateBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.status_bar {
|
||||||
|
height: var(--status-bar-height);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
25
components/page-animation/index.css
Normal file
25
components/page-animation/index.css
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
uni-page {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni-page.animation-before {
|
||||||
|
transform: translateY(20px);
|
||||||
|
}
|
||||||
|
|
||||||
|
uni-page.animation-leave {
|
||||||
|
transition: all .3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni-page.animation-enter {
|
||||||
|
transition: all .3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni-page.animation-show {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni-page.animation-after {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
37
components/page-animation/index.vue
Normal file
37
components/page-animation/index.vue
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<script>
|
||||||
|
import './index.css'
|
||||||
|
export default {
|
||||||
|
// #ifdef H5
|
||||||
|
onLaunch: function() {
|
||||||
|
this.show()
|
||||||
|
this.$router.beforeEach((to, from, next) => {
|
||||||
|
this.hide(next)
|
||||||
|
})
|
||||||
|
this.$router.afterEach(() => {
|
||||||
|
setTimeout(this.show, 50)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
hide(callback) {
|
||||||
|
const classList = document.querySelector('uni-page').classList
|
||||||
|
classList.add('animation-before', 'animation-leave')
|
||||||
|
classList.remove('animation-show')
|
||||||
|
setTimeout(() => {
|
||||||
|
classList.remove('animation-before', 'animation-leave')
|
||||||
|
callback && callback()
|
||||||
|
}, 300)
|
||||||
|
},
|
||||||
|
show() {
|
||||||
|
const classList = document.querySelector('uni-page').classList
|
||||||
|
classList.add('animation-before')
|
||||||
|
setTimeout(() => {
|
||||||
|
classList.add('animation-enter', 'animation-after', 'animation-show')
|
||||||
|
setTimeout(() => {
|
||||||
|
classList.remove('animation-before', 'animation-after', 'animation-enter')
|
||||||
|
}, 300)
|
||||||
|
}, 20)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
</script>
|
383
components/pyh-rdtpicker/pyh-rdtpicker.vue
Normal file
383
components/pyh-rdtpicker/pyh-rdtpicker.vue
Normal file
@ -0,0 +1,383 @@
|
|||||||
|
<template>
|
||||||
|
<view class="rpickerBox">
|
||||||
|
<view :class="{'pickerMask':showPicker}" @click="maskClick" @touchmove.stop.prevent="returnHandle">
|
||||||
|
<view class="r-dtpicker" :class="{'r-dtpicker-show':showPicker}">
|
||||||
|
<view class="rdtBtn" @touchmove.stop.prevent="returnHandle" @tap.stop="returnHandle">
|
||||||
|
<view @click="pickerCancel">取消</view>
|
||||||
|
<view :style="{color:themeColor}" @click="pickerConfirm">确定</view>
|
||||||
|
</view>
|
||||||
|
<view class="rangeBox" @touchmove.stop.prevent="returnHandle" @tap.stop="returnHandle">
|
||||||
|
<input type="text" disabled placeholder="开始时间" :value="startDate" :style="{color:themeColor,'border-color':themeColor,opacity:dateType=='startDate'?1:.5}" @tap="changeDateType('startDate')">至<input type="text" disabled placeholder="结束时间" :style="{color:themeColor,'border-color':themeColor,opacity:dateType=='endDate'?1:.5}" :value="endDate" @tap="changeDateType('endDate')">
|
||||||
|
</view>
|
||||||
|
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChangeMul">
|
||||||
|
<block>
|
||||||
|
<picker-view-column>
|
||||||
|
<view class="picker-item" v-for="(item,index) in yearArr" :key="index">{{item}}</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column v-if="fields!='year'">
|
||||||
|
<view class="picker-item" v-for="(item,index) in monthArr" :key="index">{{item}}</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column v-if="fields=='day'">
|
||||||
|
<view class="picker-item" v-for="(item,index) in dayArr" :key="index">{{item}}</view>
|
||||||
|
</picker-view-column>
|
||||||
|
</block>
|
||||||
|
</picker-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'range-dtpicker',
|
||||||
|
props: {
|
||||||
|
//粒度
|
||||||
|
fields:{
|
||||||
|
type: String,
|
||||||
|
default: 'day'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* picker允许选中的最小值
|
||||||
|
*/
|
||||||
|
start: {
|
||||||
|
type: String,
|
||||||
|
default: '1900-01-01'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* picker允许选中的最大值
|
||||||
|
*/
|
||||||
|
end: {
|
||||||
|
type: String,
|
||||||
|
default: '2200-12-01'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* picker默认展示的值
|
||||||
|
*/
|
||||||
|
value: {
|
||||||
|
type: Array,
|
||||||
|
default(){
|
||||||
|
return [0,0]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//是否显示
|
||||||
|
show: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
主题色
|
||||||
|
*/
|
||||||
|
themeColor:{
|
||||||
|
type: String,
|
||||||
|
default: '#4C83D6'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showPicker: this.show,
|
||||||
|
dayArr:[],
|
||||||
|
pickerValue:this.fields=='year'?[0]:this.fields=='month'?[0,0]:[0,0,0],
|
||||||
|
dateType:"startDate",
|
||||||
|
startDate:'',
|
||||||
|
endDate:""
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(value){
|
||||||
|
this.value=value;
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
show(isShow) {
|
||||||
|
this.showPicker = isShow;
|
||||||
|
},
|
||||||
|
start(){
|
||||||
|
this.init()
|
||||||
|
},
|
||||||
|
end(){
|
||||||
|
this.init()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
yearArr(){
|
||||||
|
var arr = [],start = parseInt(this.start.slice(0,4)),end=parseInt(this.end.slice(0,4));
|
||||||
|
for(var i=0;i<=end-start;i++){
|
||||||
|
arr.push(start+i)
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
},
|
||||||
|
monthArr(){
|
||||||
|
var arr = [];
|
||||||
|
for(var i=1;i<=12;i++){
|
||||||
|
var v = i;
|
||||||
|
if(v<10)v="0"+v;
|
||||||
|
if(this.start.length>4&&this.end.length>4&&(this.start.slice(0,4)==this.end.slice(0,4))){
|
||||||
|
if(parseInt(v)>=this.start.slice(5,7)&&parseInt(v)<=this.end.slice(5,7)){
|
||||||
|
arr.push(v.toString())
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
arr.push(v.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
returnHandle(){},
|
||||||
|
init(){
|
||||||
|
var that = this,pickerValue="";
|
||||||
|
if((this.fields=='year'&&this.start.length!=4)||(this.fields=='month'&&this.start.length!=7)||(this.fields=='day'&&this.start.length!=10)){
|
||||||
|
console.error("最小值格式与粒度格式不符");return;
|
||||||
|
}else if((this.fields=='year'&&this.end.length!=4)||(this.fields=='month'&&this.end.length!=7)||(this.fields=='day'&&this.end.length!=10)){
|
||||||
|
console.error("最大值格式与粒度格式不符");return;
|
||||||
|
}
|
||||||
|
var start=this.fields=='year'?this.start.slice(0,4):this.fields=='month'?this.start.slice(0,7):this.start,
|
||||||
|
end=this.fields=='year'?this.end.slice(0,4):this.fields=='month'?this.end.slice(0,7):this.end;
|
||||||
|
if(!start||!end){
|
||||||
|
console.error("时间不能为空");return;
|
||||||
|
}else if(start>end){
|
||||||
|
console.error("结束时间必须大等于开始时间");return;
|
||||||
|
}
|
||||||
|
if(this.value[0]){
|
||||||
|
if((this.fields=='year'&&this.value[0].length!=4)||(this.fields=='month'&&this.value[0].length!=7)||(this.fields=='day'&&this.value[0].length!=10)){
|
||||||
|
console.error("默认值格式与粒度格式不符");return;
|
||||||
|
}
|
||||||
|
this.startDate=this.value[0];
|
||||||
|
if(this.value[1]){
|
||||||
|
if((this.fields=='year'&&this.value[1].length!=4)||(this.fields=='month'&&this.value[1].length!=7)||(this.fields=='day'&&this.value[1].length!=10)){
|
||||||
|
console.error("默认值格式与粒度格式不符");return;
|
||||||
|
}
|
||||||
|
this.endDate=this.value[1];
|
||||||
|
this.dateType="endDate";
|
||||||
|
if(this.fields=='day')this.dayArr=this.getMonthDay(this.value[1].slice(0,4),this.value[1].slice(5,7));
|
||||||
|
pickerValue=this.getIndex(this.value[1]);
|
||||||
|
}else{
|
||||||
|
this.dateType="startDate";
|
||||||
|
if(this.fields=='day')this.dayArr=this.getMonthDay(this.value[0].slice(0,4),this.value[0].slice(5,7));
|
||||||
|
pickerValue=this.getIndex(this.value[0]);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
this.startDate=start;
|
||||||
|
pickerValue=this.getIndex(start);
|
||||||
|
if(this.fields=='day')this.dayArr=this.getMonthDay(start.slice(0,4),start.slice(5,7));
|
||||||
|
}
|
||||||
|
if(pickerValue)setTimeout(function(){that.pickerValue=pickerValue},20)
|
||||||
|
},
|
||||||
|
maskClick(){
|
||||||
|
this.$emit("showchange",false);
|
||||||
|
},
|
||||||
|
pickerConfirm(){
|
||||||
|
if(this.endDate<this.startDate){
|
||||||
|
uni.showToast({
|
||||||
|
title:"结束时间不得小于开始时间",
|
||||||
|
icon:"none",
|
||||||
|
mask:true
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$emit("change",[this.startDate,this.endDate]);
|
||||||
|
this.$emit("showchange",false);
|
||||||
|
},
|
||||||
|
pickerCancel(){
|
||||||
|
this.$emit("cancel");
|
||||||
|
this.$emit("showchange",false);
|
||||||
|
},
|
||||||
|
changeDateType(dateType){
|
||||||
|
var that = this;
|
||||||
|
this.dateType=dateType;
|
||||||
|
if(this[dateType]){
|
||||||
|
this.pickerValue=this.getIndex(this[dateType])
|
||||||
|
}else{
|
||||||
|
var dateTxt=this.fields=='year'?this.yearArr[this.pickerValue[0]]:this.fields=='month'?this.yearArr[this.pickerValue[0]]+'-'+this.monthArr[this.pickerValue[1]]:this.yearArr[this.pickerValue[0]]+'-'+this.monthArr[this.pickerValue[1]]+'-'+this.dayArr[this.pickerValue[2]];
|
||||||
|
this[dateType]=dateTxt;
|
||||||
|
this.pickerValue=this.fields=='year'?[this.pickerValue[0]]:this.fields=='month'?[this.pickerValue[0],this.pickerValue[1]]:[this.pickerValue[0],this.pickerValue[1],this.pickerValue[2]];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pickerChangeMul(e){
|
||||||
|
var that=this,val = e.detail.value,dateTxt="";
|
||||||
|
if(this.fields=='day'&&(val[0]!=this.pickerValue[0]||val[1]!=this.pickerValue[1])){
|
||||||
|
this.dayArr=this.getMonthDay(this.yearArr[val[0]],this.monthArr[val[1]])
|
||||||
|
function returnMax(){
|
||||||
|
if(!that.dayArr[val[2]]){
|
||||||
|
val[2]=(val[2]-1)
|
||||||
|
returnMax()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
returnMax()
|
||||||
|
}
|
||||||
|
dateTxt=this.yearArr[val[0]]+'-'+this.monthArr[val[1]]+'-'+this.dayArr[val[2]];
|
||||||
|
this[this.dateType]=this.fields=='year'?dateTxt.slice(0,4):this.fields=='month'?dateTxt.slice(0,7):dateTxt;
|
||||||
|
this.pickerValue=this.getIndex(this[this.dateType]);
|
||||||
|
},
|
||||||
|
getIndex(value){
|
||||||
|
var year = value.slice(0,4),month=value.slice(5,7),day=value.slice(8,10),y=0,m=0,d=0;
|
||||||
|
for(var i in this.yearArr){
|
||||||
|
if(year==this.yearArr[i]){
|
||||||
|
y=i;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(var i in this.monthArr){
|
||||||
|
if(month==this.monthArr[i]){
|
||||||
|
m=i;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(var i in this.dayArr){
|
||||||
|
if(day==this.dayArr[i]){
|
||||||
|
d=i;break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var value = [];
|
||||||
|
switch (this.fields){
|
||||||
|
case 'year':value = [Number(y)]
|
||||||
|
break;
|
||||||
|
case 'month':value = [Number(y),Number(m)]
|
||||||
|
break;
|
||||||
|
default:value = [Number(y),Number(m),Number(d)]
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
},
|
||||||
|
withData: (num) => {
|
||||||
|
let param = parseInt(num);
|
||||||
|
return param < 10 ? '0' + param : '' + param;
|
||||||
|
},
|
||||||
|
getLoopArray(start, end,specialDay){
|
||||||
|
var start = start || 0;
|
||||||
|
var end = end || 1;
|
||||||
|
var array = [];
|
||||||
|
if(specialDay){
|
||||||
|
array=specialDay;
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
for (var i = start; i <= end; i++) {
|
||||||
|
array.push(this.withData(i));
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
},
|
||||||
|
getMonthDay(year, month,specialDay){
|
||||||
|
var flag = year % 400 == 0 || (year % 4 == 0 && year % 100 != 0), array = null;
|
||||||
|
|
||||||
|
switch (month) {
|
||||||
|
case '01':
|
||||||
|
case '03':
|
||||||
|
case '05':
|
||||||
|
case '07':
|
||||||
|
case '08':
|
||||||
|
case '10':
|
||||||
|
case '12':
|
||||||
|
array = this.getLoopArray(1, 31,specialDay)
|
||||||
|
break;
|
||||||
|
case '04':
|
||||||
|
case '06':
|
||||||
|
case '09':
|
||||||
|
case '11':
|
||||||
|
array = this.getLoopArray(1, 30,specialDay)
|
||||||
|
break;
|
||||||
|
case '02':
|
||||||
|
array = flag ? this.getLoopArray(1, 29,specialDay) : this.getLoopArray(1, 28,specialDay)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
array = '月份格式不正确,请重新输入!'
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.pickerMask {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 998;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.r-dtpicker {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
transform: translateY(100%);
|
||||||
|
z-index: 998;
|
||||||
|
}
|
||||||
|
|
||||||
|
.r-dtpicker-show {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rdtBtn {
|
||||||
|
display: flex;
|
||||||
|
padding: 9px 15px;
|
||||||
|
background-color: #fff;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rdtBtn:after {
|
||||||
|
content: ' ';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 1px;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
color: #e5e5e5;
|
||||||
|
transform-origin: 0 100%;
|
||||||
|
transform: scaleY(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rdtBtn view{
|
||||||
|
display: block;
|
||||||
|
flex: 1;
|
||||||
|
color: #1aad19;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rdtBtn view:first-child {
|
||||||
|
text-align: left;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rdtBtn view:last-child {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.picker-item {
|
||||||
|
text-align: center;
|
||||||
|
line-height: 40px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mpvue-picker-view {
|
||||||
|
position: relative;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 238px;
|
||||||
|
background-color: rgba(255, 255, 255, 1);
|
||||||
|
}
|
||||||
|
.rangeBox{
|
||||||
|
background: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 15px 0;
|
||||||
|
font-size: 16px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.rangeBox input{
|
||||||
|
width: 180upx;
|
||||||
|
margin: 0 10px;
|
||||||
|
text-align: center;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
min-height: auto;
|
||||||
|
border-bottom: 1px solid #000;
|
||||||
|
}
|
||||||
|
</style>
|
81
components/pyh-rdtpicker/readme.md
Normal file
81
components/pyh-rdtpicker/readme.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
### pyh-rdtPicker 日期区间选择器
|
||||||
|
|
||||||
|
可进行多粒度的时间选择器,组件名:``pyh-rdtpicker``,代码块: rangeDatePick。
|
||||||
|
|
||||||
|
**使用方式:**
|
||||||
|
|
||||||
|
在 ``script`` 中引用组件
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
import rangeDatePick from '@/components/pyh-rdtpicker/pyh-rdtpicker.vue';
|
||||||
|
export default {
|
||||||
|
components: {rangeDatePick}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
在 ``template`` 中使用组件
|
||||||
|
|
||||||
|
```html
|
||||||
|
<rangeDatePick
|
||||||
|
:show="isShow"
|
||||||
|
@showchange="showchange"
|
||||||
|
:start="1900-01-01"
|
||||||
|
:end="2200-12-01"
|
||||||
|
:value="value"
|
||||||
|
@change="bindChange"
|
||||||
|
@cancel="bindCancel"
|
||||||
|
themeColor="#4C83D6"
|
||||||
|
fields="month"
|
||||||
|
></rangeDatePick>
|
||||||
|
```
|
||||||
|
|
||||||
|
**pdtPicker 属性说明:**
|
||||||
|
|
||||||
|
|属性名 |类型 |默认值 |说明 |
|
||||||
|
|--- |---- |--- |--- |
|
||||||
|
|themeColor |String |'#4C83D6' |主题色 |
|
||||||
|
|start |String |'1900-01-01' |限制选择器选择的最小时间 (只支持年限制),粒度格式和value格式要相符,否则会有错误提示|
|
||||||
|
|end |String |'2200-12-01' |限制选择器选择的最大时间(只支持年限制),粒度格式和value格式要相符,否则会有错误提示|
|
||||||
|
|value |Array |'' |当前日期选择器显示的时间 ,粒度格式和value格式要相符,否则会又错误提示|
|
||||||
|
|fields |String |'day' |当前日期选择器粒度:year/month/day|
|
||||||
|
|
||||||
|
|
||||||
|
**value 值说明:**
|
||||||
|
|
||||||
|
|值 |类型 |说明 |
|
||||||
|
|--- |---- |--- |
|
||||||
|
|[] |Array |当前日期选择器为开始时间的默认值 |
|
||||||
|
|['1900-01-01'] |Array |当前日期选择器开始时间为1900-01-01 |
|
||||||
|
|['1900-01-01','2010-12-01'] |Array |当前日期选择器开始时间为1900-01-01,结束时间为2010-12-01|
|
||||||
|
|
||||||
|
**事件说明:**
|
||||||
|
|
||||||
|
|事件名称 |说明 |
|
||||||
|
|---|---|
|
||||||
|
|showchange |必传,用于控制显示隐藏|
|
||||||
|
|change |时间选择器点击【确定】按钮时时触发的事件,参数为选择器的当前的 value|
|
||||||
|
|cancel |时间选择器点击【取消】按钮时时触发的事件|
|
||||||
|
|
||||||
|
**showchange事件说明:**
|
||||||
|
|
||||||
|
showchange(){
|
||||||
|
this.isShow=!this.isShow;
|
||||||
|
}
|
||||||
|
|
||||||
|
**更新记录:**
|
||||||
|
|
||||||
|
1.0.6:添加动态修改start和end,示例项目由新增注释</br>
|
||||||
|
|
||||||
|
1.0.5:修复月份切换时,day存在显示undefined的问题;修复小程序value设置后滚动位置不对的问题</br>
|
||||||
|
|
||||||
|
1.0.4:修复滚动穿透;修改默认fields为day,添加了同年限制月份(start和end同年,有月份限制),改正作者名与组件名字</br>
|
||||||
|
|
||||||
|
1.0.3:修复动态的value不能赋值问题;修复end值的可选值与实际填入的end值小一年问题</br>
|
||||||
|
|
||||||
|
1.0.2:优化了开始日期和结束日期的切换,当前版本切换时会显示更合适的日期;添加了粒度选择,现支持year/month/day;修复了demo的getDate -60年的获取问题</br>
|
||||||
|
|
||||||
|
1.0.1:新增组件——日期区间选择器
|
||||||
|
|
||||||
|
**感谢:**
|
||||||
|
|
||||||
|
> 有更多优化建议和需求,请联系作者panyh。谢谢!
|
97
components/tabBar/tabBar.vue
Normal file
97
components/tabBar/tabBar.vue
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<view class="status_bar">
|
||||||
|
<!-- 这里是状态栏 -->
|
||||||
|
</view>
|
||||||
|
<u-tabbar
|
||||||
|
:value="current"
|
||||||
|
@change="changeTab"
|
||||||
|
:fixed="true"
|
||||||
|
:placeholder="false"
|
||||||
|
:safeAreaInsetBottom="true"
|
||||||
|
:border="false"
|
||||||
|
activeColor="#FCB462"
|
||||||
|
inactiveColor="#6D6D6D"
|
||||||
|
>
|
||||||
|
<u-tabbar-item
|
||||||
|
v-for="(item, index) in tabBarList"
|
||||||
|
:key="index"
|
||||||
|
:text="item.text"
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
class="u-page__item__slot-icon"
|
||||||
|
slot="inactive-icon"
|
||||||
|
:src="item.iconPath"
|
||||||
|
></image>
|
||||||
|
<image
|
||||||
|
class="u-page__item__slot-icon"
|
||||||
|
slot="active-icon"
|
||||||
|
:src="item.selectedIconPath"
|
||||||
|
></image>
|
||||||
|
</u-tabbar-item>
|
||||||
|
</u-tabbar>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from "vuex";
|
||||||
|
export default {
|
||||||
|
name: "tabBar",
|
||||||
|
props: {
|
||||||
|
currentPage: String,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
current: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(["tabBarList"]),
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeTab(e) {
|
||||||
|
console.log(e);
|
||||||
|
console.log(this.tabBarList);
|
||||||
|
let page = "/" + this.tabBarList[e].pagePath;
|
||||||
|
console.log(page);
|
||||||
|
uni.switchTab({
|
||||||
|
url: page,
|
||||||
|
success: (res) => {
|
||||||
|
console.log(res);
|
||||||
|
},
|
||||||
|
fail: (e) => {
|
||||||
|
console.log(e);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
//隐藏原生tabbar
|
||||||
|
uni.hideTabBar();
|
||||||
|
// 当前选中的菜单
|
||||||
|
this.tabBarList.forEach((i, index) => {
|
||||||
|
if (i.pagePath == this.currentPage) {
|
||||||
|
this.current = index;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.status_bar {
|
||||||
|
height: var(--status-bar-height);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.u-page__item__slot-icon {
|
||||||
|
width: 68rpx;
|
||||||
|
height: 68rpx;
|
||||||
|
}
|
||||||
|
.u-tabbar /deep/ .u-tabbar--fixed {
|
||||||
|
width: 92%;
|
||||||
|
padding: 9px;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
bottom: 10px;
|
||||||
|
left: 1.7%;
|
||||||
|
}
|
||||||
|
</style>
|
131
components/timeRang-picker/timeRang-picker.vue
Normal file
131
components/timeRang-picker/timeRang-picker.vue
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
|
||||||
|
<template>
|
||||||
|
<u-popup :show="show" mode="bottom">
|
||||||
|
<view class="box">
|
||||||
|
<view class="head">
|
||||||
|
<view>请选择参观时间段</view>
|
||||||
|
<u-icon name="close-circle" size="48rpx" @click="close"></u-icon>
|
||||||
|
</view>
|
||||||
|
<u-divider lineColor="#868686"></u-divider>
|
||||||
|
<view class="container">
|
||||||
|
<view :class="[{'active':current === index},'card']" @click="handelInfo(index,item)" v-for="(item,index) in appointmentTimeList" :key="index">
|
||||||
|
<view class="time">
|
||||||
|
<view>{{item.date}}</view>
|
||||||
|
<view>{{item.time}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="count" v-if="item.residue>0">*剩余{{item.residue}}人</view>
|
||||||
|
<view class="count" v-else>*满员</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-divider lineColor="#868686"></u-divider>
|
||||||
|
<view class="foot">
|
||||||
|
<u-button text="确定" class="btn" @click="onConfirm"></u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</u-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
current:-1,
|
||||||
|
currentObj:{}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: ['show','appointmentTimeList'],
|
||||||
|
methods: {
|
||||||
|
close() {
|
||||||
|
this.$emit("update:show", false)
|
||||||
|
},
|
||||||
|
handelInfo(index,item) {
|
||||||
|
this.current = index
|
||||||
|
this.currentObj = item
|
||||||
|
},
|
||||||
|
onConfirm() {
|
||||||
|
if(!Object.keys(this.currentObj).length){
|
||||||
|
return this.$common.msgToast("请选择一个参观时间段", null, "error");
|
||||||
|
}
|
||||||
|
this.$emit("onConfirm", this.currentObj)
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/deep/ .u-transition {
|
||||||
|
height: 752rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
padding: 30rpx;
|
||||||
|
|
||||||
|
.head {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
height: 410rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin: 5rpx;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 220rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
border: 2px solid #1836C8;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
padding-right: 10rpx;
|
||||||
|
padding-bottom: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-top: 20rpx;
|
||||||
|
padding-left: 20rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
|
||||||
|
.time {
|
||||||
|
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.count {
|
||||||
|
font-size: 16rpx;
|
||||||
|
color: #9DADFE;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.active{
|
||||||
|
background-color: #1936C9;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.foot {
|
||||||
|
.btn {
|
||||||
|
width: 436rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
background-color: #1936C9;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.container::after {
|
||||||
|
content: '';
|
||||||
|
flex: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
1171
components/w-picker/date-picker.vue
Normal file
1171
components/w-picker/date-picker.vue
Normal file
File diff suppressed because it is too large
Load Diff
526
components/w-picker/half-picker.vue
Normal file
526
components/w-picker/half-picker.vue
Normal file
@ -0,0 +1,526 @@
|
|||||||
|
<template>
|
||||||
|
<view class="w-picker-view">
|
||||||
|
<view
|
||||||
|
style="
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
padding: 30upx 0;
|
||||||
|
border-bottom: 1rpx solid rgb(134 134 134);
|
||||||
|
border-top: 1rpx solid rgb(134 134 134);
|
||||||
|
color:#1936C9
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<view>年份</view>
|
||||||
|
<view>月</view>
|
||||||
|
<view>日</view>
|
||||||
|
<view>场次</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<picker-view
|
||||||
|
class="d-picker-view"
|
||||||
|
:indicator-style="itemHeight"
|
||||||
|
:value="pickVal"
|
||||||
|
@change="handlerChange"
|
||||||
|
>
|
||||||
|
<picker-view-column>
|
||||||
|
<view
|
||||||
|
class="w-picker-item"
|
||||||
|
v-for="(item, index) in range.years"
|
||||||
|
:key="index"
|
||||||
|
>{{ item }}</view
|
||||||
|
>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column>
|
||||||
|
<view
|
||||||
|
class="w-picker-item"
|
||||||
|
v-for="(item, index) in range.months"
|
||||||
|
:key="index"
|
||||||
|
>{{ item }}</view
|
||||||
|
>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column>
|
||||||
|
<view
|
||||||
|
class="w-picker-item"
|
||||||
|
v-for="(item, index) in range.days"
|
||||||
|
:key="index"
|
||||||
|
>{{ item }}</view
|
||||||
|
>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column>
|
||||||
|
<view
|
||||||
|
class="w-picker-item"
|
||||||
|
v-for="(item, index) in range.sections"
|
||||||
|
:key="index"
|
||||||
|
>{{ item }}</view
|
||||||
|
>
|
||||||
|
</picker-view-column>
|
||||||
|
</picker-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
pickVal: [],
|
||||||
|
range: {},
|
||||||
|
checkObj: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
itemHeight: {
|
||||||
|
type: String,
|
||||||
|
default: "44px",
|
||||||
|
},
|
||||||
|
startYear: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
endYear: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Array, Number],
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
current: {
|
||||||
|
//是否默认选中当前日期
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
disabledAfter: {
|
||||||
|
//是否禁用当前之后的日期
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
disabledBefore: {
|
||||||
|
//是否禁用当前之前
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(val) {
|
||||||
|
this.initData();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
formatNum(n) {
|
||||||
|
return Number(n) < 10 ? "0" + Number(n) : Number(n) + "";
|
||||||
|
},
|
||||||
|
checkValue(value) {
|
||||||
|
let strReg = /^\d{4}-\d{2}-\d{2} [\u4e00-\u9fa5]{2}$/,
|
||||||
|
example;
|
||||||
|
if (!strReg.test(value)) {
|
||||||
|
console.log(
|
||||||
|
new Error(
|
||||||
|
"请传入与mode、fields匹配的value值,例value=" + example + ""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return strReg.test(value);
|
||||||
|
},
|
||||||
|
resetData(year, month, day) {
|
||||||
|
let curDate = this.getCurrenDate();
|
||||||
|
let curFlag = this.current;
|
||||||
|
let curYear = curDate.curYear;
|
||||||
|
let curMonth = curDate.curMonth;
|
||||||
|
let curDay = curDate.curDay;
|
||||||
|
let curHour = curDate.curHour;
|
||||||
|
let months = [],
|
||||||
|
days = [],
|
||||||
|
sections = [];
|
||||||
|
let disabledAfter = this.disabledAfter;
|
||||||
|
let monthsLen = disabledAfter ? (year * 1 < curYear ? 12 : curMonth) : 12;
|
||||||
|
let totalDays = new Date(year, month, 0).getDate(); //计算当月有几天;
|
||||||
|
let daysLen = disabledAfter
|
||||||
|
? year * 1 < curYear || month * 1 < curMonth
|
||||||
|
? totalDays
|
||||||
|
: curDay
|
||||||
|
: totalDays;
|
||||||
|
let sectionFlag = disabledAfter
|
||||||
|
? (year * 1 < curYear || month * 1 < curMonth || day * 1 < curDay) ==
|
||||||
|
true
|
||||||
|
? false
|
||||||
|
: true
|
||||||
|
: curHour > 12 == true
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
|
||||||
|
sections = ["上午", "下午"];
|
||||||
|
for (let month = 1; month <= monthsLen; month++) {
|
||||||
|
months.push(this.formatNum(month));
|
||||||
|
}
|
||||||
|
for (let day = 1; day <= daysLen; day++) {
|
||||||
|
days.push(this.formatNum(day));
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
months,
|
||||||
|
days,
|
||||||
|
sections,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getData(dVal) {
|
||||||
|
//用来处理初始化数据
|
||||||
|
let curFlag = this.current;
|
||||||
|
let disabledAfter = this.disabledAfter;
|
||||||
|
let curDate = this.getCurrenDate();
|
||||||
|
let curYear = curDate.curYear;
|
||||||
|
let curMonthdays = curDate.curMonthdays;
|
||||||
|
let curMonth = curDate.curMonth;
|
||||||
|
let curDay = curDate.curDay;
|
||||||
|
let curHour = curDate.curHour;
|
||||||
|
let defaultDate = this.getDefaultDate();
|
||||||
|
let startYear = this.getStartDate().getFullYear();
|
||||||
|
let endYear = this.getEndDate().getFullYear();
|
||||||
|
let years = [],
|
||||||
|
months = [],
|
||||||
|
days = [],
|
||||||
|
sections = [];
|
||||||
|
let year = dVal[0] * 1;
|
||||||
|
let month = dVal[1] * 1;
|
||||||
|
let day = dVal[2] * 1;
|
||||||
|
let monthsLen = disabledAfter
|
||||||
|
? year < curYear
|
||||||
|
? 12
|
||||||
|
: curDate.curMonth
|
||||||
|
: 12;
|
||||||
|
let daysLen = disabledAfter
|
||||||
|
? year < curYear || month < curMonth
|
||||||
|
? defaultDate.defaultDays
|
||||||
|
: curDay
|
||||||
|
: curFlag
|
||||||
|
? curMonthdays
|
||||||
|
: defaultDate.defaultDays;
|
||||||
|
let sectionFlag = disabledAfter
|
||||||
|
? (year * 1 < curYear || month * 1 < curMonth || day * 1 < curDay) ==
|
||||||
|
true
|
||||||
|
? false
|
||||||
|
: true
|
||||||
|
: curHour > 12 == true
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
for (
|
||||||
|
let year = startYear;
|
||||||
|
year <= (disabledAfter ? curYear : endYear);
|
||||||
|
year++
|
||||||
|
) {
|
||||||
|
years.push(year.toString());
|
||||||
|
}
|
||||||
|
for (let month = 1; month <= monthsLen; month++) {
|
||||||
|
months.push(this.formatNum(month));
|
||||||
|
}
|
||||||
|
for (let day = 1; day <= daysLen; day++) {
|
||||||
|
days.push(this.formatNum(day));
|
||||||
|
}
|
||||||
|
sections = ["上午", "下午"];
|
||||||
|
if (this.disabledBefore) {
|
||||||
|
years = years.filter((item) => item * 1 >= curYear);
|
||||||
|
months = months.filter((item) => item * 1 >= curMonth);
|
||||||
|
days = days.filter((item) => item * 1 >= curDay);
|
||||||
|
|
||||||
|
let nowcurDate = new Date();
|
||||||
|
let nowcurYear = nowcurDate.getFullYear();
|
||||||
|
let nowcurMonth = nowcurDate.getMonth() + 1;
|
||||||
|
let nowcurDay = nowcurDate.getDate();
|
||||||
|
let nowcurHour = nowcurDate.getHours();
|
||||||
|
if (
|
||||||
|
curYear === nowcurYear &&
|
||||||
|
curMonth === nowcurMonth &&
|
||||||
|
curDay === nowcurDay &&
|
||||||
|
nowcurHour > 12
|
||||||
|
) {
|
||||||
|
sections = ["下午"];
|
||||||
|
} else {
|
||||||
|
sections = ["上午", "下午"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
years,
|
||||||
|
months,
|
||||||
|
days,
|
||||||
|
sections,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getCurrenDate() {
|
||||||
|
let curDate = new Date();
|
||||||
|
let curYear = curDate.getFullYear();
|
||||||
|
let curMonth = curDate.getMonth() + 1;
|
||||||
|
let curMonthdays = new Date(curYear, curMonth, 0).getDate();
|
||||||
|
let curDay = curDate.getDate();
|
||||||
|
let curHour = curDate.getHours();
|
||||||
|
let curSection = "上午";
|
||||||
|
if (curHour >= 12) {
|
||||||
|
curSection = "下午";
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
curDate,
|
||||||
|
curYear,
|
||||||
|
curMonth,
|
||||||
|
curMonthdays,
|
||||||
|
curDay,
|
||||||
|
curHour,
|
||||||
|
curSection,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getDefaultDate() {
|
||||||
|
let value = this.value;
|
||||||
|
let reg = /-/g;
|
||||||
|
let defaultDate = value
|
||||||
|
? new Date(value.split(" ")[0].replace(reg, "/"))
|
||||||
|
: new Date();
|
||||||
|
let defaultYear = defaultDate.getFullYear();
|
||||||
|
let defaultMonth = defaultDate.getMonth() + 1;
|
||||||
|
let defaultDay = defaultDate.getDate();
|
||||||
|
let defaultDays = new Date(defaultYear, defaultMonth, 0).getDate() * 1;
|
||||||
|
return {
|
||||||
|
defaultDate,
|
||||||
|
defaultYear,
|
||||||
|
defaultMonth,
|
||||||
|
defaultDay,
|
||||||
|
defaultDays,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getStartDate() {
|
||||||
|
let start = this.startYear;
|
||||||
|
let startDate = "";
|
||||||
|
let reg = /-/g;
|
||||||
|
if (start) {
|
||||||
|
startDate = new Date(start + "/01/01");
|
||||||
|
} else {
|
||||||
|
startDate = new Date("1970/01/01");
|
||||||
|
}
|
||||||
|
return startDate;
|
||||||
|
},
|
||||||
|
getEndDate() {
|
||||||
|
let end = this.endYear;
|
||||||
|
let reg = /-/g;
|
||||||
|
let endDate = "";
|
||||||
|
if (end) {
|
||||||
|
endDate = new Date(end + "/12/31");
|
||||||
|
} else {
|
||||||
|
endDate = new Date();
|
||||||
|
}
|
||||||
|
return endDate;
|
||||||
|
},
|
||||||
|
getDval() {
|
||||||
|
let value = this.value;
|
||||||
|
let dVal = null;
|
||||||
|
let aDate = new Date();
|
||||||
|
let year = this.formatNum(aDate.getFullYear());
|
||||||
|
let month = this.formatNum(aDate.getMonth() + 1);
|
||||||
|
let day = this.formatNum(aDate.getDate());
|
||||||
|
let hour = aDate.getHours();
|
||||||
|
let section = "上午";
|
||||||
|
if (hour >= 12) section = "下午";
|
||||||
|
if (value) {
|
||||||
|
let flag = this.checkValue(value);
|
||||||
|
if (!flag) {
|
||||||
|
dVal = [year, month, day, section];
|
||||||
|
} else {
|
||||||
|
let v = value.split(" ");
|
||||||
|
dVal = [...v[0].split("-"), v[1]];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dVal = [year, month, day, section];
|
||||||
|
}
|
||||||
|
return dVal;
|
||||||
|
},
|
||||||
|
initData() {
|
||||||
|
let startDate,
|
||||||
|
endDate,
|
||||||
|
startYear,
|
||||||
|
endYear,
|
||||||
|
startMonth,
|
||||||
|
endMonth,
|
||||||
|
startDay,
|
||||||
|
endDay;
|
||||||
|
let years = [],
|
||||||
|
months = [],
|
||||||
|
days = [],
|
||||||
|
sections = [];
|
||||||
|
let dVal = [],
|
||||||
|
pickVal = [];
|
||||||
|
let value = this.value;
|
||||||
|
let reg = /-/g;
|
||||||
|
let range = {};
|
||||||
|
let result = "",
|
||||||
|
full = "",
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
day,
|
||||||
|
section,
|
||||||
|
obj = {};
|
||||||
|
let defaultDate = this.getDefaultDate();
|
||||||
|
let defaultYear = defaultDate.defaultYear;
|
||||||
|
let defaultMonth = defaultDate.defaultMonth;
|
||||||
|
let defaultDay = defaultDate.defaultDay;
|
||||||
|
let defaultDays = defaultDate.defaultDays;
|
||||||
|
let curFlag = this.current;
|
||||||
|
let disabledAfter = this.disabledAfter;
|
||||||
|
let curDate = this.getCurrenDate();
|
||||||
|
let curYear = curDate.curYear;
|
||||||
|
let curMonth = curDate.curMonth;
|
||||||
|
let curMonthdays = curDate.curMonthdays;
|
||||||
|
let curDay = curDate.curDay;
|
||||||
|
let curSection = curDate.curSection;
|
||||||
|
let dateData = [];
|
||||||
|
dVal = this.getDval();
|
||||||
|
startDate = this.getStartDate();
|
||||||
|
endDate = this.getEndDate();
|
||||||
|
startYear = startDate.getFullYear();
|
||||||
|
startMonth = startDate.getMonth();
|
||||||
|
startDay = startDate.getDate();
|
||||||
|
endYear = endDate.getFullYear();
|
||||||
|
endMonth = endDate.getMonth();
|
||||||
|
endDay = endDate.getDate();
|
||||||
|
dateData = this.getData(dVal);
|
||||||
|
years = dateData.years;
|
||||||
|
months = dateData.months;
|
||||||
|
days = dateData.days;
|
||||||
|
sections = dateData.sections;
|
||||||
|
pickVal = disabledAfter
|
||||||
|
? [
|
||||||
|
dVal[0] && years.indexOf(dVal[0]) != -1
|
||||||
|
? years.indexOf(dVal[0])
|
||||||
|
: 0,
|
||||||
|
dVal[1] && months.indexOf(dVal[1]) != -1
|
||||||
|
? months.indexOf(dVal[1])
|
||||||
|
: 0,
|
||||||
|
dVal[2] && days.indexOf(dVal[2]) != -1 ? days.indexOf(dVal[2]) : 0,
|
||||||
|
dVal[3] && sections.indexOf(dVal[3]) != -1
|
||||||
|
? sections.indexOf(dVal[3])
|
||||||
|
: 0,
|
||||||
|
]
|
||||||
|
: curFlag
|
||||||
|
? [
|
||||||
|
years.indexOf(curYear + ""),
|
||||||
|
months.indexOf(this.formatNum(curMonth)),
|
||||||
|
days.indexOf(this.formatNum(curDay)),
|
||||||
|
sections.indexOf(curSection),
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
dVal[0] && years.indexOf(dVal[0]) != -1
|
||||||
|
? years.indexOf(dVal[0])
|
||||||
|
: 0,
|
||||||
|
dVal[1] && months.indexOf(dVal[1]) != -1
|
||||||
|
? months.indexOf(dVal[1])
|
||||||
|
: 0,
|
||||||
|
dVal[2] && days.indexOf(dVal[2]) != -1 ? days.indexOf(dVal[2]) : 0,
|
||||||
|
dVal[3] && sections.indexOf(dVal[3]) != -1
|
||||||
|
? sections.indexOf(dVal[3])
|
||||||
|
: 0,
|
||||||
|
];
|
||||||
|
range = { years, months, days, sections };
|
||||||
|
year = dVal[0] ? dVal[0] : years[0];
|
||||||
|
month = dVal[1] ? dVal[1] : months[0];
|
||||||
|
day = dVal[2] ? dVal[2] : days[0];
|
||||||
|
section = dVal[3] ? dVal[3] : sections[0];
|
||||||
|
result = full = `${year + "-" + month + "-" + day + " " + section}`;
|
||||||
|
obj = {
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
day,
|
||||||
|
section,
|
||||||
|
};
|
||||||
|
this.range = range;
|
||||||
|
this.checkObj = obj;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.pickVal = pickVal;
|
||||||
|
});
|
||||||
|
this.$emit("change", {
|
||||||
|
result: result,
|
||||||
|
value: full,
|
||||||
|
obj: obj,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handlerChange(e) {
|
||||||
|
let arr = [...e.detail.value];
|
||||||
|
let data = this.range;
|
||||||
|
let year = "",
|
||||||
|
month = "",
|
||||||
|
day = "",
|
||||||
|
section = "";
|
||||||
|
let result = "",
|
||||||
|
full = "",
|
||||||
|
obj = {};
|
||||||
|
let months = null,
|
||||||
|
days = null,
|
||||||
|
sections = null;
|
||||||
|
let disabledAfter = this.disabledAfter;
|
||||||
|
year =
|
||||||
|
arr[0] || arr[0] == 0
|
||||||
|
? data.years[arr[0]] || data.years[data.years.length - 1]
|
||||||
|
: "";
|
||||||
|
month =
|
||||||
|
arr[1] || arr[1] == 0
|
||||||
|
? data.months[arr[1]] || data.months[data.months.length - 1]
|
||||||
|
: "";
|
||||||
|
day =
|
||||||
|
arr[2] || arr[2] == 0
|
||||||
|
? data.days[arr[2]] || data.days[data.days.length - 1]
|
||||||
|
: "";
|
||||||
|
section =
|
||||||
|
arr[3] || arr[3] == 0
|
||||||
|
? data.sections[arr[3]] || data.sections[data.sections.length - 1]
|
||||||
|
: "";
|
||||||
|
result = full = `${year + "-" + month + "-" + day + " " + section}`;
|
||||||
|
let resetData = this.resetData(year, month, day);
|
||||||
|
if (this.disabledAfter) {
|
||||||
|
months = resetData.months;
|
||||||
|
days = resetData.days;
|
||||||
|
sections = resetData.sections;
|
||||||
|
} else {
|
||||||
|
if (year % 4 == 0 || month != this.checkObj.month) {
|
||||||
|
days = resetData.days;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.disabledBefore) {
|
||||||
|
let curDate = new Date();
|
||||||
|
let curYear = curDate.getFullYear();
|
||||||
|
let curMonth = curDate.getMonth() + 1;
|
||||||
|
let curMonthdays = new Date(curYear, curMonth, 0).getDate();
|
||||||
|
let curDay = curDate.getDate();
|
||||||
|
let curHour = curDate.getHours();
|
||||||
|
if (
|
||||||
|
year === curYear + "" &&
|
||||||
|
month * 1 === curMonth &&
|
||||||
|
day === curDay + "" &&
|
||||||
|
curHour > 12
|
||||||
|
) {
|
||||||
|
this.range.sections = ["下午"];
|
||||||
|
} else {
|
||||||
|
this.range.sections = ["上午", "下午"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (months) this.range.months = months;
|
||||||
|
if (days) this.range.days = days;
|
||||||
|
if (sections) this.range.sections = sections;
|
||||||
|
obj = {
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
day,
|
||||||
|
section,
|
||||||
|
};
|
||||||
|
this.checkObj = obj;
|
||||||
|
this.$emit("change", {
|
||||||
|
result: result,
|
||||||
|
value: full,
|
||||||
|
obj: obj,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "./w-picker.css";
|
||||||
|
</style>
|
344
components/w-picker/range-picker.vue
Normal file
344
components/w-picker/range-picker.vue
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
<template>
|
||||||
|
<view class="w-picker-view">
|
||||||
|
<picker-view class="d-picker-view" :indicator-style="itemHeight" :value="pickVal" @change="handlerChange">
|
||||||
|
<picker-view-column class="w-picker-flex2">
|
||||||
|
<view class="w-picker-item" v-for="(item,index) in range.fyears" :key="index">{{item}}年</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column class="w-picker-flex2">
|
||||||
|
<view class="w-picker-item" v-for="(item,index) in range.fmonths" :key="index">{{item}}月</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column class="w-picker-flex2">
|
||||||
|
<view class="w-picker-item" v-for="(item,index) in range.fdays" :key="index">{{item}}日</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column class="w-picker-flex1">
|
||||||
|
<view class="w-picker-item">-</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column class="w-picker-flex2">
|
||||||
|
<view class="w-picker-item" v-for="(item,index) in range.tyears" :key="index">{{item}}年</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column class="w-picker-flex2">
|
||||||
|
<view class="w-picker-item" v-for="(item,index) in range.tmonths" :key="index">{{item}}月</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column class="w-picker-flex2">
|
||||||
|
<view class="w-picker-item" v-for="(item,index) in range.tdays" :key="index">{{item}}日</view>
|
||||||
|
</picker-view-column>
|
||||||
|
</picker-view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
pickVal:[],
|
||||||
|
range:{},
|
||||||
|
checkObj:{}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
props:{
|
||||||
|
itemHeight:{
|
||||||
|
type:String,
|
||||||
|
default:"44px"
|
||||||
|
},
|
||||||
|
value:{
|
||||||
|
type:[String,Array],
|
||||||
|
default(){
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
current:{//是否默认选中当前日期
|
||||||
|
type:Boolean,
|
||||||
|
default:false
|
||||||
|
},
|
||||||
|
startYear:{
|
||||||
|
type:[String,Number],
|
||||||
|
default:1970
|
||||||
|
},
|
||||||
|
endYear:{
|
||||||
|
type:[String,Number],
|
||||||
|
default:new Date().getFullYear()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
value(val){
|
||||||
|
this.initData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.initData();
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
formatNum(n){
|
||||||
|
return (Number(n)<10?'0'+Number(n):Number(n)+'');
|
||||||
|
},
|
||||||
|
checkValue(value){
|
||||||
|
let strReg=/^\d{4}-\d{2}-\d{2}$/,example="2020-04-03";
|
||||||
|
if(!strReg.test(value[0])||!strReg.test(value[1])){
|
||||||
|
console.log(new Error("请传入与mode匹配的value值,例["+example+","+example+"]"))
|
||||||
|
}
|
||||||
|
return strReg.test(value[0])&&strReg.test(value[1]);
|
||||||
|
},
|
||||||
|
resetToData(fmonth,fday,tyear,tmonth){
|
||||||
|
let range=this.range;
|
||||||
|
let tmonths=[],tdays=[];
|
||||||
|
let yearFlag=tyear!=range.tyears[0];
|
||||||
|
let monthFlag=tyear!=range.tyears[0]||tmonth!=range.tmonths[0];
|
||||||
|
let ttotal=new Date(tyear,tmonth,0).getDate();
|
||||||
|
for(let i=yearFlag?1:fmonth*1;i<=12;i++){
|
||||||
|
tmonths.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
for(let i=monthFlag?1:fday*1;i<=ttotal;i++){
|
||||||
|
tdays.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
return{
|
||||||
|
tmonths,
|
||||||
|
tdays
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetData(fyear,fmonth,fday,tyear,tmonth){
|
||||||
|
let fyears=[],fmonths=[],fdays=[],tyears=[],tmonths=[],tdays=[];
|
||||||
|
let startYear=this.startYear;
|
||||||
|
let endYear=this.endYear;
|
||||||
|
let ftotal=new Date(fyear,fmonth,0).getDate();
|
||||||
|
let ttotal=new Date(tyear,tmonth,0).getDate();
|
||||||
|
for(let i=startYear*1;i<=endYear;i++){
|
||||||
|
fyears.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
for(let i=1;i<=12;i++){
|
||||||
|
fmonths.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
for(let i=1;i<=ftotal;i++){
|
||||||
|
fdays.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
for(let i=fyear*1;i<=endYear;i++){
|
||||||
|
tyears.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
for(let i=fmonth*1;i<=12;i++){
|
||||||
|
tmonths.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
for(let i=fday*1;i<=ttotal;i++){
|
||||||
|
tdays.push(this.formatNum(i))
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
fyears,
|
||||||
|
fmonths,
|
||||||
|
fdays,
|
||||||
|
tyears,
|
||||||
|
tmonths,
|
||||||
|
tdays
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getData(dVal){
|
||||||
|
let start=this.startYear*1;
|
||||||
|
let end=this.endYear*1;
|
||||||
|
let value=dVal;
|
||||||
|
let flag=this.current;
|
||||||
|
let aToday=new Date();
|
||||||
|
let tYear,tMonth,tDay,tHours,tMinutes,tSeconds,pickVal=[];
|
||||||
|
let initstartDate=new Date(start.toString());
|
||||||
|
let endDate=new Date(end.toString());
|
||||||
|
if(start>end){
|
||||||
|
initstartDate=new Date(end.toString());
|
||||||
|
endDate=new Date(start.toString());
|
||||||
|
};
|
||||||
|
let startYear=initstartDate.getFullYear();
|
||||||
|
let startMonth=initstartDate.getMonth()+1;
|
||||||
|
let endYear=endDate.getFullYear();
|
||||||
|
let fyears=[],fmonths=[],fdays=[],tyears=[],tmonths=[],tdays=[],returnArr=[],startDVal=[],endDVal=[];
|
||||||
|
let curMonth=flag?value[1]*1:(startDVal[1]*1+1);
|
||||||
|
let curMonth1=flag?value[5][1]*1:(value[5]*1+1);
|
||||||
|
let totalDays=new Date(value[0],value[1],0).getDate();
|
||||||
|
let totalDays1=new Date(value[4],value[5],0).getDate();
|
||||||
|
for(let s=startYear;s<=endYear;s++){
|
||||||
|
fyears.push(this.formatNum(s));
|
||||||
|
};
|
||||||
|
for(let m=1;m<=12;m++){
|
||||||
|
fmonths.push(this.formatNum(m));
|
||||||
|
};
|
||||||
|
for(let d=1;d<=totalDays;d++){
|
||||||
|
fdays.push(this.formatNum(d));
|
||||||
|
};
|
||||||
|
for(let s=value[0]*1;s<=endYear;s++){
|
||||||
|
tyears.push(this.formatNum(s));
|
||||||
|
};
|
||||||
|
|
||||||
|
if(value[4]*1>value[0]*1){
|
||||||
|
for(let m=1;m<=12;m++){
|
||||||
|
tmonths.push(this.formatNum(m));
|
||||||
|
};
|
||||||
|
for(let d=1;d<=totalDays1;d++){
|
||||||
|
tdays.push(this.formatNum(d));
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
for(let m=value[1]*1;m<=12;m++){
|
||||||
|
tmonths.push(this.formatNum(m));
|
||||||
|
};
|
||||||
|
for(let d=value[2]*1;d<=totalDays1;d++){
|
||||||
|
tdays.push(this.formatNum(d));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pickVal=[
|
||||||
|
fyears.indexOf(value[0])==-1?0:fyears.indexOf(value[0]),
|
||||||
|
fmonths.indexOf(value[1])==-1?0:fmonths.indexOf(value[1]),
|
||||||
|
fdays.indexOf(value[2])==-1?0:fdays.indexOf(value[2]),
|
||||||
|
0,
|
||||||
|
tyears.indexOf(value[4])==-1?0:tyears.indexOf(value[4]),
|
||||||
|
tmonths.indexOf(value[5])==-1?0:tmonths.indexOf(value[5]),
|
||||||
|
tdays.indexOf(value[6])==-1?0:tdays.indexOf(value[6])
|
||||||
|
];
|
||||||
|
return {
|
||||||
|
fyears,
|
||||||
|
fmonths,
|
||||||
|
fdays,
|
||||||
|
tyears,
|
||||||
|
tmonths,
|
||||||
|
tdays,
|
||||||
|
pickVal
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDval(){
|
||||||
|
let value=this.value;
|
||||||
|
let fields=this.fields;
|
||||||
|
let dVal=null;
|
||||||
|
let aDate=new Date();
|
||||||
|
let fyear=this.formatNum(aDate.getFullYear());
|
||||||
|
let fmonth=this.formatNum(aDate.getMonth()+1);
|
||||||
|
let fday=this.formatNum(aDate.getDate());
|
||||||
|
let tyear=this.formatNum(aDate.getFullYear());
|
||||||
|
let tmonth=this.formatNum(aDate.getMonth()+1);
|
||||||
|
let tday=this.formatNum(aDate.getDate());
|
||||||
|
if(value&&value.length>0){
|
||||||
|
let flag=this.checkValue(value);
|
||||||
|
if(!flag){
|
||||||
|
dVal=[fyear,fmonth,fday,"-",tyear,tmonth,tday]
|
||||||
|
}else{
|
||||||
|
dVal=[...value[0].split("-"),"-",...value[1].split("-")];
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
dVal=[fyear,fmonth,fday,"-",tyear,tmonth,tday]
|
||||||
|
}
|
||||||
|
return dVal;
|
||||||
|
},
|
||||||
|
initData(){
|
||||||
|
let range=[],pickVal=[];
|
||||||
|
let result="",full="",obj={};
|
||||||
|
let dVal=this.getDval();
|
||||||
|
let dateData=this.getData(dVal);
|
||||||
|
let fyears=[],fmonths=[],fdays=[],tyears=[],tmonths=[],tdays=[];
|
||||||
|
let fyear,fmonth,fday,tyear,tmonth,tday;
|
||||||
|
pickVal=dateData.pickVal;
|
||||||
|
fyears=dateData.fyears;
|
||||||
|
fmonths=dateData.fmonths;
|
||||||
|
fdays=dateData.fdays;
|
||||||
|
tyears=dateData.tyears;
|
||||||
|
tmonths=dateData.tmonths;
|
||||||
|
tdays=dateData.tdays;
|
||||||
|
range={
|
||||||
|
fyears,
|
||||||
|
fmonths,
|
||||||
|
fdays,
|
||||||
|
tyears,
|
||||||
|
tmonths,
|
||||||
|
tdays,
|
||||||
|
}
|
||||||
|
fyear=range.fyears[pickVal[0]];
|
||||||
|
fmonth=range.fmonths[pickVal[1]];
|
||||||
|
fday=range.fdays[pickVal[2]];
|
||||||
|
tyear=range.tyears[pickVal[4]];
|
||||||
|
tmonth=range.tmonths[pickVal[5]];
|
||||||
|
tday=range.tdays[pickVal[6]];
|
||||||
|
obj={
|
||||||
|
fyear,
|
||||||
|
fmonth,
|
||||||
|
fday,
|
||||||
|
tyear,
|
||||||
|
tmonth,
|
||||||
|
tday
|
||||||
|
}
|
||||||
|
result=`${fyear+'-'+fmonth+'-'+fday+'至'+tyear+'-'+tmonth+'-'+tday}`;
|
||||||
|
this.range=range;
|
||||||
|
this.checkObj=obj;
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.pickVal=pickVal;
|
||||||
|
});
|
||||||
|
this.$emit("change",{
|
||||||
|
result:result,
|
||||||
|
value:result.split("至"),
|
||||||
|
obj:obj
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handlerChange(e){
|
||||||
|
let arr=[...e.detail.value];
|
||||||
|
let result="",full="",obj={};
|
||||||
|
let year="",month="",day="",hour="",minute="",second="",note=[],province,city,area;
|
||||||
|
let checkObj=this.checkObj;
|
||||||
|
let days=[],months=[],endYears=[],endMonths=[],endDays=[],startDays=[];
|
||||||
|
let mode=this.mode;
|
||||||
|
let col1,col2,col3,d,a,h,m;
|
||||||
|
let xDate=new Date().getTime();
|
||||||
|
let range=this.range;
|
||||||
|
let fyear=range.fyears[arr[0]]||range.fyears[range.fyears.length-1];
|
||||||
|
let fmonth=range.fmonths[arr[1]]||range.fmonths[range.fmonths.length-1];
|
||||||
|
let fday=range.fdays[arr[2]]||range.fdays[range.fdays.length-1];
|
||||||
|
let tyear=range.tyears[arr[4]]||range.tyears[range.tyears.length-1];
|
||||||
|
let tmonth=range.tmonths[arr[5]]||range.tmonths[range.tmonths.length-1];
|
||||||
|
let tday=range.tdays[arr[6]]||range.tdays[range.tdays.length-1];
|
||||||
|
let resetData=this.resetData(fyear,fmonth,fday,tyear,tmonth);
|
||||||
|
if(fyear!=checkObj.fyear||fmonth!=checkObj.fmonth||fday!=checkObj.fday){
|
||||||
|
arr[4]=0;
|
||||||
|
arr[5]=0;
|
||||||
|
arr[6]=0;
|
||||||
|
range.tyears=resetData.tyears;
|
||||||
|
range.tmonths=resetData.tmonths;
|
||||||
|
range.tdays=resetData.tdays;
|
||||||
|
tyear=range.tyears[0];
|
||||||
|
checkObj.tyears=range.tyears[0];
|
||||||
|
tmonth=range.tmonths[0];
|
||||||
|
checkObj.tmonths=range.tmonths[0];
|
||||||
|
tday=range.tdays[0];
|
||||||
|
checkObj.tdays=range.tdays[0];
|
||||||
|
}
|
||||||
|
if(fyear!=checkObj.fyear||fmonth!=checkObj.fmonth){
|
||||||
|
range.fdays=resetData.fdays;
|
||||||
|
};
|
||||||
|
if(tyear!=checkObj.tyear){
|
||||||
|
arr[5]=0;
|
||||||
|
arr[6]=0;
|
||||||
|
let toData=this.resetToData(fmonth,fday,tyear,tmonth);
|
||||||
|
range.tmonths=toData.tmonths;
|
||||||
|
range.tdays=toData.tdays;
|
||||||
|
tmonth=range.tmonths[0];
|
||||||
|
checkObj.tmonths=range.tmonths[0];
|
||||||
|
tday=range.tdays[0];
|
||||||
|
checkObj.tdays=range.tdays[0];
|
||||||
|
};
|
||||||
|
if(tmonth!=checkObj.tmonth){
|
||||||
|
arr[6]=0;
|
||||||
|
let toData=this.resetToData(fmonth,fday,tyear,tmonth);
|
||||||
|
range.tdays=toData.tdays;
|
||||||
|
tday=range.tdays[0];
|
||||||
|
checkObj.tdays=range.tdays[0];
|
||||||
|
};
|
||||||
|
result=`${fyear+'-'+fmonth+'-'+fday+'至'+tyear+'-'+tmonth+'-'+tday}`;
|
||||||
|
obj={
|
||||||
|
fyear,fmonth,fday,tyear,tmonth,tday
|
||||||
|
}
|
||||||
|
this.checkObj=obj;
|
||||||
|
this.$nextTick(()=>{
|
||||||
|
this.pickVal=arr;
|
||||||
|
})
|
||||||
|
this.$emit("change",{
|
||||||
|
result:result,
|
||||||
|
value:result.split("至"),
|
||||||
|
obj:obj
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "./w-picker.css";
|
||||||
|
</style>
|
32
components/w-picker/w-picker.css
Normal file
32
components/w-picker/w-picker.css
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
.w-picker-flex2 {
|
||||||
|
flex: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker-flex1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker-view {
|
||||||
|
width: 100%;
|
||||||
|
height: 540upx;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: rgba(255, 255, 255, 1);
|
||||||
|
z-index: 666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.d-picker-view {
|
||||||
|
height: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
/* height: 88upx; */
|
||||||
|
/* line-height: 88upx; */
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 30upx;
|
||||||
|
}
|
285
components/w-picker/w-picker.vue
Normal file
285
components/w-picker/w-picker.vue
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
<template name="w-picker">
|
||||||
|
<view class="w-picker" :key="createKey" :data-key="createKey">
|
||||||
|
<view class="mask" :class="{ visible: visible }" @tap="onCancel" @touchmove.stop.prevent catchtouchmove="true"></view>
|
||||||
|
<view class="w-picker-cnt" :class="{ visible: visible }">
|
||||||
|
<view class="w-picker-header" @touchmove.stop.prevent catchtouchmove="true">
|
||||||
|
<text style="font-size: 18px">请选择时间</text>
|
||||||
|
<text @tap.stop.prevent="onCancel">
|
||||||
|
<u-icon name="close-circle" size="26"></u-icon>
|
||||||
|
</text>
|
||||||
|
<slot></slot>
|
||||||
|
<!-- <text :style="{ color: themeColor }" @tap.stop.prevent="pickerConfirm"
|
||||||
|
>确定</text
|
||||||
|
> -->
|
||||||
|
</view>
|
||||||
|
<date-picker v-if="mode == 'date'" class="w-picker-wrapper" :startYear="startYear" :endYear="endYear" :value="value"
|
||||||
|
:fields="fields" :item-height="itemHeight" :current="current" :disabled-after="disabledAfter"
|
||||||
|
:disabledBefore="disabledBefore"
|
||||||
|
@change="handlerChange" @touchstart="touchStart" @touchend="touchEnd">
|
||||||
|
</date-picker>
|
||||||
|
|
||||||
|
<range-picker v-if="mode == 'range'" class="w-picker-wrapper" :startYear="startYear" :endYear="endYear"
|
||||||
|
:value="value" :item-height="itemHeight" :current="current" @change="handlerChange" @touchstart="touchStart"
|
||||||
|
@touchend="touchEnd">
|
||||||
|
</range-picker>
|
||||||
|
|
||||||
|
<half-picker v-if="mode == 'half'" class="w-picker-wrapper" :startYear="startYear" :endYear="endYear" :value="value"
|
||||||
|
:item-height="itemHeight" :current="current" :disabled-after="disabledAfter" @change="handlerChange"
|
||||||
|
@touchstart="touchStart" @touchend="touchEnd">
|
||||||
|
</half-picker>
|
||||||
|
<view style="margin-bottom: 10px">
|
||||||
|
<u-button width="" text="确定" shape="circle" :style="{
|
||||||
|
color: '#fff',
|
||||||
|
width: '500upx',
|
||||||
|
backgroundColor: '#1936C9',
|
||||||
|
}" @click="pickerConfirm"></u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import datePicker from "./date-picker.vue";
|
||||||
|
import rangePicker from "./range-picker.vue";
|
||||||
|
import halfPicker from "./half-picker.vue";
|
||||||
|
export default {
|
||||||
|
name: "w-picker",
|
||||||
|
components: {
|
||||||
|
datePicker,
|
||||||
|
rangePicker,
|
||||||
|
halfPicker,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: "date",
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
//默认值
|
||||||
|
type: [String, Array, Number],
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
current: {
|
||||||
|
//是否默认显示当前时间,如果是,传的默认值将失效
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
themeColor: {
|
||||||
|
//确认按钮主题颜色
|
||||||
|
type: String,
|
||||||
|
default: "#f5a200",
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
//日期颗粒度:year、month、day、hour、minute、second
|
||||||
|
type: String,
|
||||||
|
default: "date",
|
||||||
|
},
|
||||||
|
disabledAfter: {
|
||||||
|
//是否禁用当前之后的日期
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
second: {
|
||||||
|
//time-picker是否显示秒
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
//selector,region数据源
|
||||||
|
type: [Array, Object],
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultProps: {
|
||||||
|
//selector,linkagle字段转换配置
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
label: "label",
|
||||||
|
value: "value",
|
||||||
|
children: "children",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
defaultType: {
|
||||||
|
type: String,
|
||||||
|
default: "label",
|
||||||
|
},
|
||||||
|
hideArea: {
|
||||||
|
//mode=region时,是否隐藏区县列
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
level: {
|
||||||
|
//多级联动层级,表示几级联动,区间2-4;
|
||||||
|
type: [Number, String],
|
||||||
|
default: 2,
|
||||||
|
},
|
||||||
|
timeout: {
|
||||||
|
//是否开启点击延迟,当快速滚动 还没有滚动完毕点击关闭时得到的值是不准确的
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
expand: {
|
||||||
|
//mode=shortterm 默认往后拓展天数
|
||||||
|
type: [Number, String],
|
||||||
|
default: 30,
|
||||||
|
},
|
||||||
|
startYear: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 1970,
|
||||||
|
},
|
||||||
|
endYear: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: new Date().getFullYear(),
|
||||||
|
},
|
||||||
|
visible: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
//不是插件自带为了组件复用故意传参数
|
||||||
|
timeType: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
// disabledMonth: {
|
||||||
|
// type: Number,
|
||||||
|
// default: 0,
|
||||||
|
// },
|
||||||
|
// disabledRange: {
|
||||||
|
// type: Array,
|
||||||
|
// default: ''
|
||||||
|
// },
|
||||||
|
disabledBefore: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.createKey = Math.random() * 1000;
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
itemHeight: `height: ${uni.upx2px(88)}px;`,
|
||||||
|
result: {},
|
||||||
|
confirmFlag: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
touchStart() {
|
||||||
|
if (this.timeout) {
|
||||||
|
this.confirmFlag = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
touchEnd() {
|
||||||
|
if (this.timeout) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.confirmFlag = true;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handlerChange(res) {
|
||||||
|
let _this = this;
|
||||||
|
this.result = { ...res };
|
||||||
|
},
|
||||||
|
show() {
|
||||||
|
this.$emit("update:visible", true);
|
||||||
|
},
|
||||||
|
hide() {
|
||||||
|
this.$emit("update:visible", false);
|
||||||
|
},
|
||||||
|
onCancel(res) {
|
||||||
|
this.$emit("update:visible", false);
|
||||||
|
this.$emit("cancel");
|
||||||
|
},
|
||||||
|
pickerConfirm() {
|
||||||
|
if (!this.confirmFlag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$emit("confirm", { timeType: this.timeType, ...this.result });
|
||||||
|
this.$emit("update:visible", false);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.w-picker-item {
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 88upx;
|
||||||
|
line-height: 88upx;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: 30upx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker {
|
||||||
|
z-index: 888;
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 1000;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.6);
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask.visible {
|
||||||
|
visibility: visible;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker-cnt {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
transform: translateY(100%);
|
||||||
|
z-index: 3000;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker-cnt.visible {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12upx 30upx;
|
||||||
|
height: 88upx;
|
||||||
|
background-color: #fff;
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32upx;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-bottom: solid 1px #eee;
|
||||||
|
border-radius: 10upx 0;
|
||||||
|
|
||||||
|
.w-picker-btn {
|
||||||
|
font-size: 30upx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.w-picker-hd:after {
|
||||||
|
content: " ";
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 1px;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
color: #e5e5e5;
|
||||||
|
transform-origin: 0 100%;
|
||||||
|
transform: scaleY(0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
7
http/api.js
Normal file
7
http/api.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default {
|
||||||
|
// backUrl: 'http://172.16.100.93:9023',
|
||||||
|
// backUrl: 'https://appointtest.szjixun.cn',
|
||||||
|
// backUrl: 'https://appoint.szjixun.cn',
|
||||||
|
// backUrl: "https://appointtest2.szjixun.cn",
|
||||||
|
backUrl: "http://114.218.158.24:9020",
|
||||||
|
};
|
13
http/index.js
Normal file
13
http/index.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import http from './interface'
|
||||||
|
|
||||||
|
export const request = (url, data, type) => {
|
||||||
|
return http.request({
|
||||||
|
url: url,
|
||||||
|
method: type || 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
request,
|
||||||
|
}
|
175
http/interface.js
Normal file
175
http/interface.js
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
/**
|
||||||
|
* 通用uni-app网络请求
|
||||||
|
* 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截
|
||||||
|
*/
|
||||||
|
import apiUrl from "./api";
|
||||||
|
export default {
|
||||||
|
config: {
|
||||||
|
baseUrl: "http://114.218.158.24:9020",
|
||||||
|
//"https://appointtest2.szjixun.cn",
|
||||||
|
// "https://appointteam.szjixun.cn",
|
||||||
|
header: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
// 'Content-Type':'application/x-www-form-urlencoded'
|
||||||
|
},
|
||||||
|
data: {},
|
||||||
|
method: "GET",
|
||||||
|
dataType: "json" /* 如设为json,会对返回的数据做一次 JSON.parse */,
|
||||||
|
responseType: "text",
|
||||||
|
success() {},
|
||||||
|
fail() {},
|
||||||
|
complete() {},
|
||||||
|
},
|
||||||
|
interceptor: {
|
||||||
|
request: null,
|
||||||
|
response: null,
|
||||||
|
},
|
||||||
|
request(options) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
options.baseUrl = options.baseUrl || this.config.baseUrl;
|
||||||
|
options.dataType = options.dataType || this.config.dataType;
|
||||||
|
options.url = options.baseUrl + options.url;
|
||||||
|
options.data = options.data || {};
|
||||||
|
options.method = options.method || this.config.method;
|
||||||
|
//TODO 加密数据
|
||||||
|
options.header = options.header || this.config.header;
|
||||||
|
//TODO 数据签名
|
||||||
|
let _token = {
|
||||||
|
Authorization: uni.getStorageSync("pay-token") || "46d71a72d8d845ad7ed23eba9bdde260e635407190c2ce1bf7fd22088e41682ea07773ec65cae8946d2003f264d55961f96e0fc5da10eb96d3a348c1664e9644e756eda7154e1af9e70d1c9d2f100823a26885ea6df3249fe619995cb79dc5dbd5ead32d43b955d6b3ce83129097bb21bb8169898f48692de4f966db140c71b85a2065acfc948561c465279fc05194a79a1115f3b00170944b6c4bd6c52ada909a075c55d18d76c2ed2175602421b34b27362a05c350733ed73382471df0a08950f7f1e812a610c17bdac82d82d54be38969f6b41201af79b8d36ef177c5b94b180c1e16c357f434e29e022c62394499059c937382faf6e496d68b48d5f0c8770bff6906979526141dacb14bb2edae6f0325160574152e3f7a0944600210214ba274ed1e49813121ce451c0016e420ea0634a8e6936726c5d09024d22202c8d0",
|
||||||
|
tokenC: uni.getStorageSync("pay-token") || "undefined",
|
||||||
|
};
|
||||||
|
options.header = Object.assign({}, options.header, _token);
|
||||||
|
/*
|
||||||
|
_sign = {'sign': sign(JSON.stringify(options.data))}
|
||||||
|
options.header = Object.assign({}, options.header, _token,_sign)
|
||||||
|
*/
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let _config = null;
|
||||||
|
|
||||||
|
options.complete = (response) => {
|
||||||
|
let statusCode = response.statusCode;
|
||||||
|
response.config = _config;
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
if (statusCode === 200) {
|
||||||
|
// console.log("【" + _config.requestId + "】 结果:" + JSON.stringify(response.data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.interceptor.response) {
|
||||||
|
let newResponse = this.interceptor.response(response);
|
||||||
|
if (newResponse) {
|
||||||
|
response = newResponse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (document.cookie?.split("=")[1] && response.data.status === 401) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url:
|
||||||
|
"/pages/verify/login?id=" +
|
||||||
|
uni.getStorageSync("verifyDataId") +
|
||||||
|
"&type=" +
|
||||||
|
uni.getStorageSync("type"),
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 统一的响应日志记录
|
||||||
|
_reslog(response);
|
||||||
|
if (statusCode === 200) {
|
||||||
|
//成功
|
||||||
|
resolve(response.data);
|
||||||
|
} else {
|
||||||
|
reject(response);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
_config = Object.assign({}, this.config, options);
|
||||||
|
_config.requestId = new Date().getTime();
|
||||||
|
|
||||||
|
if (this.interceptor.request) {
|
||||||
|
this.interceptor.request(_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 统一的请求日志记录
|
||||||
|
_reqlog(_config);
|
||||||
|
|
||||||
|
uni.request(_config);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
get(url, data, options) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
options.url = url;
|
||||||
|
options.data = data;
|
||||||
|
options.method = "GET";
|
||||||
|
return this.request(options);
|
||||||
|
},
|
||||||
|
post(url, data, options, header) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
options.url = url;
|
||||||
|
options.data = data;
|
||||||
|
options.header = header;
|
||||||
|
options.method = "POST";
|
||||||
|
return this.request(options);
|
||||||
|
},
|
||||||
|
put(url, data, options) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
options.url = url;
|
||||||
|
options.data = data;
|
||||||
|
options.method = "PUT";
|
||||||
|
return this.request(options);
|
||||||
|
},
|
||||||
|
delete(url, data, options) {
|
||||||
|
if (!options) {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
options.url = url;
|
||||||
|
options.data = data;
|
||||||
|
options.method = "DELETE";
|
||||||
|
return this.request(options);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 请求接口日志记录
|
||||||
|
*/
|
||||||
|
function _reqlog(req) {
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
// console.log("【" + req.requestId + "】 地址:" + req.url)
|
||||||
|
if (req.data) {
|
||||||
|
// console.log("【" + req.requestId + "】 请求参数:" + JSON.stringify(req.data))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO 调接口异步写入日志数据库
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应接口日志记录
|
||||||
|
*/
|
||||||
|
function _reslog(res) {
|
||||||
|
let _statusCode = res.statusCode;
|
||||||
|
if (process.env.NODE_ENV === "development") {
|
||||||
|
// console.log("【" + res.config.requestId + "】 地址:" + res.config.url)
|
||||||
|
if (res.config.data) {
|
||||||
|
// console.log("【" + res.config.requestId + "】 请求参数:" + JSON.stringify(res.config.data))
|
||||||
|
}
|
||||||
|
// console.log("【" + res.config.requestId + "】 响应结果:" + JSON.stringify(res))
|
||||||
|
}
|
||||||
|
//TODO 除了接口服务错误外,其他日志调接口异步写入日志数据库
|
||||||
|
switch (_statusCode) {
|
||||||
|
case 200:
|
||||||
|
break;
|
||||||
|
case 401:
|
||||||
|
break;
|
||||||
|
case 404:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
25
index.html
Normal file
25
index.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script>
|
||||||
|
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||||
|
CSS.supports('top: constant(a)'))
|
||||||
|
document.write(
|
||||||
|
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
|
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||||
|
</script>
|
||||||
|
<title></title>
|
||||||
|
<!--preload-links-->
|
||||||
|
<!--app-context-->
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
|
<!--app-html-->
|
||||||
|
</div>
|
||||||
|
<script type="module" src="/main.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
24
main.js
Normal file
24
main.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import App from "./App";
|
||||||
|
|
||||||
|
import Vue from "vue";
|
||||||
|
import uView from "uview-ui";
|
||||||
|
import store from "./store/index.js";
|
||||||
|
import common from "./common/index.js";
|
||||||
|
import api from "@/http/";
|
||||||
|
import moment from "moment";
|
||||||
|
import ww from "chinese-workday";
|
||||||
|
|
||||||
|
Vue.use(uView);
|
||||||
|
Vue.prototype.$api = api;
|
||||||
|
Vue.prototype.$common = common;
|
||||||
|
Vue.prototype.$moment = moment;
|
||||||
|
Vue.prototype.$isWorkday = ww.isWorkday;
|
||||||
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
|
// Vue.config.ignoredElements.push("wx-open-launch-weapp");
|
||||||
|
App.mpType = "app";
|
||||||
|
const app = new Vue({
|
||||||
|
...App,
|
||||||
|
store,
|
||||||
|
});
|
||||||
|
app.$mount();
|
139
manifest.json
Normal file
139
manifest.json
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"name" : "FONCHAT",
|
||||||
|
"appid" : "__UNI__84B5B31",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.1",
|
||||||
|
"versionCode" : 101,
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : true,
|
||||||
|
"waiting" : true,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"distribute" : {
|
||||||
|
/* android打包配置 */
|
||||||
|
"android" : {
|
||||||
|
"permissions" : [
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||||
|
],
|
||||||
|
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ]
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {
|
||||||
|
"dSYMs" : false
|
||||||
|
},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"ad" : {}
|
||||||
|
},
|
||||||
|
"icons" : {
|
||||||
|
"android" : {
|
||||||
|
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||||
|
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||||
|
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||||
|
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||||
|
},
|
||||||
|
"ios" : {
|
||||||
|
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||||
|
"ipad" : {
|
||||||
|
"app" : "unpackage/res/icons/76x76.png",
|
||||||
|
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||||
|
"notification" : "unpackage/res/icons/20x20.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||||
|
"settings" : "unpackage/res/icons/29x29.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||||
|
},
|
||||||
|
"iphone" : {
|
||||||
|
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||||
|
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||||
|
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true,
|
||||||
|
"unipush" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"permission" : {
|
||||||
|
"scope.userLocation" : {
|
||||||
|
"desc" : ""
|
||||||
|
},
|
||||||
|
"permission" : {
|
||||||
|
"jsApiDomain" : "https://appointteam.szjixun.cn"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "2",
|
||||||
|
"h5" : {
|
||||||
|
"template" : "",
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"maps" : {
|
||||||
|
"amap" : {
|
||||||
|
"key" : "e152c1daf64d0f1d1b2370d4e58ebed7",
|
||||||
|
"securityJsCode" : "23a195cc14b23f62e7203f3ad91fd43c",
|
||||||
|
"serviceHost" : ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"publicPath" : "./",
|
||||||
|
"router" : {
|
||||||
|
"base" : ""
|
||||||
|
},
|
||||||
|
"devServer" : {
|
||||||
|
"https" : false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
63
package-lock.json
generated
Normal file
63
package-lock.json
generated
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"name": "日期区间picker",
|
||||||
|
"version": "1.0.7",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "日期区间picker",
|
||||||
|
"version": "1.0.7",
|
||||||
|
"dependencies": {
|
||||||
|
"chinese-workday": "^1.9.0",
|
||||||
|
"jweixin-module": "^1.6.0",
|
||||||
|
"moment": "^2.29.4",
|
||||||
|
"weixin-js-sdk": "^1.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chinese-workday": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/chinese-workday/-/chinese-workday-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-qXxFBFpMQzCaHOBs4VnVEVnTySWkCfxE/1fSbibtrJIB+qnjioDrjgQtXAzCvaqKndhYKS6PVl4BPtv/gMCO+w=="
|
||||||
|
},
|
||||||
|
"node_modules/jweixin-module": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
|
||||||
|
},
|
||||||
|
"node_modules/moment": {
|
||||||
|
"version": "2.29.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
|
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/weixin-js-sdk": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"chinese-workday": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/chinese-workday/-/chinese-workday-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-qXxFBFpMQzCaHOBs4VnVEVnTySWkCfxE/1fSbibtrJIB+qnjioDrjgQtXAzCvaqKndhYKS6PVl4BPtv/gMCO+w=="
|
||||||
|
},
|
||||||
|
"jweixin-module": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/jweixin-module/-/jweixin-module-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-dGk9cf+ipipHmtzYmKZs5B2toX+p4hLyllGLF6xuC8t+B05oYxd8fYoaRz0T30U2n3RUv8a4iwvjhA+OcYz52w=="
|
||||||
|
},
|
||||||
|
"moment": {
|
||||||
|
"version": "2.29.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
|
||||||
|
"integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
|
||||||
|
},
|
||||||
|
"weixin-js-sdk": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz",
|
||||||
|
"integrity": "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
package.json
Normal file
25
package.json
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"id": "pyh-rdtpicker",
|
||||||
|
"name": "日期区间picker",
|
||||||
|
"version": "1.0.7",
|
||||||
|
"description": "日期区间选择组件,可选粒度,可自定义主题",
|
||||||
|
"keywords": [
|
||||||
|
"日期",
|
||||||
|
"区间",
|
||||||
|
"时间",
|
||||||
|
"组件",
|
||||||
|
"选择"
|
||||||
|
],
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"前端组件",
|
||||||
|
"通用组件"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"chinese-workday": "^1.9.0",
|
||||||
|
"jweixin-module": "^1.6.0",
|
||||||
|
"moment": "^2.29.4",
|
||||||
|
"weixin-js-sdk": "^1.6.0"
|
||||||
|
}
|
||||||
|
}
|
29
pages.json
Normal file
29
pages.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"easycom": {
|
||||||
|
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
|
||||||
|
},
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
// 首页
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "FONCHAT",
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false // 禁用原生导航
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "uni-app",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
},
|
||||||
|
|
||||||
|
"uniIdRouter": {}
|
||||||
|
}
|
656
pages/index/index.vue
Normal file
656
pages/index/index.vue
Normal file
@ -0,0 +1,656 @@
|
|||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<view class="top-bar">
|
||||||
|
<image
|
||||||
|
@click="changeMode"
|
||||||
|
class="version"
|
||||||
|
:src="
|
||||||
|
isGPT3 ? '../../static/image/3.5.png' : '../../static/image/4.0.png'
|
||||||
|
" />
|
||||||
|
<view class="title">FONCHAT</view>
|
||||||
|
<view></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bottom">
|
||||||
|
<div v-show="!acqStatus">
|
||||||
|
<div class="line"></div>
|
||||||
|
</div>
|
||||||
|
<view
|
||||||
|
class="chat-content"
|
||||||
|
id="chat-content"
|
||||||
|
ref="chatContent">
|
||||||
|
<view
|
||||||
|
class="chat-wrapper"
|
||||||
|
v-for="(item, index) in chatList"
|
||||||
|
:key="index">
|
||||||
|
<view
|
||||||
|
class="chat-friend"
|
||||||
|
v-if="item.uid !== 'admin'">
|
||||||
|
<span style="color: #175abd"
|
||||||
|
>客服AI<span
|
||||||
|
style="font-size: 20rpx"
|
||||||
|
v-show="!acqStatus && index === chatList.length - 1"
|
||||||
|
>(正在思索……)</span
|
||||||
|
></span
|
||||||
|
>
|
||||||
|
<image
|
||||||
|
style="
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
position: absolute;
|
||||||
|
left: -48px;
|
||||||
|
top: 5px;
|
||||||
|
"
|
||||||
|
src="../../static/image/avator.png" />
|
||||||
|
<view
|
||||||
|
class="chat-text"
|
||||||
|
v-if="item.chatType == 0">
|
||||||
|
<view v-if="item.msg" class="chat-word">{{ item.msg }}</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="chat-image"
|
||||||
|
v-if="item.chatType == 1">
|
||||||
|
<image
|
||||||
|
:src="item.msg"
|
||||||
|
alt="表情"
|
||||||
|
v-if="item.extend.imageType == 1"
|
||||||
|
style="width: 100px; height: 100px" />
|
||||||
|
<image
|
||||||
|
style="border-radius: 10px"
|
||||||
|
:src="item.msg"
|
||||||
|
v-else>
|
||||||
|
</image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="chat-me"
|
||||||
|
v-else>
|
||||||
|
<image
|
||||||
|
:src="item.headimage"
|
||||||
|
alt=""
|
||||||
|
style="
|
||||||
|
height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
position: absolute;
|
||||||
|
right: -48px;
|
||||||
|
top: 5px;
|
||||||
|
" />
|
||||||
|
<view
|
||||||
|
class="chat-text"
|
||||||
|
v-if="item.chatType == 0">
|
||||||
|
<span style="font-size: 16px">{{ item.msg }}</span>
|
||||||
|
</view>
|
||||||
|
<view
|
||||||
|
class="chat-image"
|
||||||
|
v-if="item.chatType == 1">
|
||||||
|
<image
|
||||||
|
:src="item.msg"
|
||||||
|
alt="表情"
|
||||||
|
v-if="item.extend.imageType == 1"
|
||||||
|
style="width: 100px; height: 100px" />
|
||||||
|
<a-image
|
||||||
|
style="max-width: 300px; border-radius: 10px"
|
||||||
|
:src="item.msg"
|
||||||
|
v-else>
|
||||||
|
</a-image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 下面是两个是占位元素 -->
|
||||||
|
<view style="height: 12vh"></view>
|
||||||
|
<view class="text-area"> </view>
|
||||||
|
<view
|
||||||
|
class="text-area"
|
||||||
|
style="position: fixed">
|
||||||
|
<u--input
|
||||||
|
style="
|
||||||
|
width: 500rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
background-color: #d8d8d8;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
"
|
||||||
|
:disabled="!acqStatus"
|
||||||
|
@confirm="sendText"
|
||||||
|
v-model="inputMsg"
|
||||||
|
border="none"
|
||||||
|
placeholder="请输入内容"></u--input>
|
||||||
|
<u-button
|
||||||
|
style="
|
||||||
|
border-radius: 40rpx;
|
||||||
|
width: 120rpx;
|
||||||
|
height: 64rpx;
|
||||||
|
background-color: #175abd;
|
||||||
|
"
|
||||||
|
@click="sendText"
|
||||||
|
type="primary"
|
||||||
|
text="发送"></u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from "@/http/";
|
||||||
|
import moment from "moment";
|
||||||
|
import {
|
||||||
|
OPENAI_API_KEY,
|
||||||
|
GPT_MODEL,
|
||||||
|
FREQUENCY_PENALTY,
|
||||||
|
MAX_TOKENS,
|
||||||
|
PRESENCE_PENALTY,
|
||||||
|
TEMPERATURE,
|
||||||
|
TOP_P,
|
||||||
|
} from "utils/openAiConfig";
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
chatList: [],
|
||||||
|
inputMsg: "",
|
||||||
|
acqStatus: true,
|
||||||
|
gptMode: "gpt-3.5-turbo",
|
||||||
|
isGPT3: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad(item) {},
|
||||||
|
methods: {
|
||||||
|
//发送文字信息
|
||||||
|
sendText() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.acqStatus = false;
|
||||||
|
});
|
||||||
|
const dateNow = moment().format("YYYY/M/DD/ HH:mm:ss");
|
||||||
|
let params = {};
|
||||||
|
console.log(this.inputMsg);
|
||||||
|
if (this.inputMsg) {
|
||||||
|
let chatMsg = {
|
||||||
|
headimage: "../../static/image/head.jpg",
|
||||||
|
name: GPT_MODEL,
|
||||||
|
time: dateNow,
|
||||||
|
msg: this.inputMsg,
|
||||||
|
chatType: 0, //信息类型,0文字,1图片
|
||||||
|
uid: "admin", //uid
|
||||||
|
};
|
||||||
|
console.log(chatMsg, 888);
|
||||||
|
this.sendMsg(chatMsg);
|
||||||
|
|
||||||
|
//如果是文字模式则进入
|
||||||
|
(params.model = this.gptMode),
|
||||||
|
(params.max_tokens = MAX_TOKENS),
|
||||||
|
(params.temperature = TEMPERATURE),
|
||||||
|
(params.top_p = TOP_P),
|
||||||
|
(params.presence_penalty = PRESENCE_PENALTY),
|
||||||
|
(params.frequency_penalty = FREQUENCY_PENALTY);
|
||||||
|
|
||||||
|
let chatBeforResMsg = {
|
||||||
|
headimage: "",
|
||||||
|
name: "",
|
||||||
|
time: moment().format("YYYY/M/DD/ HH:mm:ss"),
|
||||||
|
msg: "",
|
||||||
|
chatType: 0, //信息类型,0文字,1图片
|
||||||
|
uid: "ai", //uid
|
||||||
|
};
|
||||||
|
this.chatCompletion(params, chatBeforResMsg);
|
||||||
|
|
||||||
|
this.inputMsg = "";
|
||||||
|
} else {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.acqStatus = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 自动滚动到底部
|
||||||
|
scrollToBottom() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
uni
|
||||||
|
.createSelectorQuery()
|
||||||
|
.select(".chat-content")
|
||||||
|
.boundingClientRect((data) => {
|
||||||
|
uni.pageScrollTo({
|
||||||
|
duration: 100, //过渡时间
|
||||||
|
scrollTop: 1600, //到达目标class的top值
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.exec();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 切换模式
|
||||||
|
changeMode(e) {
|
||||||
|
this.acqStatus = true;
|
||||||
|
this.isGPT3 = !this.isGPT3;
|
||||||
|
this.gptMode = this.isGPT3 ? "gpt-3.5-turbo" : "gpt-4";
|
||||||
|
// 清空对话
|
||||||
|
this.chatList = [];
|
||||||
|
},
|
||||||
|
// 从接口获取对话结果
|
||||||
|
async chatCompletion(params, chatBeforResMsg) {
|
||||||
|
let conversation = this.contextualAssemblyData();
|
||||||
|
params.messages = conversation.map((item) => {
|
||||||
|
return {
|
||||||
|
role: item.speaker === "user" ? "user" : "assistant",
|
||||||
|
content: item.text,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
params.stream = true;
|
||||||
|
//新增一个空的消息
|
||||||
|
this.sendMsg(chatBeforResMsg);
|
||||||
|
|
||||||
|
const currentResLocation = this.chatList.length - 1;
|
||||||
|
// 获取当前环境地址
|
||||||
|
const baseUrl = "http://114.218.158.24:9020/";
|
||||||
|
try {
|
||||||
|
uni.request({
|
||||||
|
url: baseUrl + "chat/app-completion", //你的接口地址
|
||||||
|
method: "POST",
|
||||||
|
data: JSON.stringify(params),
|
||||||
|
|
||||||
|
header: {
|
||||||
|
"Content-Type": "text/event-stream",
|
||||||
|
Accept: "application/json",
|
||||||
|
Authorization: "",
|
||||||
|
},
|
||||||
|
success: (response) => {
|
||||||
|
// 在这里处理你的响应数据
|
||||||
|
console.log(response.data, 123);
|
||||||
|
if (response.data) {
|
||||||
|
if (response.data.data.content) {
|
||||||
|
this.chatList[currentResLocation].msg =
|
||||||
|
response.data.data.content;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.acqStatus = true;
|
||||||
|
});
|
||||||
|
this.scrollToBottom();
|
||||||
|
} else {
|
||||||
|
this.chatList[currentResLocation].msg =
|
||||||
|
"我还在学习中,等我学习完再来问我吧!";
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.acqStatus = true;
|
||||||
|
});
|
||||||
|
this.scrollToBottom();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error(err);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//组装上下文数据
|
||||||
|
contextualAssemblyData() {
|
||||||
|
const conversation = [];
|
||||||
|
for (var chat of this.chatList) {
|
||||||
|
if (chat.uid == "admin") {
|
||||||
|
let my = { speaker: "user", text: chat.msg };
|
||||||
|
conversation.push(my);
|
||||||
|
} else if (chat.uid == "ai") {
|
||||||
|
let ai = { speaker: "agent", text: chat.msg };
|
||||||
|
conversation.push(ai);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return conversation;
|
||||||
|
},
|
||||||
|
// 发送信息
|
||||||
|
sendMsg(msgList) {
|
||||||
|
this.chatList.push(msgList);
|
||||||
|
this.scrollToBottom();
|
||||||
|
},
|
||||||
|
// 当监听到向上滚动的时候
|
||||||
|
scrollToUpper() {
|
||||||
|
console.log("滚动到顶部");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.uni-body {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
background-size: auto 100%;
|
||||||
|
background-attachment: fixed;
|
||||||
|
}
|
||||||
|
page {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
background-size: auto 100%;
|
||||||
|
background-attachment: fixed;
|
||||||
|
}
|
||||||
|
/deep/ .u-input__content {
|
||||||
|
color: #fff;
|
||||||
|
padding-left: 40rpx;
|
||||||
|
}
|
||||||
|
.text-area {
|
||||||
|
// position: fixed;
|
||||||
|
width: 95%;
|
||||||
|
bottom: 0;
|
||||||
|
height: 6vh;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 30rpx 40rpx 0rpx 20rpx;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
width: 97%;
|
||||||
|
background-color: #fff;
|
||||||
|
background-size: auto 100%;
|
||||||
|
background-attachment: fixed;
|
||||||
|
height: 100%;
|
||||||
|
// overflow: hidden;
|
||||||
|
.top-bar {
|
||||||
|
width: 100%;
|
||||||
|
z-index: 100;
|
||||||
|
position: fixed;
|
||||||
|
height: 180rpx;
|
||||||
|
// 背景色渐变
|
||||||
|
background: linear-gradient(to bottom, #175abd 0%, #25a7f2 100%);
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
justify-content: space-between;
|
||||||
|
.version {
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
width: 100rpx;
|
||||||
|
height: 56rpx;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 120rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom {
|
||||||
|
width: 100%;
|
||||||
|
height: 80vh;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
// background-color: rgb(50, 54, 68);
|
||||||
|
border-radius: 20px;
|
||||||
|
padding: 99px 20px 20px 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.chat-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
// overflow-y: scroll;
|
||||||
|
// overflow-x: hidden;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
width: 3px;
|
||||||
|
/* 设置滚动条宽度 */
|
||||||
|
}
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #8b67ef;
|
||||||
|
/* 设置滚动条滑块的背景色 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-friend {
|
||||||
|
width: 100%;
|
||||||
|
float: left;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
margin-left: 30px;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.chat-text {
|
||||||
|
float: left;
|
||||||
|
max-width: 90%;
|
||||||
|
padding: 15px;
|
||||||
|
color: #535353;
|
||||||
|
border-radius: 20px 20px 20px 5px;
|
||||||
|
border: 1px solid #d8d8d8;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-image {
|
||||||
|
image {
|
||||||
|
max-width: 300px;
|
||||||
|
max-height: 200px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-time {
|
||||||
|
margin: 10px 0;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
color: #8b67ef;
|
||||||
|
image {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span:last-child {
|
||||||
|
margin-left: 10px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-me {
|
||||||
|
width: 100%;
|
||||||
|
float: right;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
position: relative;
|
||||||
|
margin-right: 28px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
.chat-text {
|
||||||
|
float: right;
|
||||||
|
max-width: 90%;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 20px 20px 5px 20px;
|
||||||
|
background-color: #175abd;
|
||||||
|
color: #fff;
|
||||||
|
word-break: break-all;
|
||||||
|
// 让文字一个一个显示
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-image {
|
||||||
|
image {
|
||||||
|
max-width: 300px;
|
||||||
|
max-height: 200px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-time {
|
||||||
|
margin: 10px 0;
|
||||||
|
color: #8b67ef;
|
||||||
|
font-size: 14px;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span:first-child {
|
||||||
|
margin-right: 10px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chatInputs {
|
||||||
|
width: 90%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
margin: 3%;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.boxinput {
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: rgb(50, 54, 68);
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 1px solid rgb(80, 85, 103);
|
||||||
|
box-shadow: 0px 0px 5px 0px rgb(0, 136, 255);
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji {
|
||||||
|
transition: 0.3s;
|
||||||
|
width: 50px;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.luyin {
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 1.5%;
|
||||||
|
font-size: 30px;
|
||||||
|
text-align: center;
|
||||||
|
transition: 0.3s;
|
||||||
|
width: 50px;
|
||||||
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.inputs {
|
||||||
|
width: 95%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: rgb(66, 70, 86);
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 2px solid rgb(34, 135, 225);
|
||||||
|
padding: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
transition: 0.2s;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 100;
|
||||||
|
margin: 0 20px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.line {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
margin-left: 2%;
|
||||||
|
height: 2px;
|
||||||
|
background: linear-gradient(to right, #175abd 0%, #25a7f2 100%);
|
||||||
|
animation: shrink-and-expand 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line::before,
|
||||||
|
.line::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
background: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line::before {
|
||||||
|
border-top-left-radius: 2px;
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
left: 0;
|
||||||
|
transform-origin: left;
|
||||||
|
animation: shrink-left 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line::after {
|
||||||
|
border-top-left-radius: 2px;
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
right: 0;
|
||||||
|
transform-origin: right;
|
||||||
|
animation: shrink-right 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shrink-and-expand {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shrink-left {
|
||||||
|
0%,
|
||||||
|
50% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50.1%,
|
||||||
|
100% {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shrink-right {
|
||||||
|
0%,
|
||||||
|
50% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
50.1%,
|
||||||
|
100% {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.chat-word {
|
||||||
|
// 文字缓慢出现
|
||||||
|
animation: word 1s linear;
|
||||||
|
}
|
||||||
|
@keyframes word {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
29
project.config.json
Normal file
29
project.config.json
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"appid": "wx1e155fd041eda3be",
|
||||||
|
"compileType": "miniprogram",
|
||||||
|
"libVersion": "2.31.1",
|
||||||
|
"packOptions": {
|
||||||
|
"ignore": [],
|
||||||
|
"include": []
|
||||||
|
},
|
||||||
|
"setting": {
|
||||||
|
"coverView": true,
|
||||||
|
"es6": true,
|
||||||
|
"postcss": true,
|
||||||
|
"minified": true,
|
||||||
|
"enhance": true,
|
||||||
|
"showShadowRootInWxmlPanel": true,
|
||||||
|
"packNpmRelationList": [],
|
||||||
|
"babelSetting": {
|
||||||
|
"ignore": [],
|
||||||
|
"disablePlugins": [],
|
||||||
|
"outputPath": ""
|
||||||
|
},
|
||||||
|
"condition": false
|
||||||
|
},
|
||||||
|
"condition": {},
|
||||||
|
"editorSetting": {
|
||||||
|
"tabIndent": "insertSpaces",
|
||||||
|
"tabSize": 2
|
||||||
|
}
|
||||||
|
}
|
7
project.private.config.json
Normal file
7
project.private.config.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
|
||||||
|
"projectname": "FuchuanMountainHall",
|
||||||
|
"setting": {
|
||||||
|
"compileHotReLoad": true
|
||||||
|
}
|
||||||
|
}
|
BIN
static/image/3.5.png
Normal file
BIN
static/image/3.5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.3 KiB |
BIN
static/image/4.0.png
Normal file
BIN
static/image/4.0.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
BIN
static/image/avator.png
Normal file
BIN
static/image/avator.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
BIN
static/image/head.jpg
Normal file
BIN
static/image/head.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
static/image/shop-car.png
Normal file
BIN
static/image/shop-car.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.6 KiB |
BIN
static/image/success.png
Normal file
BIN
static/image/success.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 KiB |
16
store/index.js
Normal file
16
store/index.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
Vue.use(Vuex)
|
||||||
|
|
||||||
|
const store = new Vuex.Store({
|
||||||
|
state: {
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
export default store
|
10
uni.promisify.adaptor.js
Normal file
10
uni.promisify.adaptor.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
uni.addInterceptor({
|
||||||
|
returnValue (res) {
|
||||||
|
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
77
uni.scss
Normal file
77
uni.scss
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/**
|
||||||
|
* 这里是uni-app内置的常用样式变量
|
||||||
|
*
|
||||||
|
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||||
|
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||||
|
*
|
||||||
|
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||||
|
*/
|
||||||
|
@import 'uview-ui/theme.scss';
|
||||||
|
|
||||||
|
/* 颜色变量 */
|
||||||
|
|
||||||
|
/* 行为相关颜色 */
|
||||||
|
$uni-color-primary: #007aff;
|
||||||
|
$uni-color-success: #4cd964;
|
||||||
|
$uni-color-warning: #f0ad4e;
|
||||||
|
$uni-color-error: #dd524d;
|
||||||
|
|
||||||
|
/* 文字基本颜色 */
|
||||||
|
$uni-text-color:#333;//基本色
|
||||||
|
$uni-text-color-inverse:#fff;//反色
|
||||||
|
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||||
|
$uni-text-color-placeholder: #808080;
|
||||||
|
$uni-text-color-disable:#c0c0c0;
|
||||||
|
|
||||||
|
/* 背景颜色 */
|
||||||
|
$uni-bg-color:#ffffff;
|
||||||
|
$uni-bg-color-grey:#f8f8f8;
|
||||||
|
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||||
|
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
$uni-border-color:#c8c7cc;
|
||||||
|
|
||||||
|
/* 尺寸变量 */
|
||||||
|
|
||||||
|
/* 文字尺寸 */
|
||||||
|
$uni-font-size-sm:12px;
|
||||||
|
$uni-font-size-base:14px;
|
||||||
|
$uni-font-size-lg:16;
|
||||||
|
|
||||||
|
/* 图片尺寸 */
|
||||||
|
$uni-img-size-sm:20px;
|
||||||
|
$uni-img-size-base:26px;
|
||||||
|
$uni-img-size-lg:40px;
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
$uni-border-radius-sm: 2px;
|
||||||
|
$uni-border-radius-base: 3px;
|
||||||
|
$uni-border-radius-lg: 6px;
|
||||||
|
$uni-border-radius-circle: 50%;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-row-sm: 5px;
|
||||||
|
$uni-spacing-row-base: 10px;
|
||||||
|
$uni-spacing-row-lg: 15px;
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
$uni-spacing-col-sm: 4px;
|
||||||
|
$uni-spacing-col-base: 8px;
|
||||||
|
$uni-spacing-col-lg: 12px;
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
$uni-color-title: #2C405A; // 文章标题颜色
|
||||||
|
$uni-font-size-title:20px;
|
||||||
|
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||||
|
$uni-font-size-subtitle:26px;
|
||||||
|
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||||
|
$uni-font-size-paragraph:15px;
|
22
uni_modules/superwei-combox/changelog.md
Normal file
22
uni_modules/superwei-combox/changelog.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
## 1.0.10(2022-10-19)
|
||||||
|
- 修改文档,更改为不兼容小程序(存在下拉框滑动会自动关闭的问题,后期改进后再兼容,若各位有好的解决方法的话欢迎评论)
|
||||||
|
## 1.0.9(2022-07-28)
|
||||||
|
- 完善是否创建新条目功能,并将默认值改为允许
|
||||||
|
## 1.0.8(2022-07-26)
|
||||||
|
- 新增禁用选项和是否创建新条目功能,新增disabledColor和isAllowCreate属性
|
||||||
|
## 1.0.7(2022-05-05)
|
||||||
|
- 解决传入JSON数组后,在模糊匹配项中进行选择,@select事件返回值为undefined且报错的问题
|
||||||
|
## 1.0.6(2022-03-24)
|
||||||
|
- 新增@select事件
|
||||||
|
## 1.0.5(2022-03-22)
|
||||||
|
- 修改文档
|
||||||
|
## 1.0.4(2022-03-18)
|
||||||
|
- 新增isJSON和keyName属性,candidates支持JSON数组格式
|
||||||
|
## 1.0.3(2022-03-01)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
|
## 1.0.2(2022-03-01)
|
||||||
|
- 基于官方uni-combox组件,解决选择后再次选择不展示全部选项的问题,同时新增选中项默认的文字和背景颜色,也可自定义进行样式覆盖
|
||||||
|
## 1.0.1(2022-03-01)
|
||||||
|
- 无
|
||||||
|
## 1.0.0(2022-03-01)
|
||||||
|
- 无
|
@ -0,0 +1,381 @@
|
|||||||
|
<template>
|
||||||
|
<view class="superwei-combox" :class="border ? '' : 'superwei-combox__no-border'">
|
||||||
|
<view v-if="label" class="superwei-combox__label" :style="labelStyle">
|
||||||
|
<text>{{label}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="superwei-combox__input-box">
|
||||||
|
<input class="superwei-combox__input" type="text" :placeholder="placeholder"
|
||||||
|
placeholder-class="superwei-combox__input-plac" v-model="inputVal" @input="onInput" @focus="onFocus"
|
||||||
|
@blur="onBlur" />
|
||||||
|
<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" @click="toggleSelector">
|
||||||
|
</uni-icons>
|
||||||
|
</view>
|
||||||
|
<view class="superwei-combox__selector" v-if="showSelector">
|
||||||
|
<view class="uni-popper__arrow"></view>
|
||||||
|
<scroll-view scroll-y="true" class="superwei-combox__selector-scroll">
|
||||||
|
<view class="superwei-combox__selector-empty" v-if="filterCandidatesLength === 0">
|
||||||
|
<text>{{emptyTips}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="superwei-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index">
|
||||||
|
<template v-if="(isJSON?(item.disabled?true:false):false)">
|
||||||
|
<text
|
||||||
|
:style="'color:'+disabledColor+';cursor: not-allowed;'">{{isJSON?item[keyName]?item[keyName]:'字段'+keyName+'不存在':item}}</text>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<text @click="onSelectorClick(index)"
|
||||||
|
:style="(isJSON?item[keyName]?item[keyName]==inputVal:false:item==inputVal)?'font-weight: bold;background-color: '+selectedBackground+';color: '+selectedColor:''">{{isJSON?item[keyName]?item[keyName]:'字段'+keyName+'不存在':item}}</text>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Combox 组合输入框
|
||||||
|
* @description 组合输入框一般用于既可以输入也可以选择的场景
|
||||||
|
* @property {String} label 左侧文字
|
||||||
|
* @property {String} labelWidth 左侧内容宽度
|
||||||
|
* @property {String} placeholder 输入框占位符
|
||||||
|
* @property {Array} candidates 候选项列表
|
||||||
|
* @property {String} emptyTips 筛选结果为空时显示的文字
|
||||||
|
* @property {String} value 组合框的值
|
||||||
|
* @property {String} selectedBackground 选中项背景颜色
|
||||||
|
* @property {String} selectedColor 选中项文字颜色
|
||||||
|
* @property {Boolean} isJSON 是否是json数组
|
||||||
|
* @property {String} keyName json数组显示的字段值
|
||||||
|
* @property {String} disabledColor 禁用项文字颜色
|
||||||
|
* @property {Boolean} isAllowCreate 是否允许用户创建新条目
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'superweiCombox',
|
||||||
|
emits: ['input', 'update:modelValue', 'select'],
|
||||||
|
props: {
|
||||||
|
isAllowCreate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
disabledColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#ababac'
|
||||||
|
},
|
||||||
|
isJSON: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
keyName: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
selectedBackground: {
|
||||||
|
type: String,
|
||||||
|
default: '#f5f7fa'
|
||||||
|
},
|
||||||
|
selectedColor: {
|
||||||
|
type: String,
|
||||||
|
default: '#409eff'
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: String,
|
||||||
|
default: 'auto'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
candidates: {
|
||||||
|
type: Array,
|
||||||
|
default () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emptyTips: {
|
||||||
|
type: String,
|
||||||
|
default: '无匹配项'
|
||||||
|
},
|
||||||
|
// #ifndef VUE3
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isInput: false,
|
||||||
|
showSelector: false,
|
||||||
|
isSelector: false,
|
||||||
|
inputVal: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
labelStyle() {
|
||||||
|
if (this.labelWidth === 'auto') {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return `width: ${this.labelWidth}`
|
||||||
|
},
|
||||||
|
filterCandidates() {
|
||||||
|
if (this.isInput) {
|
||||||
|
if (this.isJSON) {
|
||||||
|
return this.candidates.filter((item) => {
|
||||||
|
return item[this.keyName].toString().indexOf(this.inputVal) > -1
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return this.candidates.filter((item) => {
|
||||||
|
return item.toString().indexOf(this.inputVal) > -1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this.candidates
|
||||||
|
}
|
||||||
|
},
|
||||||
|
filterCandidatesLength() {
|
||||||
|
return this.filterCandidates.length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// #ifndef VUE3
|
||||||
|
value: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.inputVal = newVal
|
||||||
|
this.isInput = true
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.inputVal = newVal
|
||||||
|
this.isInput = true
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleSelector() {
|
||||||
|
this.showSelector = !this.showSelector
|
||||||
|
this.isInput = false
|
||||||
|
},
|
||||||
|
onFocus() {
|
||||||
|
this.showSelector = true
|
||||||
|
this.isInput = false
|
||||||
|
},
|
||||||
|
onChange() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showSelector = false
|
||||||
|
this.isInput = false
|
||||||
|
}, 200)
|
||||||
|
},
|
||||||
|
onBlur() {
|
||||||
|
if (!this.isInput) {
|
||||||
|
this.onChange()
|
||||||
|
} else {
|
||||||
|
if (this.inputVal && !this.isAllowCreate) {
|
||||||
|
let index = this.candidates.findIndex((item) => {
|
||||||
|
if (this.isJSON) {
|
||||||
|
return item[this.keyName].toString() == this.inputVal && !item.disabled
|
||||||
|
} else {
|
||||||
|
return item.toString() == this.inputVal
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (index == -1) {
|
||||||
|
if (this.filterCandidatesLength > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showSelector = false
|
||||||
|
this.isInput = false
|
||||||
|
if (!this.isSelector) {
|
||||||
|
this.inputVal = ''
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
}
|
||||||
|
}, 200)
|
||||||
|
this.isSelector = false
|
||||||
|
} else {
|
||||||
|
this.showSelector = false
|
||||||
|
this.isInput = false
|
||||||
|
this.inputVal = ''
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.onChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onSelectorClick(index) {
|
||||||
|
let item = this.filterCandidates[index]
|
||||||
|
if (this.isJSON) {
|
||||||
|
this.inputVal = item[this.keyName]
|
||||||
|
} else {
|
||||||
|
this.inputVal = item
|
||||||
|
}
|
||||||
|
this.showSelector = false
|
||||||
|
this.isSelector = true
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
this.$emit('select', item)
|
||||||
|
},
|
||||||
|
onInput() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.superwei-combox {
|
||||||
|
font-size: 24upx;
|
||||||
|
// border: 1px solid #DCDFE6;
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
// height: 40px;
|
||||||
|
flex-direction: row;
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 32upx;
|
||||||
|
height: 60upx;
|
||||||
|
padding: 0 10upx;
|
||||||
|
// border-bottom: solid 1px #DDDDDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__label {
|
||||||
|
font-size: 24upx;
|
||||||
|
line-height: 22px;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__input-box {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 24upx;
|
||||||
|
height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__input-plac {
|
||||||
|
font-size: 24upx;
|
||||||
|
color: #ccc; //placeholder-style="color:#FFFFFF"
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 12px);
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 2;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-scroll {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
max-height: 200px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-empty,
|
||||||
|
.superwei-combox__selector-item {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
line-height: 36px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
// border-bottom: solid 1px #DDDDDD;
|
||||||
|
padding: 0px 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-empty text,
|
||||||
|
.superwei-combox__selector-item text {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-item:hover {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__selector-empty:last-child,
|
||||||
|
.superwei-combox__selector-item:last-child {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
border-bottom: none;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
// picker 弹出层通用的指示小三角
|
||||||
|
.uni-popper__arrow,
|
||||||
|
.uni-popper__arrow::after {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-color: transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popper__arrow {
|
||||||
|
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
|
||||||
|
top: -6px;
|
||||||
|
left: 10%;
|
||||||
|
margin-right: 3px;
|
||||||
|
border-top-width: 0;
|
||||||
|
border-bottom-color: #EBEEF5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popper__arrow::after {
|
||||||
|
content: " ";
|
||||||
|
top: 1px;
|
||||||
|
margin-left: -6px;
|
||||||
|
border-top-width: 0;
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.superwei-combox__no-border {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
89
uni_modules/superwei-combox/package.json
Normal file
89
uni_modules/superwei-combox/package.json
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
{
|
||||||
|
"id": "superwei-combox",
|
||||||
|
"displayName": "superwei-combox 组合框",
|
||||||
|
"version": "1.0.10",
|
||||||
|
"description": "下拉搜索选择组合框,基于官方uni-combox组件,解决选择后再次选择不展示全部选项的问题,支持模糊搜索和JSON数组格式,可设置选中项文字和背景颜色(若使用请一定下载uni_modules版本)",
|
||||||
|
"keywords": [
|
||||||
|
"combox",
|
||||||
|
"组合框",
|
||||||
|
"select",
|
||||||
|
"下拉选择",
|
||||||
|
"搜索选择"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"前端组件",
|
||||||
|
"通用组件"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-icons"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "u",
|
||||||
|
"app-nvue": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "u",
|
||||||
|
"阿里": "u",
|
||||||
|
"百度": "u",
|
||||||
|
"字节跳动": "u",
|
||||||
|
"QQ": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
104
uni_modules/superwei-combox/readme.md
Normal file
104
uni_modules/superwei-combox/readme.md
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
## 基本用法
|
||||||
|
在 ``template`` 中使用组件
|
||||||
|
```html
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<span class="title">非JSON数组模式</span>
|
||||||
|
<superwei-combox :candidates="candidates" placeholder="请选择或输入" v-model="inputValue" @input="input"
|
||||||
|
@select="select"></superwei-combox>
|
||||||
|
|
||||||
|
<span class="title">JSON数组模式</span>
|
||||||
|
<superwei-combox :candidates="candidates_json" :isJSON="true" keyName="name" placeholder="请选择或输入"
|
||||||
|
v-model="inputValue_json" @input="input_json" @select="select_json"></superwei-combox>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
inputValue: '',
|
||||||
|
candidates: ['选项一', '选项二', '选项三', '选项四', '选项五', '选项六', '...'],
|
||||||
|
|
||||||
|
inputValue_json: '',
|
||||||
|
candidates_json: [{
|
||||||
|
id: '1',
|
||||||
|
name: '选项一'
|
||||||
|
}, {
|
||||||
|
id: '2',
|
||||||
|
name: '选项二',
|
||||||
|
disabled: true // 单独设置disabled后即可禁用该选项
|
||||||
|
}, {
|
||||||
|
id: '3',
|
||||||
|
name: '选项三'
|
||||||
|
}, {
|
||||||
|
id: '4',
|
||||||
|
name: '选项四'
|
||||||
|
}, {
|
||||||
|
id: '5',
|
||||||
|
name: '选项五',
|
||||||
|
disabled: true // 单独设置disabled后即可禁用该选项
|
||||||
|
}, {
|
||||||
|
id: '6',
|
||||||
|
name: '...'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
input(e) {
|
||||||
|
console.log(e) // 选项一
|
||||||
|
},
|
||||||
|
select(e) {
|
||||||
|
console.log(e) // 选项一
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
input_json(e) {
|
||||||
|
console.log(e) // 选项一
|
||||||
|
},
|
||||||
|
select_json(e) {
|
||||||
|
console.log(e) // {id: '1',name: '选项一'}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Combox Props
|
||||||
|
|
||||||
|
|属性名 |类型 |默认值 |说明 |
|
||||||
|
|:-: |:-: |:-: |:-: |
|
||||||
|
|label |String |- |标签文字 |
|
||||||
|
|value |String |- |combox的值 |
|
||||||
|
|labelWidth |String |auto |标签宽度,有单位字符串,如:'100px' |
|
||||||
|
|placeholder|String |- |输入框占位符 |
|
||||||
|
|candidates |Array/String |[] |候选字段 |
|
||||||
|
|emptyTips |String |无匹配项 |无匹配项时的提示语 |
|
||||||
|
|selectedBackground |String |#f5f7fa |选中项背景颜色 |
|
||||||
|
|selectedColor |String |#409eff |选中项文字颜色 |
|
||||||
|
|isJSON |Boolean |false |候选字段是否是json数组 |
|
||||||
|
|keyName |String |- |json数组显示的字段值 |
|
||||||
|
|disabledColor |String |#ababac |禁用项文字颜色 |
|
||||||
|
|isAllowCreate |Boolean |true |是否允许用户创建新条目 |
|
||||||
|
|
||||||
|
### Combox Events
|
||||||
|
|
||||||
|
|事件称名 |说明 |返回值 |
|
||||||
|
|:-: |:-: |:-: |
|
||||||
|
|@input |combox输入事件 |返回combox输入值|
|
||||||
|
|@select|combox选择事件 |返回combox选项值|
|
15
uni_modules/uni-combox/changelog.md
Normal file
15
uni_modules/uni-combox/changelog.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
## 1.0.1(2021-11-23)
|
||||||
|
- 优化 label、label-width 属性
|
||||||
|
## 1.0.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-combox](https://uniapp.dcloud.io/component/uniui/uni-combox)
|
||||||
|
## 0.1.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 0.0.6(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 0.0.5(2021-04-21)
|
||||||
|
- 优化 添加依赖 uni-icons, 导入后自动下载依赖
|
||||||
|
## 0.0.4(2021-02-05)
|
||||||
|
- 优化 组件引用关系,通过uni_modules引用组件
|
||||||
|
## 0.0.3(2021-02-04)
|
||||||
|
- 调整为uni_modules目录规范
|
275
uni_modules/uni-combox/components/uni-combox/uni-combox.vue
Normal file
275
uni_modules/uni-combox/components/uni-combox/uni-combox.vue
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-combox" :class="border ? '' : 'uni-combox__no-border'">
|
||||||
|
<view v-if="label" class="uni-combox__label" :style="labelStyle">
|
||||||
|
<text>{{label}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-combox__input-box">
|
||||||
|
<input class="uni-combox__input" type="text" :placeholder="placeholder"
|
||||||
|
placeholder-class="uni-combox__input-plac" v-model="inputVal" @input="onInput" @focus="onFocus"
|
||||||
|
@blur="onBlur" />
|
||||||
|
<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" @click="toggleSelector">
|
||||||
|
</uni-icons>
|
||||||
|
</view>
|
||||||
|
<view class="uni-combox__selector" v-if="showSelector">
|
||||||
|
<view class="uni-popper__arrow"></view>
|
||||||
|
<scroll-view scroll-y="true" class="uni-combox__selector-scroll">
|
||||||
|
<view class="uni-combox__selector-empty" v-if="filterCandidatesLength === 0">
|
||||||
|
<text>{{emptyTips}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-combox__selector-item" v-for="(item,index) in filterCandidates" :key="index"
|
||||||
|
@click="onSelectorClick(index)">
|
||||||
|
<text>{{item}}</text>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Combox 组合输入框
|
||||||
|
* @description 组合输入框一般用于既可以输入也可以选择的场景
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=1261
|
||||||
|
* @property {String} label 左侧文字
|
||||||
|
* @property {String} labelWidth 左侧内容宽度
|
||||||
|
* @property {String} placeholder 输入框占位符
|
||||||
|
* @property {Array} candidates 候选项列表
|
||||||
|
* @property {String} emptyTips 筛选结果为空时显示的文字
|
||||||
|
* @property {String} value 组合框的值
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniCombox',
|
||||||
|
emits: ['input', 'update:modelValue'],
|
||||||
|
props: {
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
labelWidth: {
|
||||||
|
type: String,
|
||||||
|
default: 'auto'
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
candidates: {
|
||||||
|
type: Array,
|
||||||
|
default () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
emptyTips: {
|
||||||
|
type: String,
|
||||||
|
default: '无匹配项'
|
||||||
|
},
|
||||||
|
// #ifndef VUE3
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showSelector: false,
|
||||||
|
inputVal: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
labelStyle() {
|
||||||
|
if (this.labelWidth === 'auto') {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return `width: ${this.labelWidth}`
|
||||||
|
},
|
||||||
|
filterCandidates() {
|
||||||
|
return this.candidates.filter((item) => {
|
||||||
|
return item.toString().indexOf(this.inputVal) > -1
|
||||||
|
})
|
||||||
|
},
|
||||||
|
filterCandidatesLength() {
|
||||||
|
return this.filterCandidates.length
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// #ifndef VUE3
|
||||||
|
value: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.inputVal = newVal
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
modelValue: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.inputVal = newVal
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleSelector() {
|
||||||
|
this.showSelector = !this.showSelector
|
||||||
|
},
|
||||||
|
onFocus() {
|
||||||
|
this.showSelector = true
|
||||||
|
},
|
||||||
|
onBlur() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.showSelector = false
|
||||||
|
}, 153)
|
||||||
|
},
|
||||||
|
onSelectorClick(index) {
|
||||||
|
this.inputVal = this.filterCandidates[index]
|
||||||
|
this.showSelector = false
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
},
|
||||||
|
onInput() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit('input', this.inputVal)
|
||||||
|
this.$emit('update:modelValue', this.inputVal)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.uni-combox {
|
||||||
|
font-size: 14px;
|
||||||
|
border: 1px solid #DCDFE6;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 6px 10px;
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
// height: 40px;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
// border-bottom: solid 1px #DDDDDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__label {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 22px;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__input-box {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 14px;
|
||||||
|
height: 22px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__input-plac {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__selector {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 12px);
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border: 1px solid #EBEEF5;
|
||||||
|
border-radius: 6px;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
z-index: 2;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__selector-scroll {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
max-height: 200px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__selector-empty,
|
||||||
|
.uni-combox__selector-item {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
line-height: 36px;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
// border-bottom: solid 1px #DDDDDD;
|
||||||
|
padding: 0px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__selector-item:hover {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__selector-empty:last-child,
|
||||||
|
.uni-combox__selector-item:last-child {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
border-bottom: none;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
// picker 弹出层通用的指示小三角
|
||||||
|
.uni-popper__arrow,
|
||||||
|
.uni-popper__arrow::after {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-color: transparent;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popper__arrow {
|
||||||
|
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
|
||||||
|
top: -6px;
|
||||||
|
left: 10%;
|
||||||
|
margin-right: 3px;
|
||||||
|
border-top-width: 0;
|
||||||
|
border-bottom-color: #EBEEF5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-popper__arrow::after {
|
||||||
|
content: " ";
|
||||||
|
top: 1px;
|
||||||
|
margin-left: -6px;
|
||||||
|
border-top-width: 0;
|
||||||
|
border-bottom-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-combox__no-border {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
90
uni_modules/uni-combox/package.json
Normal file
90
uni_modules/uni-combox/package.json
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-combox",
|
||||||
|
"displayName": "uni-combox 组合框",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"description": "可以选择也可以输入的表单项 ",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"combox",
|
||||||
|
"组合框",
|
||||||
|
"select"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"前端组件",
|
||||||
|
"通用组件"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-icons"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "n"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
uni_modules/uni-combox/readme.md
Normal file
11
uni_modules/uni-combox/readme.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## Combox 组合框
|
||||||
|
> **组件名:uni-combox**
|
||||||
|
> 代码块: `uCombox`
|
||||||
|
|
||||||
|
|
||||||
|
组合框组件。
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-combox)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
103
uni_modules/uni-datetime-picker/changelog.md
Normal file
103
uni_modules/uni-datetime-picker/changelog.md
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
## 2.2.11(2022-09-19)
|
||||||
|
- 修复,支付宝小程序样式错乱,[详情](https://github.com/dcloudio/uni-app/issues/3861)
|
||||||
|
## 2.2.10(2022-09-19)
|
||||||
|
- 修复,反向选择日期范围,日期显示异常,[详情](https://ask.dcloud.net.cn/question/153401?item_id=212892&rf=false)
|
||||||
|
## 2.2.9(2022-09-16)
|
||||||
|
- 可以使用 uni-scss 控制主题色
|
||||||
|
## 2.2.8(2022-09-08)
|
||||||
|
- 修复 close事件无效的 bug
|
||||||
|
## 2.2.7(2022-09-05)
|
||||||
|
- 修复 移动端 maskClick 无效的 bug,详见:[https://ask.dcloud.net.cn/question/140824?item_id=209458&rf=false](https://ask.dcloud.net.cn/question/140824?item_id=209458&rf=false)
|
||||||
|
## 2.2.6(2022-06-30)
|
||||||
|
- 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
|
||||||
|
## 2.2.5(2022-06-24)
|
||||||
|
- 修复 日历顶部年月及底部确认未国际化 bug
|
||||||
|
## 2.2.4(2022-03-31)
|
||||||
|
- 修复 Vue3 下动态赋值,单选类型未响应的 bug
|
||||||
|
## 2.2.3(2022-03-28)
|
||||||
|
- 修复 Vue3 下动态赋值未响应的 bug
|
||||||
|
## 2.2.2(2021-12-10)
|
||||||
|
- 修复 clear-icon 属性在小程序平台不生效的 bug
|
||||||
|
## 2.2.1(2021-12-10)
|
||||||
|
- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的 bug
|
||||||
|
## 2.2.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
|
||||||
|
## 2.1.5(2021-11-09)
|
||||||
|
- 新增 提供组件设计资源,组件样式调整
|
||||||
|
## 2.1.4(2021-09-10)
|
||||||
|
- 修复 hide-second 在移动端的 bug
|
||||||
|
- 修复 单选赋默认值时,赋值日期未高亮的 bug
|
||||||
|
- 修复 赋默认值时,移动端未正确显示时间的 bug
|
||||||
|
## 2.1.3(2021-09-09)
|
||||||
|
- 新增 hide-second 属性,支持只使用时分,隐藏秒
|
||||||
|
## 2.1.2(2021-09-03)
|
||||||
|
- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
|
||||||
|
- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
|
||||||
|
- 优化 调整字号大小,美化日历界面
|
||||||
|
- 修复 因国际化导致的 placeholder 失效的 bug
|
||||||
|
## 2.1.1(2021-08-24)
|
||||||
|
- 新增 支持国际化
|
||||||
|
- 优化 范围选择器在 pc 端过宽的问题
|
||||||
|
## 2.1.0(2021-08-09)
|
||||||
|
- 新增 适配 vue3
|
||||||
|
## 2.0.19(2021-08-09)
|
||||||
|
- 新增 支持作为 uni-forms 子组件相关功能
|
||||||
|
- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
|
||||||
|
## 2.0.18(2021-08-05)
|
||||||
|
- 修复 type 属性动态赋值无效的 bug
|
||||||
|
- 修复 ‘确认’按钮被 tabbar 遮盖 bug
|
||||||
|
- 修复 组件未赋值时范围选左、右日历相同的 bug
|
||||||
|
## 2.0.17(2021-08-04)
|
||||||
|
- 修复 范围选未正确显示当前值的 bug
|
||||||
|
- 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
|
||||||
|
## 2.0.16(2021-07-21)
|
||||||
|
- 新增 return-type 属性支持返回 date 日期对象
|
||||||
|
## 2.0.15(2021-07-14)
|
||||||
|
- 修复 单选日期类型,初始赋值后不在当前日历的 bug
|
||||||
|
- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效)
|
||||||
|
- 优化 移动端移除显示框的清空按钮,无实际用途
|
||||||
|
## 2.0.14(2021-07-14)
|
||||||
|
- 修复 组件赋值为空,界面未更新的 bug
|
||||||
|
- 修复 start 和 end 不能动态赋值的 bug
|
||||||
|
- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的 bug
|
||||||
|
## 2.0.13(2021-07-08)
|
||||||
|
- 修复 范围选择不能动态赋值的 bug
|
||||||
|
## 2.0.12(2021-07-08)
|
||||||
|
- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug
|
||||||
|
## 2.0.11(2021-07-08)
|
||||||
|
- 优化 弹出层在超出视窗边缘定位不准确的问题
|
||||||
|
## 2.0.10(2021-07-08)
|
||||||
|
- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的 bug
|
||||||
|
- 优化 弹出层在超出视窗边缘被遮盖的问题
|
||||||
|
## 2.0.9(2021-07-07)
|
||||||
|
- 新增 maskClick 事件
|
||||||
|
- 修复 特殊情况日历 rpx 布局错误的 bug,rpx -> px
|
||||||
|
- 修复 范围选择时清空返回值不合理的bug,['', ''] -> []
|
||||||
|
## 2.0.8(2021-07-07)
|
||||||
|
- 新增 日期时间显示框支持插槽
|
||||||
|
## 2.0.7(2021-07-01)
|
||||||
|
- 优化 添加 uni-icons 依赖
|
||||||
|
## 2.0.6(2021-05-22)
|
||||||
|
- 修复 图标在小程序上不显示的 bug
|
||||||
|
- 优化 重命名引用组件,避免潜在组件命名冲突
|
||||||
|
## 2.0.5(2021-05-20)
|
||||||
|
- 优化 代码目录扁平化
|
||||||
|
## 2.0.4(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 2.0.3(2021-05-10)
|
||||||
|
- 修复 ios 下不识别 '-' 日期格式的 bug
|
||||||
|
- 优化 pc 下弹出层添加边框和阴影
|
||||||
|
## 2.0.2(2021-05-08)
|
||||||
|
- 修复 在 admin 中获取弹出层定位错误的bug
|
||||||
|
## 2.0.1(2021-05-08)
|
||||||
|
- 修复 type 属性向下兼容,默认值从 date 变更为 datetime
|
||||||
|
## 2.0.0(2021-04-30)
|
||||||
|
- 支持日历形式的日期+时间的范围选择
|
||||||
|
> 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)
|
||||||
|
## 1.0.6(2021-03-18)
|
||||||
|
- 新增 hide-second 属性,时间支持仅选择时、分
|
||||||
|
- 修复 选择跟显示的日期不一样的 bug
|
||||||
|
- 修复 chang事件触发2次的 bug
|
||||||
|
- 修复 分、秒 end 范围错误的 bug
|
||||||
|
- 优化 更好的 nvue 适配
|
@ -0,0 +1,187 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-calendar-item__weeks-box" :class="{
|
||||||
|
'uni-calendar-item--disable':weeks.disable,
|
||||||
|
'uni-calendar-item--before-checked-x':weeks.beforeMultiple,
|
||||||
|
'uni-calendar-item--multiple': weeks.multiple,
|
||||||
|
'uni-calendar-item--after-checked-x':weeks.afterMultiple,
|
||||||
|
}" @click="choiceDate(weeks)" @mouseenter="handleMousemove(weeks)">
|
||||||
|
<view class="uni-calendar-item__weeks-box-item" :class="{
|
||||||
|
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && (calendar.userChecked || !checkHover),
|
||||||
|
'uni-calendar-item--checked-range-text': checkHover,
|
||||||
|
'uni-calendar-item--before-checked':weeks.beforeMultiple,
|
||||||
|
'uni-calendar-item--multiple': weeks.multiple,
|
||||||
|
'uni-calendar-item--after-checked':weeks.afterMultiple,
|
||||||
|
'uni-calendar-item--disable':weeks.disable,
|
||||||
|
}">
|
||||||
|
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
|
||||||
|
<text class="uni-calendar-item__weeks-box-text uni-calendar-item__weeks-box-text-disable uni-calendar-item--checked-text">{{weeks.date}}</text>
|
||||||
|
</view>
|
||||||
|
<view :class="{'uni-calendar-item--isDay': weeks.isDay}"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
weeks: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calendar: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
type: Array,
|
||||||
|
default: () => {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lunar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
checkHover: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
choiceDate(weeks) {
|
||||||
|
this.$emit('change', weeks)
|
||||||
|
},
|
||||||
|
handleMousemove(weeks) {
|
||||||
|
this.$emit('handleMouse', weeks)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" >
|
||||||
|
$uni-primary: #007aff !default;
|
||||||
|
|
||||||
|
.uni-calendar-item__weeks-box {
|
||||||
|
flex: 1;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: 1px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item__weeks-box-text {
|
||||||
|
font-size: 14px;
|
||||||
|
// font-family: Lato-Bold, Lato;
|
||||||
|
font-weight: bold;
|
||||||
|
color: darken($color: $uni-primary, $amount: 40%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item__weeks-lunar-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item__weeks-box-item {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.uni-calendar-item__weeks-box-circle {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 5px;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #dd524d;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item__weeks-box .uni-calendar-item--disable {
|
||||||
|
// background-color: rgba(249, 249, 249, $uni-opacity-disabled);
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--disable .uni-calendar-item__weeks-box-text-disable {
|
||||||
|
color: #D1D1D1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--isDay {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 17%;
|
||||||
|
background-color: #dd524d;
|
||||||
|
width:6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--extra {
|
||||||
|
color: #dd524d;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item__weeks-box .uni-calendar-item--checked {
|
||||||
|
background-color: $uni-primary;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 3px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--checked .uni-calendar-item--checked-text {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--multiple .uni-calendar-item--checked-range-text {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--multiple {
|
||||||
|
background-color: #F6F7FC;
|
||||||
|
// color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--multiple .uni-calendar-item--before-checked,
|
||||||
|
.uni-calendar-item--multiple .uni-calendar-item--after-checked {
|
||||||
|
background-color: $uni-primary;
|
||||||
|
border-radius: 50%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 3px solid #F6F7FC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--before-checked .uni-calendar-item--checked-text,
|
||||||
|
.uni-calendar-item--after-checked .uni-calendar-item--checked-text {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--before-checked-x {
|
||||||
|
border-top-left-radius: 50px;
|
||||||
|
border-bottom-left-radius: 50px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-color: #F6F7FC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar-item--after-checked-x {
|
||||||
|
border-top-right-radius: 50px;
|
||||||
|
border-bottom-right-radius: 50px;
|
||||||
|
background-color: #F6F7FC;
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,924 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-calendar" @mouseleave="leaveCale">
|
||||||
|
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}"
|
||||||
|
@click="clean();maskClick()"></view>
|
||||||
|
<view v-if="insert || show" class="uni-calendar__content"
|
||||||
|
:class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow, 'uni-calendar__content-mobile': aniMaskShow}">
|
||||||
|
<view class="uni-calendar__header" :class="{'uni-calendar__header-mobile' :!insert}">
|
||||||
|
<view v-if="left" class="uni-calendar__header-btn-box" @click.stop="pre">
|
||||||
|
<view class="uni-calendar__header-btn uni-calendar--left"></view>
|
||||||
|
</view>
|
||||||
|
<picker mode="date" :value="date" fields="month" @change="bindDateChange">
|
||||||
|
<text
|
||||||
|
class="uni-calendar__header-text">{{ (nowDate.year||'') + yearText + ( nowDate.month||'') + monthText}}</text>
|
||||||
|
</picker>
|
||||||
|
<view v-if="right" class="uni-calendar__header-btn-box" @click.stop="next">
|
||||||
|
<view class="uni-calendar__header-btn uni-calendar--right"></view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!insert" class="dialog-close" @click="clean">
|
||||||
|
<view class="dialog-close-plus" data-id="close"></view>
|
||||||
|
<view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- <text class="uni-calendar__backtoday" @click="backtoday">回到今天</text> -->
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__box">
|
||||||
|
<view v-if="showMonth" class="uni-calendar__box-bg">
|
||||||
|
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks" style="padding-bottom: 7px;">
|
||||||
|
<view class="uni-calendar__weeks-day">
|
||||||
|
<text class="uni-calendar__weeks-day-text">{{SUNText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks-day">
|
||||||
|
<text class="uni-calendar__weeks-day-text">{{MONText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks-day">
|
||||||
|
<text class="uni-calendar__weeks-day-text">{{TUEText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks-day">
|
||||||
|
<text class="uni-calendar__weeks-day-text">{{WEDText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks-day">
|
||||||
|
<text class="uni-calendar__weeks-day-text">{{THUText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks-day">
|
||||||
|
<text class="uni-calendar__weeks-day-text">{{FRIText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks-day">
|
||||||
|
<text class="uni-calendar__weeks-day-text">{{SATText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
|
||||||
|
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
|
||||||
|
<calendar-item class="uni-calendar-item--hook" :weeks="weeks" :calendar="calendar"
|
||||||
|
:selected="selected" :lunar="lunar" :checkHover="range" @change="choiceDate"
|
||||||
|
@handleMouse="handleMouse">
|
||||||
|
</calendar-item>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!insert && !range && typeHasTime" class="uni-date-changed uni-calendar--fixed-top"
|
||||||
|
style="padding: 0 80px;">
|
||||||
|
<view class="uni-date-changed--time-date">{{tempSingleDate ? tempSingleDate : selectDateText}}</view>
|
||||||
|
<time-picker type="time" :start="reactStartTime" :end="reactEndTime" v-model="time"
|
||||||
|
:disabled="!tempSingleDate" :border="false" :hide-second="hideSecond" class="time-picker-style">
|
||||||
|
</time-picker>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="!insert && range && typeHasTime" class="uni-date-changed uni-calendar--fixed-top">
|
||||||
|
<view class="uni-date-changed--time-start">
|
||||||
|
<view class="uni-date-changed--time-date">{{tempRange.before ? tempRange.before : startDateText}}
|
||||||
|
</view>
|
||||||
|
<time-picker type="time" :start="reactStartTime" v-model="timeRange.startTime" :border="false"
|
||||||
|
:hide-second="hideSecond" :disabled="!tempRange.before" class="time-picker-style">
|
||||||
|
</time-picker>
|
||||||
|
</view>
|
||||||
|
<view style="line-height: 50px;">
|
||||||
|
<uni-icons type="arrowthinright" color="#999"></uni-icons>
|
||||||
|
</view>
|
||||||
|
<view class="uni-date-changed--time-end">
|
||||||
|
<view class="uni-date-changed--time-date">{{tempRange.after ? tempRange.after : endDateText}}</view>
|
||||||
|
<time-picker type="time" :end="reactEndTime" v-model="timeRange.endTime" :border="false"
|
||||||
|
:hide-second="hideSecond" :disabled="!tempRange.after" class="time-picker-style">
|
||||||
|
</time-picker>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!insert" class="uni-date-changed uni-date-btn--ok">
|
||||||
|
<!-- <view class="uni-calendar__header-btn-box">
|
||||||
|
<text class="uni-calendar__button-text uni-calendar--fixed-width">{{okText}}</text>
|
||||||
|
</view> -->
|
||||||
|
<view class="uni-datetime-picker--btn" @click="confirm">{{confirmText}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Calendar from './util.js';
|
||||||
|
import calendarItem from './calendar-item.vue'
|
||||||
|
import timePicker from './time-picker.vue'
|
||||||
|
import {
|
||||||
|
initVueI18n
|
||||||
|
} from '@dcloudio/uni-i18n'
|
||||||
|
import messages from './i18n/index.js'
|
||||||
|
const {
|
||||||
|
t
|
||||||
|
} = initVueI18n(messages)
|
||||||
|
/**
|
||||||
|
* Calendar 日历
|
||||||
|
* @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=56
|
||||||
|
* @property {String} date 自定义当前时间,默认为今天
|
||||||
|
* @property {Boolean} lunar 显示农历
|
||||||
|
* @property {String} startDate 日期选择范围-开始日期
|
||||||
|
* @property {String} endDate 日期选择范围-结束日期
|
||||||
|
* @property {Boolean} range 范围选择
|
||||||
|
* @property {Boolean} insert = [true|false] 插入模式,默认为false
|
||||||
|
* @value true 弹窗模式
|
||||||
|
* @value false 插入模式
|
||||||
|
* @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
|
||||||
|
* @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
|
||||||
|
* @property {Boolean} showMonth 是否选择月份为背景
|
||||||
|
* @event {Function} change 日期改变,`insert :ture` 时生效
|
||||||
|
* @event {Function} confirm 确认选择`insert :false` 时生效
|
||||||
|
* @event {Function} monthSwitch 切换月份时触发
|
||||||
|
* @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
calendarItem,
|
||||||
|
timePicker
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
date: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
defTime: {
|
||||||
|
type: [String, Object],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
selectableTimes: {
|
||||||
|
type: [Object],
|
||||||
|
default () {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
type: Array,
|
||||||
|
default () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
lunar: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
startDate: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
endDate: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
range: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
typeHasTime: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
insert: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
showMonth: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
clearDate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
left: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
right: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
checkHover: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
hideSecond: {
|
||||||
|
type: [Boolean],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
pleStatus: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
before: '',
|
||||||
|
after: '',
|
||||||
|
data: [],
|
||||||
|
fulldate: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
show: false,
|
||||||
|
weeks: [],
|
||||||
|
calendar: {},
|
||||||
|
nowDate: '',
|
||||||
|
aniMaskShow: false,
|
||||||
|
firstEnter: true,
|
||||||
|
time: '',
|
||||||
|
timeRange: {
|
||||||
|
startTime: '',
|
||||||
|
endTime: ''
|
||||||
|
},
|
||||||
|
tempSingleDate: '',
|
||||||
|
tempRange: {
|
||||||
|
before: '',
|
||||||
|
after: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
date: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
if (!this.range) {
|
||||||
|
this.tempSingleDate = newVal
|
||||||
|
setTimeout(() => {
|
||||||
|
this.init(newVal)
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
defTime: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
if (!this.range) {
|
||||||
|
this.time = newVal
|
||||||
|
} else {
|
||||||
|
// console.log('-----', newVal);
|
||||||
|
this.timeRange.startTime = newVal.start
|
||||||
|
this.timeRange.endTime = newVal.end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
startDate(val) {
|
||||||
|
this.cale.resetSatrtDate(val)
|
||||||
|
this.cale.setDate(this.nowDate.fullDate)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
},
|
||||||
|
endDate(val) {
|
||||||
|
this.cale.resetEndDate(val)
|
||||||
|
this.cale.setDate(this.nowDate.fullDate)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
},
|
||||||
|
selected(newVal) {
|
||||||
|
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
},
|
||||||
|
pleStatus: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
const {
|
||||||
|
before,
|
||||||
|
after,
|
||||||
|
fulldate,
|
||||||
|
which
|
||||||
|
} = newVal
|
||||||
|
this.tempRange.before = before
|
||||||
|
this.tempRange.after = after
|
||||||
|
setTimeout(() => {
|
||||||
|
if (fulldate) {
|
||||||
|
this.cale.setHoverMultiple(fulldate)
|
||||||
|
if (before && after) {
|
||||||
|
this.cale.lastHover = true
|
||||||
|
if (this.rangeWithinMonth(after, before)) return
|
||||||
|
this.setDate(before)
|
||||||
|
} else {
|
||||||
|
this.cale.setMultiple(fulldate)
|
||||||
|
this.setDate(this.nowDate.fullDate)
|
||||||
|
this.calendar.fullDate = ''
|
||||||
|
this.cale.lastHover = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.cale.setDefaultMultiple(before, after)
|
||||||
|
if (which === 'left') {
|
||||||
|
this.setDate(before)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
} else {
|
||||||
|
this.setDate(after)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
}
|
||||||
|
this.cale.lastHover = true
|
||||||
|
}
|
||||||
|
}, 16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
reactStartTime() {
|
||||||
|
const activeDate = this.range ? this.tempRange.before : this.calendar.fullDate
|
||||||
|
const res = activeDate === this.startDate ? this.selectableTimes.start : ''
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
reactEndTime() {
|
||||||
|
const activeDate = this.range ? this.tempRange.after : this.calendar.fullDate
|
||||||
|
const res = activeDate === this.endDate ? this.selectableTimes.end : ''
|
||||||
|
return res
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* for i18n
|
||||||
|
*/
|
||||||
|
selectDateText() {
|
||||||
|
return t("uni-datetime-picker.selectDate")
|
||||||
|
},
|
||||||
|
startDateText() {
|
||||||
|
return this.startPlaceholder || t("uni-datetime-picker.startDate")
|
||||||
|
},
|
||||||
|
endDateText() {
|
||||||
|
return this.endPlaceholder || t("uni-datetime-picker.endDate")
|
||||||
|
},
|
||||||
|
okText() {
|
||||||
|
return t("uni-datetime-picker.ok")
|
||||||
|
},
|
||||||
|
yearText() {
|
||||||
|
return t("uni-datetime-picker.year")
|
||||||
|
},
|
||||||
|
monthText() {
|
||||||
|
return t("uni-datetime-picker.month")
|
||||||
|
},
|
||||||
|
MONText() {
|
||||||
|
return t("uni-calender.MON")
|
||||||
|
},
|
||||||
|
TUEText() {
|
||||||
|
return t("uni-calender.TUE")
|
||||||
|
},
|
||||||
|
WEDText() {
|
||||||
|
return t("uni-calender.WED")
|
||||||
|
},
|
||||||
|
THUText() {
|
||||||
|
return t("uni-calender.THU")
|
||||||
|
},
|
||||||
|
FRIText() {
|
||||||
|
return t("uni-calender.FRI")
|
||||||
|
},
|
||||||
|
SATText() {
|
||||||
|
return t("uni-calender.SAT")
|
||||||
|
},
|
||||||
|
SUNText() {
|
||||||
|
return t("uni-calender.SUN")
|
||||||
|
},
|
||||||
|
confirmText() {
|
||||||
|
return t("uni-calender.confirm")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 获取日历方法实例
|
||||||
|
this.cale = new Calendar({
|
||||||
|
// date: new Date(),
|
||||||
|
selected: this.selected,
|
||||||
|
startDate: this.startDate,
|
||||||
|
endDate: this.endDate,
|
||||||
|
range: this.range,
|
||||||
|
// multipleStatus: this.pleStatus
|
||||||
|
})
|
||||||
|
// 选中某一天
|
||||||
|
// this.cale.setDate(this.date)
|
||||||
|
this.init(this.date)
|
||||||
|
// this.setDay
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
leaveCale() {
|
||||||
|
this.firstEnter = true
|
||||||
|
},
|
||||||
|
handleMouse(weeks) {
|
||||||
|
if (weeks.disable) return
|
||||||
|
if (this.cale.lastHover) return
|
||||||
|
let {
|
||||||
|
before,
|
||||||
|
after
|
||||||
|
} = this.cale.multipleStatus
|
||||||
|
if (!before) return
|
||||||
|
this.calendar = weeks
|
||||||
|
// 设置范围选
|
||||||
|
this.cale.setHoverMultiple(this.calendar.fullDate)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
// hover时,进入一个日历,更新另一个
|
||||||
|
if (this.firstEnter) {
|
||||||
|
this.$emit('firstEnterCale', this.cale.multipleStatus)
|
||||||
|
this.firstEnter = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rangeWithinMonth(A, B) {
|
||||||
|
const [yearA, monthA] = A.split('-')
|
||||||
|
const [yearB, monthB] = B.split('-')
|
||||||
|
return yearA === yearB && monthA === monthB
|
||||||
|
},
|
||||||
|
|
||||||
|
// 取消穿透
|
||||||
|
clean() {
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 蒙版点击事件
|
||||||
|
maskClick() {
|
||||||
|
this.$emit('maskClose')
|
||||||
|
},
|
||||||
|
|
||||||
|
clearCalender() {
|
||||||
|
if (this.range) {
|
||||||
|
this.timeRange.startTime = ''
|
||||||
|
this.timeRange.endTime = ''
|
||||||
|
this.tempRange.before = ''
|
||||||
|
this.tempRange.after = ''
|
||||||
|
this.cale.multipleStatus.before = ''
|
||||||
|
this.cale.multipleStatus.after = ''
|
||||||
|
this.cale.multipleStatus.data = []
|
||||||
|
this.cale.lastHover = false
|
||||||
|
} else {
|
||||||
|
this.time = ''
|
||||||
|
this.tempSingleDate = ''
|
||||||
|
}
|
||||||
|
this.calendar.fullDate = ''
|
||||||
|
this.setDate()
|
||||||
|
},
|
||||||
|
|
||||||
|
bindDateChange(e) {
|
||||||
|
const value = e.detail.value + '-1'
|
||||||
|
this.init(value)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 初始化日期显示
|
||||||
|
* @param {Object} date
|
||||||
|
*/
|
||||||
|
init(date) {
|
||||||
|
this.cale.setDate(date)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
this.nowDate = this.calendar = this.cale.getInfo(date)
|
||||||
|
},
|
||||||
|
// choiceDate(weeks) {
|
||||||
|
// if (weeks.disable) return
|
||||||
|
// this.calendar = weeks
|
||||||
|
// // 设置多选
|
||||||
|
// this.cale.setMultiple(this.calendar.fullDate, true)
|
||||||
|
// this.weeks = this.cale.weeks
|
||||||
|
// this.tempSingleDate = this.calendar.fullDate
|
||||||
|
// this.tempRange.before = this.cale.multipleStatus.before
|
||||||
|
// this.tempRange.after = this.cale.multipleStatus.after
|
||||||
|
// this.change()
|
||||||
|
// },
|
||||||
|
/**
|
||||||
|
* 打开日历弹窗
|
||||||
|
*/
|
||||||
|
open() {
|
||||||
|
// 弹窗模式并且清理数据
|
||||||
|
if (this.clearDate && !this.insert) {
|
||||||
|
this.cale.cleanMultipleStatus()
|
||||||
|
// this.cale.setDate(this.date)
|
||||||
|
this.init(this.date)
|
||||||
|
}
|
||||||
|
this.show = true
|
||||||
|
this.$nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.aniMaskShow = true
|
||||||
|
}, 50)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 关闭日历弹窗
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
this.aniMaskShow = false
|
||||||
|
this.$nextTick(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.show = false
|
||||||
|
this.$emit('close')
|
||||||
|
}, 300)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 确认按钮
|
||||||
|
*/
|
||||||
|
confirm() {
|
||||||
|
this.setEmit('confirm')
|
||||||
|
this.close()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 变化触发
|
||||||
|
*/
|
||||||
|
change() {
|
||||||
|
if (!this.insert) return
|
||||||
|
this.setEmit('change')
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 选择月份触发
|
||||||
|
*/
|
||||||
|
monthSwitch() {
|
||||||
|
let {
|
||||||
|
year,
|
||||||
|
month
|
||||||
|
} = this.nowDate
|
||||||
|
this.$emit('monthSwitch', {
|
||||||
|
year,
|
||||||
|
month: Number(month)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 派发事件
|
||||||
|
* @param {Object} name
|
||||||
|
*/
|
||||||
|
setEmit(name) {
|
||||||
|
let {
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
date,
|
||||||
|
fullDate,
|
||||||
|
lunar,
|
||||||
|
extraInfo
|
||||||
|
} = this.calendar
|
||||||
|
this.$emit(name, {
|
||||||
|
range: this.cale.multipleStatus,
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
date,
|
||||||
|
time: this.time,
|
||||||
|
timeRange: this.timeRange,
|
||||||
|
fulldate: fullDate,
|
||||||
|
lunar,
|
||||||
|
extraInfo: extraInfo || {}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 选择天触发
|
||||||
|
* @param {Object} weeks
|
||||||
|
*/
|
||||||
|
choiceDate(weeks) {
|
||||||
|
if (weeks.disable) return
|
||||||
|
this.calendar = weeks
|
||||||
|
this.calendar.userChecked = true
|
||||||
|
// 设置多选
|
||||||
|
this.cale.setMultiple(this.calendar.fullDate, true)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
this.tempSingleDate = this.calendar.fullDate
|
||||||
|
const beforeStatus = this.cale.multipleStatus.before
|
||||||
|
const beforeDate = new Date(this.cale.multipleStatus.before).getTime()
|
||||||
|
const afterDate = new Date(this.cale.multipleStatus.after).getTime()
|
||||||
|
if (beforeDate > afterDate && afterDate) {
|
||||||
|
this.tempRange.before = this.cale.multipleStatus.after
|
||||||
|
this.tempRange.after = this.cale.multipleStatus.before
|
||||||
|
} else {
|
||||||
|
this.tempRange.before = this.cale.multipleStatus.before
|
||||||
|
this.tempRange.after = this.cale.multipleStatus.after
|
||||||
|
}
|
||||||
|
this.change()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 回到今天
|
||||||
|
*/
|
||||||
|
backtoday() {
|
||||||
|
let date = this.cale.getDate(new Date()).fullDate
|
||||||
|
// this.cale.setDate(date)
|
||||||
|
this.init(date)
|
||||||
|
this.change()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 比较时间大小
|
||||||
|
*/
|
||||||
|
dateCompare(startDate, endDate) {
|
||||||
|
// 计算截止时间
|
||||||
|
startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
|
||||||
|
// 计算详细项的截止时间
|
||||||
|
endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
|
||||||
|
if (startDate <= endDate) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 上个月
|
||||||
|
*/
|
||||||
|
pre() {
|
||||||
|
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
|
||||||
|
this.setDate(preDate)
|
||||||
|
this.monthSwitch()
|
||||||
|
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 下个月
|
||||||
|
*/
|
||||||
|
next() {
|
||||||
|
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
|
||||||
|
this.setDate(nextDate)
|
||||||
|
this.monthSwitch()
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 设置日期
|
||||||
|
* @param {Object} date
|
||||||
|
*/
|
||||||
|
setDate(date) {
|
||||||
|
this.cale.setDate(date)
|
||||||
|
this.weeks = this.cale.weeks
|
||||||
|
this.nowDate = this.cale.getInfo(date)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" >
|
||||||
|
$uni-primary: #007aff !default;
|
||||||
|
|
||||||
|
.uni-calendar {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__mask {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
transition-property: opacity;
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
opacity: 0;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 99;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar--mask-show {
|
||||||
|
opacity: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar--fixed {
|
||||||
|
position: fixed;
|
||||||
|
bottom: calc(var(--window-bottom));
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
transition-property: transform;
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
transform: translateY(460px);
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
z-index: 99;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar--ani-show {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__content {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__content-mobile {
|
||||||
|
border-top-left-radius: 10px;
|
||||||
|
border-top-right-radius: 10px;
|
||||||
|
box-shadow: 0px 0px 5px 3px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__header {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__header-mobile {
|
||||||
|
padding: 10px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar--fixed-top {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
border-top-color: rgba(0, 0, 0, 0.4);
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar--fixed-width {
|
||||||
|
width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__backtoday {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 25rpx;
|
||||||
|
padding: 0 5px;
|
||||||
|
padding-left: 10px;
|
||||||
|
height: 25px;
|
||||||
|
line-height: 25px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-top-left-radius: 25px;
|
||||||
|
border-bottom-left-radius: 25px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__header-text {
|
||||||
|
text-align: center;
|
||||||
|
width: 100px;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__button-text {
|
||||||
|
text-align: center;
|
||||||
|
width: 100px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: $uni-primary;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
letter-spacing: 3px;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__header-btn-box {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__header-btn {
|
||||||
|
width: 9px;
|
||||||
|
height: 9px;
|
||||||
|
border-left-color: #808080;
|
||||||
|
border-left-style: solid;
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-top-color: #555555;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar--left {
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar--right {
|
||||||
|
transform: rotate(135deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.uni-calendar__weeks {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__weeks-item {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__weeks-day {
|
||||||
|
flex: 1;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 40px;
|
||||||
|
border-bottom-color: #F5F5F5;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__weeks-day-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #B2B2B2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__box {
|
||||||
|
position: relative;
|
||||||
|
// padding: 0 10px;
|
||||||
|
padding-bottom: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__box-bg {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-calendar__box-bg-text {
|
||||||
|
font-size: 200px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #999;
|
||||||
|
opacity: 0.1;
|
||||||
|
text-align: center;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
line-height: 1;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-date-changed {
|
||||||
|
padding: 0 10px;
|
||||||
|
// line-height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
color: #333;
|
||||||
|
border-top-color: #DCDCDC;
|
||||||
|
;
|
||||||
|
border-top-style: solid;
|
||||||
|
border-top-width: 1px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-date-btn--ok {
|
||||||
|
padding: 20px 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-date-changed--time-start {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-date-changed--time-end {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-date-changed--time-date {
|
||||||
|
color: #999;
|
||||||
|
line-height: 50px;
|
||||||
|
margin-right: 5px;
|
||||||
|
// opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-picker-style {
|
||||||
|
// width: 62px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-10 {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 25px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-close-plus {
|
||||||
|
width: 16px;
|
||||||
|
height: 2px;
|
||||||
|
background-color: #737987;
|
||||||
|
border-radius: 2px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-close-rotate {
|
||||||
|
position: absolute;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker--btn {
|
||||||
|
border-radius: 100px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
background-color: $uni-primary;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
.uni-datetime-picker--btn:active {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
</style>
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"uni-datetime-picker.selectDate": "select date",
|
||||||
|
"uni-datetime-picker.selectTime": "select time",
|
||||||
|
"uni-datetime-picker.selectDateTime": "select datetime",
|
||||||
|
"uni-datetime-picker.startDate": "start date",
|
||||||
|
"uni-datetime-picker.endDate": "end date",
|
||||||
|
"uni-datetime-picker.startTime": "start time",
|
||||||
|
"uni-datetime-picker.endTime": "end time",
|
||||||
|
"uni-datetime-picker.ok": "ok",
|
||||||
|
"uni-datetime-picker.clear": "clear",
|
||||||
|
"uni-datetime-picker.cancel": "cancel",
|
||||||
|
"uni-datetime-picker.year": "-",
|
||||||
|
"uni-datetime-picker.month": "",
|
||||||
|
"uni-calender.MON": "MON",
|
||||||
|
"uni-calender.TUE": "TUE",
|
||||||
|
"uni-calender.WED": "WED",
|
||||||
|
"uni-calender.THU": "THU",
|
||||||
|
"uni-calender.FRI": "FRI",
|
||||||
|
"uni-calender.SAT": "SAT",
|
||||||
|
"uni-calender.SUN": "SUN",
|
||||||
|
"uni-calender.confirm": "confirm"
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import en from './en.json'
|
||||||
|
import zhHans from './zh-Hans.json'
|
||||||
|
import zhHant from './zh-Hant.json'
|
||||||
|
export default {
|
||||||
|
en,
|
||||||
|
'zh-Hans': zhHans,
|
||||||
|
'zh-Hant': zhHant
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"uni-datetime-picker.selectDate": "选择日期",
|
||||||
|
"uni-datetime-picker.selectTime": "选择时间",
|
||||||
|
"uni-datetime-picker.selectDateTime": "选择日期时间",
|
||||||
|
"uni-datetime-picker.startDate": "开始日期",
|
||||||
|
"uni-datetime-picker.endDate": "结束日期",
|
||||||
|
"uni-datetime-picker.startTime": "开始时间",
|
||||||
|
"uni-datetime-picker.endTime": "结束时间",
|
||||||
|
"uni-datetime-picker.ok": "确定",
|
||||||
|
"uni-datetime-picker.clear": "清除",
|
||||||
|
"uni-datetime-picker.cancel": "取消",
|
||||||
|
"uni-datetime-picker.year": "年",
|
||||||
|
"uni-datetime-picker.month": "月",
|
||||||
|
"uni-calender.SUN": "日",
|
||||||
|
"uni-calender.MON": "一",
|
||||||
|
"uni-calender.TUE": "二",
|
||||||
|
"uni-calender.WED": "三",
|
||||||
|
"uni-calender.THU": "四",
|
||||||
|
"uni-calender.FRI": "五",
|
||||||
|
"uni-calender.SAT": "六",
|
||||||
|
"uni-calender.confirm": "确认"
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"uni-datetime-picker.selectDate": "選擇日期",
|
||||||
|
"uni-datetime-picker.selectTime": "選擇時間",
|
||||||
|
"uni-datetime-picker.selectDateTime": "選擇日期時間",
|
||||||
|
"uni-datetime-picker.startDate": "開始日期",
|
||||||
|
"uni-datetime-picker.endDate": "結束日期",
|
||||||
|
"uni-datetime-picker.startTime": "開始时间",
|
||||||
|
"uni-datetime-picker.endTime": "結束时间",
|
||||||
|
"uni-datetime-picker.ok": "確定",
|
||||||
|
"uni-datetime-picker.clear": "清除",
|
||||||
|
"uni-datetime-picker.cancel": "取消",
|
||||||
|
"uni-datetime-picker.year": "年",
|
||||||
|
"uni-datetime-picker.month": "月",
|
||||||
|
"uni-calender.SUN": "日",
|
||||||
|
"uni-calender.MON": "一",
|
||||||
|
"uni-calender.TUE": "二",
|
||||||
|
"uni-calender.WED": "三",
|
||||||
|
"uni-calender.THU": "四",
|
||||||
|
"uni-calender.FRI": "五",
|
||||||
|
"uni-calender.SAT": "六",
|
||||||
|
"uni-calender.confirm": "確認"
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
// #ifdef H5
|
||||||
|
export default {
|
||||||
|
name: 'Keypress',
|
||||||
|
props: {
|
||||||
|
disable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted () {
|
||||||
|
const keyNames = {
|
||||||
|
esc: ['Esc', 'Escape'],
|
||||||
|
tab: 'Tab',
|
||||||
|
enter: 'Enter',
|
||||||
|
space: [' ', 'Spacebar'],
|
||||||
|
up: ['Up', 'ArrowUp'],
|
||||||
|
left: ['Left', 'ArrowLeft'],
|
||||||
|
right: ['Right', 'ArrowRight'],
|
||||||
|
down: ['Down', 'ArrowDown'],
|
||||||
|
delete: ['Backspace', 'Delete', 'Del']
|
||||||
|
}
|
||||||
|
const listener = ($event) => {
|
||||||
|
if (this.disable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const keyName = Object.keys(keyNames).find(key => {
|
||||||
|
const keyName = $event.key
|
||||||
|
const value = keyNames[key]
|
||||||
|
return value === keyName || (Array.isArray(value) && value.includes(keyName))
|
||||||
|
})
|
||||||
|
if (keyName) {
|
||||||
|
// 避免和其他按键事件冲突
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$emit(keyName, {})
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('keyup', listener)
|
||||||
|
this.$once('hook:beforeDestroy', () => {
|
||||||
|
document.removeEventListener('keyup', listener)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
render: () => {}
|
||||||
|
}
|
||||||
|
// #endif
|
@ -0,0 +1,930 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-datetime-picker">
|
||||||
|
<view @click="initTimePicker">
|
||||||
|
<slot>
|
||||||
|
<view class="uni-datetime-picker-timebox-pointer"
|
||||||
|
:class="{'uni-datetime-picker-disabled': disabled, 'uni-datetime-picker-timebox': border}">
|
||||||
|
<text class="uni-datetime-picker-text">{{time}}</text>
|
||||||
|
<view v-if="!time" class="uni-datetime-picker-time">
|
||||||
|
<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
<view v-if="visible" id="mask" class="uni-datetime-picker-mask" @click="tiggerTimePicker"></view>
|
||||||
|
<view v-if="visible" class="uni-datetime-picker-popup" :class="[dateShow && timeShow ? '' : 'fix-nvue-height']"
|
||||||
|
:style="fixNvueBug">
|
||||||
|
<view class="uni-title">
|
||||||
|
<text class="uni-datetime-picker-text">{{selectTimeText}}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="dateShow" class="uni-datetime-picker__container-box">
|
||||||
|
<picker-view class="uni-datetime-picker-view" :indicator-style="indicatorStyle" :value="ymd"
|
||||||
|
@change="bindDateChange">
|
||||||
|
<picker-view-column>
|
||||||
|
<view class="uni-datetime-picker-item" v-for="(item,index) in years" :key="index">
|
||||||
|
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
|
||||||
|
</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column>
|
||||||
|
<view class="uni-datetime-picker-item" v-for="(item,index) in months" :key="index">
|
||||||
|
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
|
||||||
|
</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column>
|
||||||
|
<view class="uni-datetime-picker-item" v-for="(item,index) in days" :key="index">
|
||||||
|
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
|
||||||
|
</view>
|
||||||
|
</picker-view-column>
|
||||||
|
</picker-view>
|
||||||
|
<!-- 兼容 nvue 不支持伪类 -->
|
||||||
|
<text class="uni-datetime-picker-sign sign-left">-</text>
|
||||||
|
<text class="uni-datetime-picker-sign sign-right">-</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="timeShow" class="uni-datetime-picker__container-box">
|
||||||
|
<picker-view class="uni-datetime-picker-view" :class="[hideSecond ? 'time-hide-second' : '']"
|
||||||
|
:indicator-style="indicatorStyle" :value="hms" @change="bindTimeChange">
|
||||||
|
<picker-view-column>
|
||||||
|
<view class="uni-datetime-picker-item" v-for="(item,index) in hours" :key="index">
|
||||||
|
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
|
||||||
|
</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column>
|
||||||
|
<view class="uni-datetime-picker-item" v-for="(item,index) in minutes" :key="index">
|
||||||
|
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
|
||||||
|
</view>
|
||||||
|
</picker-view-column>
|
||||||
|
<picker-view-column v-if="!hideSecond">
|
||||||
|
<view class="uni-datetime-picker-item" v-for="(item,index) in seconds" :key="index">
|
||||||
|
<text class="uni-datetime-picker-item">{{lessThanTen(item)}}</text>
|
||||||
|
</view>
|
||||||
|
</picker-view-column>
|
||||||
|
</picker-view>
|
||||||
|
<!-- 兼容 nvue 不支持伪类 -->
|
||||||
|
<text class="uni-datetime-picker-sign" :class="[hideSecond ? 'sign-center' : 'sign-left']">:</text>
|
||||||
|
<text v-if="!hideSecond" class="uni-datetime-picker-sign sign-right">:</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-datetime-picker-btn">
|
||||||
|
<view @click="clearTime">
|
||||||
|
<text class="uni-datetime-picker-btn-text">{{clearText}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="uni-datetime-picker-btn-group">
|
||||||
|
<view class="uni-datetime-picker-cancel" @click="tiggerTimePicker">
|
||||||
|
<text class="uni-datetime-picker-btn-text">{{cancelText}}</text>
|
||||||
|
</view>
|
||||||
|
<view @click="setTime">
|
||||||
|
<text class="uni-datetime-picker-btn-text">{{okText}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<!-- <keypress v-if="visible" @esc="tiggerTimePicker" @enter="setTime" /> -->
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifdef H5
|
||||||
|
import keypress from './keypress'
|
||||||
|
// #endif
|
||||||
|
import {
|
||||||
|
initVueI18n
|
||||||
|
} from '@dcloudio/uni-i18n'
|
||||||
|
import messages from './i18n/index.js'
|
||||||
|
const { t } = initVueI18n(messages)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DatetimePicker 时间选择器
|
||||||
|
* @description 可以同时选择日期和时间的选择器
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=xxx
|
||||||
|
* @property {String} type = [datetime | date | time] 显示模式
|
||||||
|
* @property {Boolean} multiple = [true|false] 是否多选
|
||||||
|
* @property {String|Number} value 默认值
|
||||||
|
* @property {String|Number} start 起始日期或时间
|
||||||
|
* @property {String|Number} end 起始日期或时间
|
||||||
|
* @property {String} return-type = [timestamp | string]
|
||||||
|
* @event {Function} change 选中发生变化触发
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'UniDatetimePicker',
|
||||||
|
components: {
|
||||||
|
// #ifdef H5
|
||||||
|
keypress
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
indicatorStyle: `height: 50px;`,
|
||||||
|
visible: false,
|
||||||
|
fixNvueBug: {},
|
||||||
|
dateShow: true,
|
||||||
|
timeShow: true,
|
||||||
|
title: '日期和时间',
|
||||||
|
// 输入框当前时间
|
||||||
|
time: '',
|
||||||
|
// 当前的年月日时分秒
|
||||||
|
year: 1920,
|
||||||
|
month: 0,
|
||||||
|
day: 0,
|
||||||
|
hour: 0,
|
||||||
|
minute: 0,
|
||||||
|
second: 0,
|
||||||
|
// 起始时间
|
||||||
|
startYear: 1920,
|
||||||
|
startMonth: 1,
|
||||||
|
startDay: 1,
|
||||||
|
startHour: 0,
|
||||||
|
startMinute: 0,
|
||||||
|
startSecond: 0,
|
||||||
|
// 结束时间
|
||||||
|
endYear: 2120,
|
||||||
|
endMonth: 12,
|
||||||
|
endDay: 31,
|
||||||
|
endHour: 23,
|
||||||
|
endMinute: 59,
|
||||||
|
endSecond: 59,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: 'datetime'
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
start: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
returnType: {
|
||||||
|
type: String,
|
||||||
|
default: 'string'
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
hideSecond: {
|
||||||
|
type: [Boolean, String],
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value: {
|
||||||
|
handler(newVal, oldVal) {
|
||||||
|
if (newVal) {
|
||||||
|
this.parseValue(this.fixIosDateFormat(newVal)) //兼容 iOS、safari 日期格式
|
||||||
|
this.initTime(false)
|
||||||
|
} else {
|
||||||
|
this.time = ''
|
||||||
|
this.parseValue(Date.now())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
handler(newValue) {
|
||||||
|
if (newValue === 'date') {
|
||||||
|
this.dateShow = true
|
||||||
|
this.timeShow = false
|
||||||
|
this.title = '日期'
|
||||||
|
} else if (newValue === 'time') {
|
||||||
|
this.dateShow = false
|
||||||
|
this.timeShow = true
|
||||||
|
this.title = '时间'
|
||||||
|
} else {
|
||||||
|
this.dateShow = true
|
||||||
|
this.timeShow = true
|
||||||
|
this.title = '日期和时间'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
start: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'start') //兼容 iOS、safari 日期格式
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
end: {
|
||||||
|
handler(newVal) {
|
||||||
|
this.parseDatetimeRange(this.fixIosDateFormat(newVal), 'end') //兼容 iOS、safari 日期格式
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
|
||||||
|
// 月、日、时、分、秒可选范围变化后,检查当前值是否在范围内,不在则当前值重置为可选范围第一项
|
||||||
|
months(newVal) {
|
||||||
|
this.checkValue('month', this.month, newVal)
|
||||||
|
},
|
||||||
|
days(newVal) {
|
||||||
|
this.checkValue('day', this.day, newVal)
|
||||||
|
},
|
||||||
|
hours(newVal) {
|
||||||
|
this.checkValue('hour', this.hour, newVal)
|
||||||
|
},
|
||||||
|
minutes(newVal) {
|
||||||
|
this.checkValue('minute', this.minute, newVal)
|
||||||
|
},
|
||||||
|
seconds(newVal) {
|
||||||
|
this.checkValue('second', this.second, newVal)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 当前年、月、日、时、分、秒选择范围
|
||||||
|
years() {
|
||||||
|
return this.getCurrentRange('year')
|
||||||
|
},
|
||||||
|
|
||||||
|
months() {
|
||||||
|
return this.getCurrentRange('month')
|
||||||
|
},
|
||||||
|
|
||||||
|
days() {
|
||||||
|
return this.getCurrentRange('day')
|
||||||
|
},
|
||||||
|
|
||||||
|
hours() {
|
||||||
|
return this.getCurrentRange('hour')
|
||||||
|
},
|
||||||
|
|
||||||
|
minutes() {
|
||||||
|
return this.getCurrentRange('minute')
|
||||||
|
},
|
||||||
|
|
||||||
|
seconds() {
|
||||||
|
return this.getCurrentRange('second')
|
||||||
|
},
|
||||||
|
|
||||||
|
// picker 当前值数组
|
||||||
|
ymd() {
|
||||||
|
return [this.year - this.minYear, this.month - this.minMonth, this.day - this.minDay]
|
||||||
|
},
|
||||||
|
hms() {
|
||||||
|
return [this.hour - this.minHour, this.minute - this.minMinute, this.second - this.minSecond]
|
||||||
|
},
|
||||||
|
|
||||||
|
// 当前 date 是 start
|
||||||
|
currentDateIsStart() {
|
||||||
|
return this.year === this.startYear && this.month === this.startMonth && this.day === this.startDay
|
||||||
|
},
|
||||||
|
|
||||||
|
// 当前 date 是 end
|
||||||
|
currentDateIsEnd() {
|
||||||
|
return this.year === this.endYear && this.month === this.endMonth && this.day === this.endDay
|
||||||
|
},
|
||||||
|
|
||||||
|
// 当前年、月、日、时、分、秒的最小值和最大值
|
||||||
|
minYear() {
|
||||||
|
return this.startYear
|
||||||
|
},
|
||||||
|
maxYear() {
|
||||||
|
return this.endYear
|
||||||
|
},
|
||||||
|
minMonth() {
|
||||||
|
if (this.year === this.startYear) {
|
||||||
|
return this.startMonth
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
maxMonth() {
|
||||||
|
if (this.year === this.endYear) {
|
||||||
|
return this.endMonth
|
||||||
|
} else {
|
||||||
|
return 12
|
||||||
|
}
|
||||||
|
},
|
||||||
|
minDay() {
|
||||||
|
if (this.year === this.startYear && this.month === this.startMonth) {
|
||||||
|
return this.startDay
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
maxDay() {
|
||||||
|
if (this.year === this.endYear && this.month === this.endMonth) {
|
||||||
|
return this.endDay
|
||||||
|
} else {
|
||||||
|
return this.daysInMonth(this.year, this.month)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
minHour() {
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
if (this.currentDateIsStart) {
|
||||||
|
return this.startHour
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.type === 'time') {
|
||||||
|
return this.startHour
|
||||||
|
}
|
||||||
|
},
|
||||||
|
maxHour() {
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
if (this.currentDateIsEnd) {
|
||||||
|
return this.endHour
|
||||||
|
} else {
|
||||||
|
return 23
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.type === 'time') {
|
||||||
|
return this.endHour
|
||||||
|
}
|
||||||
|
},
|
||||||
|
minMinute() {
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
if (this.currentDateIsStart && this.hour === this.startHour) {
|
||||||
|
return this.startMinute
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.type === 'time') {
|
||||||
|
if (this.hour === this.startHour) {
|
||||||
|
return this.startMinute
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
maxMinute() {
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
if (this.currentDateIsEnd && this.hour === this.endHour) {
|
||||||
|
return this.endMinute
|
||||||
|
} else {
|
||||||
|
return 59
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.type === 'time') {
|
||||||
|
if (this.hour === this.endHour) {
|
||||||
|
return this.endMinute
|
||||||
|
} else {
|
||||||
|
return 59
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
minSecond() {
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
if (this.currentDateIsStart && this.hour === this.startHour && this.minute === this.startMinute) {
|
||||||
|
return this.startSecond
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.type === 'time') {
|
||||||
|
if (this.hour === this.startHour && this.minute === this.startMinute) {
|
||||||
|
return this.startSecond
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
maxSecond() {
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
if (this.currentDateIsEnd && this.hour === this.endHour && this.minute === this.endMinute) {
|
||||||
|
return this.endSecond
|
||||||
|
} else {
|
||||||
|
return 59
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.type === 'time') {
|
||||||
|
if (this.hour === this.endHour && this.minute === this.endMinute) {
|
||||||
|
return this.endSecond
|
||||||
|
} else {
|
||||||
|
return 59
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* for i18n
|
||||||
|
*/
|
||||||
|
selectTimeText() {
|
||||||
|
return t("uni-datetime-picker.selectTime")
|
||||||
|
},
|
||||||
|
okText() {
|
||||||
|
return t("uni-datetime-picker.ok")
|
||||||
|
},
|
||||||
|
clearText() {
|
||||||
|
return t("uni-datetime-picker.clear")
|
||||||
|
},
|
||||||
|
cancelText() {
|
||||||
|
return t("uni-datetime-picker.cancel")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
const res = uni.getSystemInfoSync();
|
||||||
|
this.fixNvueBug = {
|
||||||
|
top: res.windowHeight / 2,
|
||||||
|
left: res.windowWidth / 2
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* @param {Object} item
|
||||||
|
* 小于 10 在前面加个 0
|
||||||
|
*/
|
||||||
|
|
||||||
|
lessThanTen(item) {
|
||||||
|
return item < 10 ? '0' + item : item
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析时分秒字符串,例如:00:00:00
|
||||||
|
* @param {String} timeString
|
||||||
|
*/
|
||||||
|
parseTimeType(timeString) {
|
||||||
|
if (timeString) {
|
||||||
|
let timeArr = timeString.split(':')
|
||||||
|
this.hour = Number(timeArr[0])
|
||||||
|
this.minute = Number(timeArr[1])
|
||||||
|
this.second = Number(timeArr[2])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析选择器初始值,类型可以是字符串、时间戳,例如:2000-10-02、'08:30:00'、 1610695109000
|
||||||
|
* @param {String | Number} datetime
|
||||||
|
*/
|
||||||
|
initPickerValue(datetime) {
|
||||||
|
let defaultValue = null
|
||||||
|
if (datetime) {
|
||||||
|
defaultValue = this.compareValueWithStartAndEnd(datetime, this.start, this.end)
|
||||||
|
} else {
|
||||||
|
defaultValue = Date.now()
|
||||||
|
defaultValue = this.compareValueWithStartAndEnd(defaultValue, this.start, this.end)
|
||||||
|
}
|
||||||
|
this.parseValue(defaultValue)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始值规则:
|
||||||
|
* - 用户设置初始值 value
|
||||||
|
* - 设置了起始时间 start、终止时间 end,并 start < value < end,初始值为 value, 否则初始值为 start
|
||||||
|
* - 只设置了起始时间 start,并 start < value,初始值为 value,否则初始值为 start
|
||||||
|
* - 只设置了终止时间 end,并 value < end,初始值为 value,否则初始值为 end
|
||||||
|
* - 无起始终止时间,则初始值为 value
|
||||||
|
* - 无初始值 value,则初始值为当前本地时间 Date.now()
|
||||||
|
* @param {Object} value
|
||||||
|
* @param {Object} dateBase
|
||||||
|
*/
|
||||||
|
compareValueWithStartAndEnd(value, start, end) {
|
||||||
|
let winner = null
|
||||||
|
value = this.superTimeStamp(value)
|
||||||
|
start = this.superTimeStamp(start)
|
||||||
|
end = this.superTimeStamp(end)
|
||||||
|
|
||||||
|
if (start && end) {
|
||||||
|
if (value < start) {
|
||||||
|
winner = new Date(start)
|
||||||
|
} else if (value > end) {
|
||||||
|
winner = new Date(end)
|
||||||
|
} else {
|
||||||
|
winner = new Date(value)
|
||||||
|
}
|
||||||
|
} else if (start && !end) {
|
||||||
|
winner = start <= value ? new Date(value) : new Date(start)
|
||||||
|
} else if (!start && end) {
|
||||||
|
winner = value <= end ? new Date(value) : new Date(end)
|
||||||
|
} else {
|
||||||
|
winner = new Date(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return winner
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转换为可比较的时间戳,接受日期、时分秒、时间戳
|
||||||
|
* @param {Object} value
|
||||||
|
*/
|
||||||
|
superTimeStamp(value) {
|
||||||
|
let dateBase = ''
|
||||||
|
if (this.type === 'time' && value && typeof value === 'string') {
|
||||||
|
const now = new Date()
|
||||||
|
const year = now.getFullYear()
|
||||||
|
const month = now.getMonth() + 1
|
||||||
|
const day = now.getDate()
|
||||||
|
dateBase = year + '/' + month + '/' + day + ' '
|
||||||
|
}
|
||||||
|
if (Number(value) && typeof value !== NaN) {
|
||||||
|
value = parseInt(value)
|
||||||
|
dateBase = 0
|
||||||
|
}
|
||||||
|
return this.createTimeStamp(dateBase + value)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析默认值 value,字符串、时间戳
|
||||||
|
* @param {Object} defaultTime
|
||||||
|
*/
|
||||||
|
parseValue(value) {
|
||||||
|
if (!value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.type === 'time' && typeof value === "string") {
|
||||||
|
this.parseTimeType(value)
|
||||||
|
} else {
|
||||||
|
let defaultDate = null
|
||||||
|
defaultDate = new Date(value)
|
||||||
|
if (this.type !== 'time') {
|
||||||
|
this.year = defaultDate.getFullYear()
|
||||||
|
this.month = defaultDate.getMonth() + 1
|
||||||
|
this.day = defaultDate.getDate()
|
||||||
|
}
|
||||||
|
if (this.type !== 'date') {
|
||||||
|
this.hour = defaultDate.getHours()
|
||||||
|
this.minute = defaultDate.getMinutes()
|
||||||
|
this.second = defaultDate.getSeconds()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.hideSecond) {
|
||||||
|
this.second = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析可选择时间范围 start、end,年月日字符串、时间戳
|
||||||
|
* @param {Object} defaultTime
|
||||||
|
*/
|
||||||
|
parseDatetimeRange(point, pointType) {
|
||||||
|
// 时间为空,则重置为初始值
|
||||||
|
if (!point) {
|
||||||
|
if (pointType === 'start') {
|
||||||
|
this.startYear = 1920
|
||||||
|
this.startMonth = 1
|
||||||
|
this.startDay = 1
|
||||||
|
this.startHour = 0
|
||||||
|
this.startMinute = 0
|
||||||
|
this.startSecond = 0
|
||||||
|
}
|
||||||
|
if (pointType === 'end') {
|
||||||
|
this.endYear = 2120
|
||||||
|
this.endMonth = 12
|
||||||
|
this.endDay = 31
|
||||||
|
this.endHour = 23
|
||||||
|
this.endMinute = 59
|
||||||
|
this.endSecond = 59
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.type === 'time') {
|
||||||
|
const pointArr = point.split(':')
|
||||||
|
this[pointType + 'Hour'] = Number(pointArr[0])
|
||||||
|
this[pointType + 'Minute'] = Number(pointArr[1])
|
||||||
|
this[pointType + 'Second'] = Number(pointArr[2])
|
||||||
|
} else {
|
||||||
|
if (!point) {
|
||||||
|
pointType === 'start' ? this.startYear = this.year - 60 : this.endYear = this.year + 60
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (Number(point) && Number(point) !== NaN) {
|
||||||
|
point = parseInt(point)
|
||||||
|
}
|
||||||
|
// datetime 的 end 没有时分秒, 则不限制
|
||||||
|
const hasTime = /[0-9]:[0-9]/
|
||||||
|
if (this.type === 'datetime' && pointType === 'end' && typeof point === 'string' && !hasTime.test(
|
||||||
|
point)) {
|
||||||
|
point = point + ' 23:59:59'
|
||||||
|
}
|
||||||
|
const pointDate = new Date(point)
|
||||||
|
this[pointType + 'Year'] = pointDate.getFullYear()
|
||||||
|
this[pointType + 'Month'] = pointDate.getMonth() + 1
|
||||||
|
this[pointType + 'Day'] = pointDate.getDate()
|
||||||
|
if (this.type === 'datetime') {
|
||||||
|
this[pointType + 'Hour'] = pointDate.getHours()
|
||||||
|
this[pointType + 'Minute'] = pointDate.getMinutes()
|
||||||
|
this[pointType + 'Second'] = pointDate.getSeconds()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取 年、月、日、时、分、秒 当前可选范围
|
||||||
|
getCurrentRange(value) {
|
||||||
|
const range = []
|
||||||
|
for (let i = this['min' + this.capitalize(value)]; i <= this['max' + this.capitalize(value)]; i++) {
|
||||||
|
range.push(i)
|
||||||
|
}
|
||||||
|
return range
|
||||||
|
},
|
||||||
|
|
||||||
|
// 字符串首字母大写
|
||||||
|
capitalize(str) {
|
||||||
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 检查当前值是否在范围内,不在则当前值重置为可选范围第一项
|
||||||
|
checkValue(name, value, values) {
|
||||||
|
if (values.indexOf(value) === -1) {
|
||||||
|
this[name] = values[0]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 每个月的实际天数
|
||||||
|
daysInMonth(year, month) { // Use 1 for January, 2 for February, etc.
|
||||||
|
return new Date(year, month, 0).getDate();
|
||||||
|
},
|
||||||
|
|
||||||
|
//兼容 iOS、safari 日期格式
|
||||||
|
fixIosDateFormat(value) {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
value = value.replace(/-/g, '/')
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成时间戳
|
||||||
|
* @param {Object} time
|
||||||
|
*/
|
||||||
|
createTimeStamp(time) {
|
||||||
|
if (!time) return
|
||||||
|
if (typeof time === "number") {
|
||||||
|
return time
|
||||||
|
} else {
|
||||||
|
time = time.replace(/-/g, '/')
|
||||||
|
if (this.type === 'date') {
|
||||||
|
time = time + ' ' + '00:00:00'
|
||||||
|
}
|
||||||
|
return Date.parse(time)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成日期或时间的字符串
|
||||||
|
*/
|
||||||
|
createDomSting() {
|
||||||
|
const yymmdd = this.year +
|
||||||
|
'-' +
|
||||||
|
this.lessThanTen(this.month) +
|
||||||
|
'-' +
|
||||||
|
this.lessThanTen(this.day)
|
||||||
|
|
||||||
|
let hhmmss = this.lessThanTen(this.hour) +
|
||||||
|
':' +
|
||||||
|
this.lessThanTen(this.minute)
|
||||||
|
|
||||||
|
if (!this.hideSecond) {
|
||||||
|
hhmmss = hhmmss + ':' + this.lessThanTen(this.second)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.type === 'date') {
|
||||||
|
return yymmdd
|
||||||
|
} else if (this.type === 'time') {
|
||||||
|
return hhmmss
|
||||||
|
} else {
|
||||||
|
return yymmdd + ' ' + hhmmss
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化返回值,并抛出 change 事件
|
||||||
|
*/
|
||||||
|
initTime(emit = true) {
|
||||||
|
this.time = this.createDomSting()
|
||||||
|
if (!emit) return
|
||||||
|
if (this.returnType === 'timestamp' && this.type !== 'time') {
|
||||||
|
this.$emit('change', this.createTimeStamp(this.time))
|
||||||
|
this.$emit('input', this.createTimeStamp(this.time))
|
||||||
|
this.$emit('update:modelValue', this.createTimeStamp(this.time))
|
||||||
|
} else {
|
||||||
|
this.$emit('change', this.time)
|
||||||
|
this.$emit('input', this.time)
|
||||||
|
this.$emit('update:modelValue', this.time)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户选择日期或时间更新 data
|
||||||
|
* @param {Object} e
|
||||||
|
*/
|
||||||
|
bindDateChange(e) {
|
||||||
|
const val = e.detail.value
|
||||||
|
this.year = this.years[val[0]]
|
||||||
|
this.month = this.months[val[1]]
|
||||||
|
this.day = this.days[val[2]]
|
||||||
|
},
|
||||||
|
bindTimeChange(e) {
|
||||||
|
const val = e.detail.value
|
||||||
|
this.hour = this.hours[val[0]]
|
||||||
|
this.minute = this.minutes[val[1]]
|
||||||
|
this.second = this.seconds[val[2]]
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化弹出层
|
||||||
|
*/
|
||||||
|
initTimePicker() {
|
||||||
|
if (this.disabled) return
|
||||||
|
const value = this.fixIosDateFormat(this.value)
|
||||||
|
this.initPickerValue(value)
|
||||||
|
this.visible = !this.visible
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 触发或关闭弹框
|
||||||
|
*/
|
||||||
|
tiggerTimePicker(e) {
|
||||||
|
this.visible = !this.visible
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户点击“清空”按钮,清空当前值
|
||||||
|
*/
|
||||||
|
clearTime() {
|
||||||
|
this.time = ''
|
||||||
|
this.$emit('change', this.time)
|
||||||
|
this.$emit('input', this.time)
|
||||||
|
this.$emit('update:modelValue', this.time)
|
||||||
|
this.tiggerTimePicker()
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户点击“确定”按钮
|
||||||
|
*/
|
||||||
|
setTime() {
|
||||||
|
this.initTime()
|
||||||
|
this.tiggerTimePicker()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$uni-primary: #007aff !default;
|
||||||
|
|
||||||
|
.uni-datetime-picker {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
/* width: 100%; */
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-view {
|
||||||
|
height: 130px;
|
||||||
|
width: 270px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-item {
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-btn {
|
||||||
|
margin-top: 60px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-btn-text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: $uni-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-btn-group {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-cancel {
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-mask {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0px;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
z-index: 998;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-popup {
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 30px;
|
||||||
|
width: 270px;
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
height: 500px;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
width: 330px;
|
||||||
|
/* #endif */
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
transition-duration: 0.3s;
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fix-nvue-height {
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
height: 330px;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-time {
|
||||||
|
color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-column {
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-timebox {
|
||||||
|
|
||||||
|
border: 1px solid #E5E5E5;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 7px 10px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-timebox-pointer {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
cursor: pointer;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.uni-datetime-picker-disabled {
|
||||||
|
opacity: 0.4;
|
||||||
|
/* #ifdef H5 */
|
||||||
|
cursor: not-allowed !important;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-text {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 50px
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker-sign {
|
||||||
|
position: absolute;
|
||||||
|
top: 53px;
|
||||||
|
/* 减掉 10px 的元素高度,兼容nvue */
|
||||||
|
color: #999;
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
font-size: 16px;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-left {
|
||||||
|
left: 86px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-right {
|
||||||
|
right: 86px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-center {
|
||||||
|
left: 135px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-datetime-picker__container-box {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-hide-second {
|
||||||
|
width: 180px;
|
||||||
|
}
|
||||||
|
</style>
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,410 @@
|
|||||||
|
class Calendar {
|
||||||
|
constructor({
|
||||||
|
date,
|
||||||
|
selected,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
range,
|
||||||
|
// multipleStatus
|
||||||
|
} = {}) {
|
||||||
|
// 当前日期
|
||||||
|
this.date = this.getDate(new Date()) // 当前初入日期
|
||||||
|
// 打点信息
|
||||||
|
this.selected = selected || [];
|
||||||
|
// 范围开始
|
||||||
|
this.startDate = startDate
|
||||||
|
// 范围结束
|
||||||
|
this.endDate = endDate
|
||||||
|
this.range = range
|
||||||
|
// 多选状态
|
||||||
|
this.cleanMultipleStatus()
|
||||||
|
// 每周日期
|
||||||
|
this.weeks = {}
|
||||||
|
// this._getWeek(this.date.fullDate)
|
||||||
|
// this.multipleStatus = multipleStatus
|
||||||
|
this.lastHover = false
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 设置日期
|
||||||
|
* @param {Object} date
|
||||||
|
*/
|
||||||
|
setDate(date) {
|
||||||
|
this.selectDate = this.getDate(date)
|
||||||
|
this._getWeek(this.selectDate.fullDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理多选状态
|
||||||
|
*/
|
||||||
|
cleanMultipleStatus() {
|
||||||
|
this.multipleStatus = {
|
||||||
|
before: '',
|
||||||
|
after: '',
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置开始日期
|
||||||
|
*/
|
||||||
|
resetSatrtDate(startDate) {
|
||||||
|
// 范围开始
|
||||||
|
this.startDate = startDate
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重置结束日期
|
||||||
|
*/
|
||||||
|
resetEndDate(endDate) {
|
||||||
|
// 范围结束
|
||||||
|
this.endDate = endDate
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取任意时间
|
||||||
|
*/
|
||||||
|
getDate(date, AddDayCount = 0, str = 'day') {
|
||||||
|
if (!date) {
|
||||||
|
date = new Date()
|
||||||
|
}
|
||||||
|
if (typeof date !== 'object') {
|
||||||
|
date = date.replace(/-/g, '/')
|
||||||
|
}
|
||||||
|
const dd = new Date(date)
|
||||||
|
switch (str) {
|
||||||
|
case 'day':
|
||||||
|
dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期
|
||||||
|
break
|
||||||
|
case 'month':
|
||||||
|
if (dd.getDate() === 31) {
|
||||||
|
dd.setDate(dd.getDate() + AddDayCount)
|
||||||
|
} else {
|
||||||
|
dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'year':
|
||||||
|
dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期
|
||||||
|
break
|
||||||
|
}
|
||||||
|
const y = dd.getFullYear()
|
||||||
|
const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0
|
||||||
|
const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0
|
||||||
|
return {
|
||||||
|
fullDate: y + '-' + m + '-' + d,
|
||||||
|
year: y,
|
||||||
|
month: m,
|
||||||
|
date: d,
|
||||||
|
day: dd.getDay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上月剩余天数
|
||||||
|
*/
|
||||||
|
_getLastMonthDays(firstDay, full) {
|
||||||
|
let dateArr = []
|
||||||
|
for (let i = firstDay; i > 0; i--) {
|
||||||
|
const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate()
|
||||||
|
dateArr.push({
|
||||||
|
date: beforeDate,
|
||||||
|
month: full.month - 1,
|
||||||
|
disable: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return dateArr
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取本月天数
|
||||||
|
*/
|
||||||
|
_currentMonthDys(dateData, full) {
|
||||||
|
let dateArr = []
|
||||||
|
let fullDate = this.date.fullDate
|
||||||
|
for (let i = 1; i <= dateData; i++) {
|
||||||
|
let isinfo = false
|
||||||
|
let nowDate = full.year + '-' + (full.month < 10 ?
|
||||||
|
full.month : full.month) + '-' + (i < 10 ?
|
||||||
|
'0' + i : i)
|
||||||
|
// 是否今天
|
||||||
|
let isDay = fullDate === nowDate
|
||||||
|
// 获取打点信息
|
||||||
|
let info = this.selected && this.selected.find((item) => {
|
||||||
|
if (this.dateEqual(nowDate, item.date)) {
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 日期禁用
|
||||||
|
let disableBefore = true
|
||||||
|
let disableAfter = true
|
||||||
|
if (this.startDate) {
|
||||||
|
// let dateCompBefore = this.dateCompare(this.startDate, fullDate)
|
||||||
|
// disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate)
|
||||||
|
disableBefore = this.dateCompare(this.startDate, nowDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.endDate) {
|
||||||
|
// let dateCompAfter = this.dateCompare(fullDate, this.endDate)
|
||||||
|
// disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate)
|
||||||
|
disableAfter = this.dateCompare(nowDate, this.endDate)
|
||||||
|
}
|
||||||
|
let multiples = this.multipleStatus.data
|
||||||
|
let checked = false
|
||||||
|
let multiplesStatus = -1
|
||||||
|
if (this.range) {
|
||||||
|
if (multiples) {
|
||||||
|
multiplesStatus = multiples.findIndex((item) => {
|
||||||
|
return this.dateEqual(item, nowDate)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (multiplesStatus !== -1) {
|
||||||
|
checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let data = {
|
||||||
|
fullDate: nowDate,
|
||||||
|
year: full.year,
|
||||||
|
date: i,
|
||||||
|
multiple: this.range ? checked : false,
|
||||||
|
beforeMultiple: this.isLogicBefore(nowDate, this.multipleStatus.before, this.multipleStatus.after),
|
||||||
|
afterMultiple: this.isLogicAfter(nowDate, this.multipleStatus.before, this.multipleStatus.after),
|
||||||
|
month: full.month,
|
||||||
|
disable: !(disableBefore && disableAfter),
|
||||||
|
isDay,
|
||||||
|
userChecked: false
|
||||||
|
}
|
||||||
|
if (info) {
|
||||||
|
data.extraInfo = info
|
||||||
|
}
|
||||||
|
|
||||||
|
dateArr.push(data)
|
||||||
|
}
|
||||||
|
return dateArr
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取下月天数
|
||||||
|
*/
|
||||||
|
_getNextMonthDays(surplus, full) {
|
||||||
|
let dateArr = []
|
||||||
|
for (let i = 1; i < surplus + 1; i++) {
|
||||||
|
dateArr.push({
|
||||||
|
date: i,
|
||||||
|
month: Number(full.month) + 1,
|
||||||
|
disable: true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return dateArr
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前日期详情
|
||||||
|
* @param {Object} date
|
||||||
|
*/
|
||||||
|
getInfo(date) {
|
||||||
|
if (!date) {
|
||||||
|
date = new Date()
|
||||||
|
}
|
||||||
|
const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate)
|
||||||
|
return dateInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较时间大小
|
||||||
|
*/
|
||||||
|
dateCompare(startDate, endDate) {
|
||||||
|
// 计算截止时间
|
||||||
|
startDate = new Date(startDate.replace('-', '/').replace('-', '/'))
|
||||||
|
// 计算详细项的截止时间
|
||||||
|
endDate = new Date(endDate.replace('-', '/').replace('-', '/'))
|
||||||
|
if (startDate <= endDate) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较时间是否相等
|
||||||
|
*/
|
||||||
|
dateEqual(before, after) {
|
||||||
|
// 计算截止时间
|
||||||
|
before = new Date(before.replace('-', '/').replace('-', '/'))
|
||||||
|
// 计算详细项的截止时间
|
||||||
|
after = new Date(after.replace('-', '/').replace('-', '/'))
|
||||||
|
if (before.getTime() - after.getTime() === 0) {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比较真实起始日期
|
||||||
|
*/
|
||||||
|
|
||||||
|
isLogicBefore(currentDay, before, after) {
|
||||||
|
let logicBefore = before
|
||||||
|
if (before && after) {
|
||||||
|
logicBefore = this.dateCompare(before, after) ? before : after
|
||||||
|
}
|
||||||
|
return this.dateEqual(logicBefore, currentDay)
|
||||||
|
}
|
||||||
|
|
||||||
|
isLogicAfter(currentDay, before, after) {
|
||||||
|
let logicAfter = after
|
||||||
|
if (before && after) {
|
||||||
|
logicAfter = this.dateCompare(before, after) ? after : before
|
||||||
|
}
|
||||||
|
return this.dateEqual(logicAfter, currentDay)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取日期范围内所有日期
|
||||||
|
* @param {Object} begin
|
||||||
|
* @param {Object} end
|
||||||
|
*/
|
||||||
|
geDateAll(begin, end) {
|
||||||
|
var arr = []
|
||||||
|
var ab = begin.split('-')
|
||||||
|
var ae = end.split('-')
|
||||||
|
var db = new Date()
|
||||||
|
db.setFullYear(ab[0], ab[1] - 1, ab[2])
|
||||||
|
var de = new Date()
|
||||||
|
de.setFullYear(ae[0], ae[1] - 1, ae[2])
|
||||||
|
var unixDb = db.getTime() - 24 * 60 * 60 * 1000
|
||||||
|
var unixDe = de.getTime() - 24 * 60 * 60 * 1000
|
||||||
|
for (var k = unixDb; k <= unixDe;) {
|
||||||
|
k = k + 24 * 60 * 60 * 1000
|
||||||
|
arr.push(this.getDate(new Date(parseInt(k))).fullDate)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取多选状态
|
||||||
|
*/
|
||||||
|
setMultiple(fullDate) {
|
||||||
|
let {
|
||||||
|
before,
|
||||||
|
after
|
||||||
|
} = this.multipleStatus
|
||||||
|
if (!this.range) return
|
||||||
|
if (before && after) {
|
||||||
|
if (!this.lastHover) {
|
||||||
|
this.lastHover = true
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.multipleStatus.before = fullDate
|
||||||
|
this.multipleStatus.after = ''
|
||||||
|
this.multipleStatus.data = []
|
||||||
|
this.multipleStatus.fulldate = ''
|
||||||
|
this.lastHover = false
|
||||||
|
} else {
|
||||||
|
if (!before) {
|
||||||
|
this.multipleStatus.before = fullDate
|
||||||
|
this.lastHover = false
|
||||||
|
} else {
|
||||||
|
this.multipleStatus.after = fullDate
|
||||||
|
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
|
||||||
|
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus
|
||||||
|
.after);
|
||||||
|
} else {
|
||||||
|
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus
|
||||||
|
.before);
|
||||||
|
}
|
||||||
|
this.lastHover = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._getWeek(fullDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 鼠标 hover 更新多选状态
|
||||||
|
*/
|
||||||
|
setHoverMultiple(fullDate) {
|
||||||
|
let {
|
||||||
|
before,
|
||||||
|
after
|
||||||
|
} = this.multipleStatus
|
||||||
|
|
||||||
|
if (!this.range) return
|
||||||
|
if (this.lastHover) return
|
||||||
|
|
||||||
|
if (!before) {
|
||||||
|
this.multipleStatus.before = fullDate
|
||||||
|
} else {
|
||||||
|
this.multipleStatus.after = fullDate
|
||||||
|
if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) {
|
||||||
|
this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after);
|
||||||
|
} else {
|
||||||
|
this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._getWeek(fullDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新默认值多选状态
|
||||||
|
*/
|
||||||
|
setDefaultMultiple(before, after) {
|
||||||
|
this.multipleStatus.before = before
|
||||||
|
this.multipleStatus.after = after
|
||||||
|
if (before && after) {
|
||||||
|
if (this.dateCompare(before, after)) {
|
||||||
|
this.multipleStatus.data = this.geDateAll(before, after);
|
||||||
|
this._getWeek(after)
|
||||||
|
} else {
|
||||||
|
this.multipleStatus.data = this.geDateAll(after, before);
|
||||||
|
this._getWeek(before)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取每周数据
|
||||||
|
* @param {Object} dateData
|
||||||
|
*/
|
||||||
|
_getWeek(dateData) {
|
||||||
|
const {
|
||||||
|
fullDate,
|
||||||
|
year,
|
||||||
|
month,
|
||||||
|
date,
|
||||||
|
day
|
||||||
|
} = this.getDate(dateData)
|
||||||
|
let firstDay = new Date(year, month - 1, 1).getDay()
|
||||||
|
let currentDay = new Date(year, month, 0).getDate()
|
||||||
|
let dates = {
|
||||||
|
lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天
|
||||||
|
currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数
|
||||||
|
nextMonthDays: [], // 下个月开始几天
|
||||||
|
weeks: []
|
||||||
|
}
|
||||||
|
let canlender = []
|
||||||
|
const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length)
|
||||||
|
dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData))
|
||||||
|
canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays)
|
||||||
|
let weeks = {}
|
||||||
|
// 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天
|
||||||
|
for (let i = 0; i < canlender.length; i++) {
|
||||||
|
if (i % 7 === 0) {
|
||||||
|
weeks[parseInt(i / 7)] = new Array(7)
|
||||||
|
}
|
||||||
|
weeks[parseInt(i / 7)][i % 7] = canlender[i]
|
||||||
|
}
|
||||||
|
this.canlender = canlender
|
||||||
|
this.weeks = weeks
|
||||||
|
}
|
||||||
|
|
||||||
|
//静态方法
|
||||||
|
// static init(date) {
|
||||||
|
// if (!this.instance) {
|
||||||
|
// this.instance = new Calendar(date);
|
||||||
|
// }
|
||||||
|
// return this.instance;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default Calendar
|
87
uni_modules/uni-datetime-picker/package.json
Normal file
87
uni_modules/uni-datetime-picker/package.json
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-datetime-picker",
|
||||||
|
"displayName": "uni-datetime-picker 日期选择器",
|
||||||
|
"version": "2.2.11",
|
||||||
|
"description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择",
|
||||||
|
"keywords": [
|
||||||
|
"uni-datetime-picker",
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"日期时间选择器",
|
||||||
|
"日期时间"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-icons"
|
||||||
|
],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "n"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
uni_modules/uni-datetime-picker/readme.md
Normal file
21
uni_modules/uni-datetime-picker/readme.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
|
||||||
|
> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护`
|
||||||
|
|
||||||
|
## DatetimePicker 时间选择器
|
||||||
|
|
||||||
|
> **组件名:uni-datetime-picker**
|
||||||
|
> 代码块: `uDatetimePicker`
|
||||||
|
|
||||||
|
|
||||||
|
该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。
|
||||||
|
|
||||||
|
若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。
|
||||||
|
|
||||||
|
**_点击 picker 默认值规则:_**
|
||||||
|
|
||||||
|
- 若设置初始值 value, 会显示在 picker 显示框中
|
||||||
|
- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
22
uni_modules/uni-icons/changelog.md
Normal file
22
uni_modules/uni-icons/changelog.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
## 1.3.5(2022-01-24)
|
||||||
|
- 优化 size 属性可以传入不带单位的字符串数值
|
||||||
|
## 1.3.4(2022-01-24)
|
||||||
|
- 优化 size 支持其他单位
|
||||||
|
## 1.3.3(2022-01-17)
|
||||||
|
- 修复 nvue 有些图标不显示的bug,兼容老版本图标
|
||||||
|
## 1.3.2(2021-12-01)
|
||||||
|
- 优化 示例可复制图标名称
|
||||||
|
## 1.3.1(2021-11-23)
|
||||||
|
- 优化 兼容旧组件 type 值
|
||||||
|
## 1.3.0(2021-11-19)
|
||||||
|
- 新增 更多图标
|
||||||
|
- 优化 自定义图标使用方式
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
|
||||||
|
## 1.1.7(2021-11-08)
|
||||||
|
## 1.2.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.1.5(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 1.1.4(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
1169
uni_modules/uni-icons/components/uni-icons/icons.js
Normal file
1169
uni_modules/uni-icons/components/uni-icons/icons.js
Normal file
File diff suppressed because it is too large
Load Diff
96
uni_modules/uni-icons/components/uni-icons/uni-icons.vue
Normal file
96
uni_modules/uni-icons/components/uni-icons/uni-icons.vue
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<!-- #ifdef APP-NVUE -->
|
||||||
|
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" @click="_onClick">{{unicode}}</text>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef APP-NVUE -->
|
||||||
|
<text :style="{ color: color, 'font-size': iconSize }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import icons from './icons.js';
|
||||||
|
const getVal = (val) => {
|
||||||
|
const reg = /^[0-9]*$/g
|
||||||
|
return (typeof val === 'number' || reg.test(val) )? val + 'px' : val;
|
||||||
|
}
|
||||||
|
// #ifdef APP-NVUE
|
||||||
|
var domModule = weex.requireModule('dom');
|
||||||
|
import iconUrl from './uniicons.ttf'
|
||||||
|
domModule.addRule('fontFace', {
|
||||||
|
'fontFamily': "uniicons",
|
||||||
|
'src': "url('"+iconUrl+"')"
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icons 图标
|
||||||
|
* @description 用于展示 icons 图标
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=28
|
||||||
|
* @property {Number} size 图标大小
|
||||||
|
* @property {String} type 图标图案,参考示例
|
||||||
|
* @property {String} color 图标颜色
|
||||||
|
* @property {String} customPrefix 自定义图标
|
||||||
|
* @event {Function} click 点击 Icon 触发事件
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'UniIcons',
|
||||||
|
emits:['click'],
|
||||||
|
props: {
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: '#333333'
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 16
|
||||||
|
},
|
||||||
|
customPrefix:{
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
icons: icons.glyphs
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
unicode(){
|
||||||
|
let code = this.icons.find(v=>v.font_class === this.type)
|
||||||
|
if(code){
|
||||||
|
return unescape(`%u${code.unicode}`)
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
},
|
||||||
|
iconSize(){
|
||||||
|
return getVal(this.size)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
_onClick() {
|
||||||
|
this.$emit('click')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
@import './uniicons.css';
|
||||||
|
@font-face {
|
||||||
|
font-family: uniicons;
|
||||||
|
src: url('./uniicons.ttf') format('truetype');
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
.uni-icons {
|
||||||
|
font-family: uniicons;
|
||||||
|
text-decoration: none;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
663
uni_modules/uni-icons/components/uni-icons/uniicons.css
Normal file
663
uni_modules/uni-icons/components/uni-icons/uniicons.css
Normal file
@ -0,0 +1,663 @@
|
|||||||
|
.uniui-color:before {
|
||||||
|
content: "\e6cf";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-wallet:before {
|
||||||
|
content: "\e6b1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-settings-filled:before {
|
||||||
|
content: "\e6ce";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-auth-filled:before {
|
||||||
|
content: "\e6cc";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-shop-filled:before {
|
||||||
|
content: "\e6cd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-staff-filled:before {
|
||||||
|
content: "\e6cb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-vip-filled:before {
|
||||||
|
content: "\e6c6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-plus-filled:before {
|
||||||
|
content: "\e6c7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-folder-add-filled:before {
|
||||||
|
content: "\e6c8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-color-filled:before {
|
||||||
|
content: "\e6c9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-tune-filled:before {
|
||||||
|
content: "\e6ca";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-calendar-filled:before {
|
||||||
|
content: "\e6c0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-notification-filled:before {
|
||||||
|
content: "\e6c1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-wallet-filled:before {
|
||||||
|
content: "\e6c2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-medal-filled:before {
|
||||||
|
content: "\e6c3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gift-filled:before {
|
||||||
|
content: "\e6c4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-fire-filled:before {
|
||||||
|
content: "\e6c5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-refreshempty:before {
|
||||||
|
content: "\e6bf";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-location-filled:before {
|
||||||
|
content: "\e6af";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-person-filled:before {
|
||||||
|
content: "\e69d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-personadd-filled:before {
|
||||||
|
content: "\e698";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-back:before {
|
||||||
|
content: "\e6b9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-forward:before {
|
||||||
|
content: "\e6ba";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-right:before {
|
||||||
|
content: "\e6bb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthinright:before {
|
||||||
|
content: "\e6bb";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-left:before {
|
||||||
|
content: "\e6bc";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthinleft:before {
|
||||||
|
content: "\e6bc";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-up:before {
|
||||||
|
content: "\e6bd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthinup:before {
|
||||||
|
content: "\e6bd";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrow-down:before {
|
||||||
|
content: "\e6be";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowthindown:before {
|
||||||
|
content: "\e6be";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-bottom:before {
|
||||||
|
content: "\e6b8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowdown:before {
|
||||||
|
content: "\e6b8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-right:before {
|
||||||
|
content: "\e6b5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowright:before {
|
||||||
|
content: "\e6b5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-top:before {
|
||||||
|
content: "\e6b6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowup:before {
|
||||||
|
content: "\e6b6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-left:before {
|
||||||
|
content: "\e6b7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-arrowleft:before {
|
||||||
|
content: "\e6b7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye:before {
|
||||||
|
content: "\e651";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye-filled:before {
|
||||||
|
content: "\e66a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye-slash:before {
|
||||||
|
content: "\e6b3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-eye-slash-filled:before {
|
||||||
|
content: "\e6b4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-info-filled:before {
|
||||||
|
content: "\e649";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-reload:before {
|
||||||
|
content: "\e6b2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-micoff-filled:before {
|
||||||
|
content: "\e6b0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map-pin-ellipse:before {
|
||||||
|
content: "\e6ac";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map-pin:before {
|
||||||
|
content: "\e6ad";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-location:before {
|
||||||
|
content: "\e6ae";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-starhalf:before {
|
||||||
|
content: "\e683";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-star:before {
|
||||||
|
content: "\e688";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-star-filled:before {
|
||||||
|
content: "\e68f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-calendar:before {
|
||||||
|
content: "\e6a0";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-fire:before {
|
||||||
|
content: "\e6a1";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-medal:before {
|
||||||
|
content: "\e6a2";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-font:before {
|
||||||
|
content: "\e6a3";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gift:before {
|
||||||
|
content: "\e6a4";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-link:before {
|
||||||
|
content: "\e6a5";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-notification:before {
|
||||||
|
content: "\e6a6";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-staff:before {
|
||||||
|
content: "\e6a7";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-vip:before {
|
||||||
|
content: "\e6a8";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-folder-add:before {
|
||||||
|
content: "\e6a9";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-tune:before {
|
||||||
|
content: "\e6aa";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-auth:before {
|
||||||
|
content: "\e6ab";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-person:before {
|
||||||
|
content: "\e699";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-email-filled:before {
|
||||||
|
content: "\e69a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-phone-filled:before {
|
||||||
|
content: "\e69b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-phone:before {
|
||||||
|
content: "\e69c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-email:before {
|
||||||
|
content: "\e69e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-personadd:before {
|
||||||
|
content: "\e69f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatboxes-filled:before {
|
||||||
|
content: "\e692";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-contact:before {
|
||||||
|
content: "\e693";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatbubble-filled:before {
|
||||||
|
content: "\e694";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-contact-filled:before {
|
||||||
|
content: "\e695";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatboxes:before {
|
||||||
|
content: "\e696";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chatbubble:before {
|
||||||
|
content: "\e697";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-upload-filled:before {
|
||||||
|
content: "\e68e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-upload:before {
|
||||||
|
content: "\e690";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-weixin:before {
|
||||||
|
content: "\e691";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-compose:before {
|
||||||
|
content: "\e67f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-qq:before {
|
||||||
|
content: "\e680";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-download-filled:before {
|
||||||
|
content: "\e681";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-pyq:before {
|
||||||
|
content: "\e682";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-sound:before {
|
||||||
|
content: "\e684";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-trash-filled:before {
|
||||||
|
content: "\e685";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-sound-filled:before {
|
||||||
|
content: "\e686";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-trash:before {
|
||||||
|
content: "\e687";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-videocam-filled:before {
|
||||||
|
content: "\e689";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-spinner-cycle:before {
|
||||||
|
content: "\e68a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-weibo:before {
|
||||||
|
content: "\e68b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-videocam:before {
|
||||||
|
content: "\e68c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-download:before {
|
||||||
|
content: "\e68d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-help:before {
|
||||||
|
content: "\e679";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-navigate-filled:before {
|
||||||
|
content: "\e67a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-plusempty:before {
|
||||||
|
content: "\e67b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-smallcircle:before {
|
||||||
|
content: "\e67c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-minus-filled:before {
|
||||||
|
content: "\e67d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-micoff:before {
|
||||||
|
content: "\e67e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-closeempty:before {
|
||||||
|
content: "\e66c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-clear:before {
|
||||||
|
content: "\e66d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-navigate:before {
|
||||||
|
content: "\e66e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-minus:before {
|
||||||
|
content: "\e66f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-image:before {
|
||||||
|
content: "\e670";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mic:before {
|
||||||
|
content: "\e671";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-paperplane:before {
|
||||||
|
content: "\e672";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-close:before {
|
||||||
|
content: "\e673";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-help-filled:before {
|
||||||
|
content: "\e674";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-paperplane-filled:before {
|
||||||
|
content: "\e675";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-plus:before {
|
||||||
|
content: "\e676";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mic-filled:before {
|
||||||
|
content: "\e677";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-image-filled:before {
|
||||||
|
content: "\e678";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-locked-filled:before {
|
||||||
|
content: "\e668";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-info:before {
|
||||||
|
content: "\e669";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-locked:before {
|
||||||
|
content: "\e66b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-camera-filled:before {
|
||||||
|
content: "\e658";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chat-filled:before {
|
||||||
|
content: "\e659";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-camera:before {
|
||||||
|
content: "\e65a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-circle:before {
|
||||||
|
content: "\e65b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-checkmarkempty:before {
|
||||||
|
content: "\e65c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-chat:before {
|
||||||
|
content: "\e65d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-circle-filled:before {
|
||||||
|
content: "\e65e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-flag:before {
|
||||||
|
content: "\e65f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-flag-filled:before {
|
||||||
|
content: "\e660";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gear-filled:before {
|
||||||
|
content: "\e661";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-home:before {
|
||||||
|
content: "\e662";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-home-filled:before {
|
||||||
|
content: "\e663";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-gear:before {
|
||||||
|
content: "\e664";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-smallcircle-filled:before {
|
||||||
|
content: "\e665";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map-filled:before {
|
||||||
|
content: "\e666";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-map:before {
|
||||||
|
content: "\e667";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-refresh-filled:before {
|
||||||
|
content: "\e656";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-refresh:before {
|
||||||
|
content: "\e657";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-upload:before {
|
||||||
|
content: "\e645";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-download-filled:before {
|
||||||
|
content: "\e646";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-download:before {
|
||||||
|
content: "\e647";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cloud-upload-filled:before {
|
||||||
|
content: "\e648";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-redo:before {
|
||||||
|
content: "\e64a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-images-filled:before {
|
||||||
|
content: "\e64b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-undo-filled:before {
|
||||||
|
content: "\e64c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-more:before {
|
||||||
|
content: "\e64d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-more-filled:before {
|
||||||
|
content: "\e64e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-undo:before {
|
||||||
|
content: "\e64f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-images:before {
|
||||||
|
content: "\e650";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-paperclip:before {
|
||||||
|
content: "\e652";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-settings:before {
|
||||||
|
content: "\e653";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-search:before {
|
||||||
|
content: "\e654";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-redo-filled:before {
|
||||||
|
content: "\e655";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-list:before {
|
||||||
|
content: "\e644";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mail-open-filled:before {
|
||||||
|
content: "\e63a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-down-filled:before {
|
||||||
|
content: "\e63c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-down:before {
|
||||||
|
content: "\e63d";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-up-filled:before {
|
||||||
|
content: "\e63e";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-hand-up:before {
|
||||||
|
content: "\e63f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-heart-filled:before {
|
||||||
|
content: "\e641";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-mail-open:before {
|
||||||
|
content: "\e643";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-heart:before {
|
||||||
|
content: "\e639";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-loop:before {
|
||||||
|
content: "\e633";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-pulldown:before {
|
||||||
|
content: "\e632";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-scan:before {
|
||||||
|
content: "\e62a";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-bars:before {
|
||||||
|
content: "\e627";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cart-filled:before {
|
||||||
|
content: "\e629";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-checkbox:before {
|
||||||
|
content: "\e62b";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-checkbox-filled:before {
|
||||||
|
content: "\e62c";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-shop:before {
|
||||||
|
content: "\e62f";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-headphones:before {
|
||||||
|
content: "\e630";
|
||||||
|
}
|
||||||
|
|
||||||
|
.uniui-cart:before {
|
||||||
|
content: "\e631";
|
||||||
|
}
|
BIN
uni_modules/uni-icons/components/uni-icons/uniicons.ttf
Normal file
BIN
uni_modules/uni-icons/components/uni-icons/uniicons.ttf
Normal file
Binary file not shown.
86
uni_modules/uni-icons/package.json
Normal file
86
uni_modules/uni-icons/package.json
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-icons",
|
||||||
|
"displayName": "uni-icons 图标",
|
||||||
|
"version": "1.3.5",
|
||||||
|
"description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"icon",
|
||||||
|
"图标"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.2.14"
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"前端组件",
|
||||||
|
"通用组件"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": ["uni-scss"],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
uni_modules/uni-icons/readme.md
Normal file
8
uni_modules/uni-icons/readme.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
## Icons 图标
|
||||||
|
> **组件名:uni-icons**
|
||||||
|
> 代码块: `uIcons`
|
||||||
|
|
||||||
|
用于展示 icons 图标 。
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
8
uni_modules/uni-scss/changelog.md
Normal file
8
uni_modules/uni-scss/changelog.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
## 1.0.3(2022-01-21)
|
||||||
|
- 优化 组件示例
|
||||||
|
## 1.0.2(2021-11-22)
|
||||||
|
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
|
||||||
|
## 1.0.1(2021-11-22)
|
||||||
|
- 修复 vue3中scss语法兼容问题
|
||||||
|
## 1.0.0(2021-11-18)
|
||||||
|
- init
|
1
uni_modules/uni-scss/index.scss
Normal file
1
uni_modules/uni-scss/index.scss
Normal file
@ -0,0 +1 @@
|
|||||||
|
@import './styles/index.scss';
|
82
uni_modules/uni-scss/package.json
Normal file
82
uni_modules/uni-scss/package.json
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-scss",
|
||||||
|
"displayName": "uni-scss 辅助样式",
|
||||||
|
"version": "1.0.3",
|
||||||
|
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
|
||||||
|
"keywords": [
|
||||||
|
"uni-scss",
|
||||||
|
"uni-ui",
|
||||||
|
"辅助样式"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"JS SDK",
|
||||||
|
"通用 SDK"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "n",
|
||||||
|
"联盟": "n"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
4
uni_modules/uni-scss/readme.md
Normal file
4
uni_modules/uni-scss/readme.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
7
uni_modules/uni-scss/styles/index.scss
Normal file
7
uni_modules/uni-scss/styles/index.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
@import './setting/_variables.scss';
|
||||||
|
@import './setting/_border.scss';
|
||||||
|
@import './setting/_color.scss';
|
||||||
|
@import './setting/_space.scss';
|
||||||
|
@import './setting/_radius.scss';
|
||||||
|
@import './setting/_text.scss';
|
||||||
|
@import './setting/_styles.scss';
|
3
uni_modules/uni-scss/styles/setting/_border.scss
Normal file
3
uni_modules/uni-scss/styles/setting/_border.scss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.uni-border {
|
||||||
|
border: 1px $uni-border-1 solid;
|
||||||
|
}
|
66
uni_modules/uni-scss/styles/setting/_color.scss
Normal file
66
uni_modules/uni-scss/styles/setting/_color.scss
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
|
||||||
|
// @mixin get-styles($k,$c) {
|
||||||
|
// @if $k == size or $k == weight{
|
||||||
|
// font-#{$k}:#{$c}
|
||||||
|
// }@else{
|
||||||
|
// #{$k}:#{$c}
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
$uni-ui-color:(
|
||||||
|
// 主色
|
||||||
|
primary: $uni-primary,
|
||||||
|
primary-disable: $uni-primary-disable,
|
||||||
|
primary-light: $uni-primary-light,
|
||||||
|
// 辅助色
|
||||||
|
success: $uni-success,
|
||||||
|
success-disable: $uni-success-disable,
|
||||||
|
success-light: $uni-success-light,
|
||||||
|
warning: $uni-warning,
|
||||||
|
warning-disable: $uni-warning-disable,
|
||||||
|
warning-light: $uni-warning-light,
|
||||||
|
error: $uni-error,
|
||||||
|
error-disable: $uni-error-disable,
|
||||||
|
error-light: $uni-error-light,
|
||||||
|
info: $uni-info,
|
||||||
|
info-disable: $uni-info-disable,
|
||||||
|
info-light: $uni-info-light,
|
||||||
|
// 中性色
|
||||||
|
main-color: $uni-main-color,
|
||||||
|
base-color: $uni-base-color,
|
||||||
|
secondary-color: $uni-secondary-color,
|
||||||
|
extra-color: $uni-extra-color,
|
||||||
|
// 背景色
|
||||||
|
bg-color: $uni-bg-color,
|
||||||
|
// 边框颜色
|
||||||
|
border-1: $uni-border-1,
|
||||||
|
border-2: $uni-border-2,
|
||||||
|
border-3: $uni-border-3,
|
||||||
|
border-4: $uni-border-4,
|
||||||
|
// 黑色
|
||||||
|
black:$uni-black,
|
||||||
|
// 白色
|
||||||
|
white:$uni-white,
|
||||||
|
// 透明
|
||||||
|
transparent:$uni-transparent
|
||||||
|
) !default;
|
||||||
|
@each $key, $child in $uni-ui-color {
|
||||||
|
.uni-#{"" + $key} {
|
||||||
|
color: $child;
|
||||||
|
}
|
||||||
|
.uni-#{"" + $key}-bg {
|
||||||
|
background-color: $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uni-shadow-sm {
|
||||||
|
box-shadow: $uni-shadow-sm;
|
||||||
|
}
|
||||||
|
.uni-shadow-base {
|
||||||
|
box-shadow: $uni-shadow-base;
|
||||||
|
}
|
||||||
|
.uni-shadow-lg {
|
||||||
|
box-shadow: $uni-shadow-lg;
|
||||||
|
}
|
||||||
|
.uni-mask {
|
||||||
|
background-color:$uni-mask;
|
||||||
|
}
|
55
uni_modules/uni-scss/styles/setting/_radius.scss
Normal file
55
uni_modules/uni-scss/styles/setting/_radius.scss
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
@mixin radius($r,$d:null ,$important: false){
|
||||||
|
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
|
||||||
|
// Key exists within the $uni-radius variable
|
||||||
|
@if (map-has-key($uni-radius, $r) and $d){
|
||||||
|
@if $d == t {
|
||||||
|
border-top-left-radius:$radius-value;
|
||||||
|
border-top-right-radius:$radius-value;
|
||||||
|
}@else if $d == r {
|
||||||
|
border-top-right-radius:$radius-value;
|
||||||
|
border-bottom-right-radius:$radius-value;
|
||||||
|
}@else if $d == b {
|
||||||
|
border-bottom-left-radius:$radius-value;
|
||||||
|
border-bottom-right-radius:$radius-value;
|
||||||
|
}@else if $d == l {
|
||||||
|
border-top-left-radius:$radius-value;
|
||||||
|
border-bottom-left-radius:$radius-value;
|
||||||
|
}@else if $d == tl {
|
||||||
|
border-top-left-radius:$radius-value;
|
||||||
|
}@else if $d == tr {
|
||||||
|
border-top-right-radius:$radius-value;
|
||||||
|
}@else if $d == br {
|
||||||
|
border-bottom-right-radius:$radius-value;
|
||||||
|
}@else if $d == bl {
|
||||||
|
border-bottom-left-radius:$radius-value;
|
||||||
|
}
|
||||||
|
}@else{
|
||||||
|
border-radius:$radius-value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $key, $child in $uni-radius {
|
||||||
|
@if($key){
|
||||||
|
.uni-radius-#{"" + $key} {
|
||||||
|
@include radius($key)
|
||||||
|
}
|
||||||
|
}@else{
|
||||||
|
.uni-radius {
|
||||||
|
@include radius($key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $direction in t, r, b, l,tl, tr, br, bl {
|
||||||
|
@each $key, $child in $uni-radius {
|
||||||
|
@if($key){
|
||||||
|
.uni-radius-#{"" + $direction}-#{"" + $key} {
|
||||||
|
@include radius($key,$direction,false)
|
||||||
|
}
|
||||||
|
}@else{
|
||||||
|
.uni-radius-#{$direction} {
|
||||||
|
@include radius($key,$direction,false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
uni_modules/uni-scss/styles/setting/_space.scss
Normal file
56
uni_modules/uni-scss/styles/setting/_space.scss
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
|
||||||
|
@mixin fn($space,$direction,$size,$n) {
|
||||||
|
@if $n {
|
||||||
|
#{$space}-#{$direction}: #{$size*$uni-space-root}px
|
||||||
|
} @else {
|
||||||
|
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin get-styles($direction,$i,$space,$n){
|
||||||
|
@if $direction == t {
|
||||||
|
@include fn($space, top,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == r {
|
||||||
|
@include fn($space, right,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == b {
|
||||||
|
@include fn($space, bottom,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == l {
|
||||||
|
@include fn($space, left,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == x {
|
||||||
|
@include fn($space, left,$i,$n);
|
||||||
|
@include fn($space, right,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == y {
|
||||||
|
@include fn($space, top,$i,$n);
|
||||||
|
@include fn($space, bottom,$i,$n);
|
||||||
|
}
|
||||||
|
@if $direction == a {
|
||||||
|
@if $n {
|
||||||
|
#{$space}:#{$i*$uni-space-root}px;
|
||||||
|
} @else {
|
||||||
|
#{$space}:#{-$i*$uni-space-root}px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $orientation in m,p {
|
||||||
|
$space: margin;
|
||||||
|
@if $orientation == m {
|
||||||
|
$space: margin;
|
||||||
|
} @else {
|
||||||
|
$space: padding;
|
||||||
|
}
|
||||||
|
@for $i from 0 through 16 {
|
||||||
|
@each $direction in t, r, b, l, x, y, a {
|
||||||
|
.uni-#{$orientation}#{$direction}-#{$i} {
|
||||||
|
@include get-styles($direction,$i,$space,true);
|
||||||
|
}
|
||||||
|
.uni-#{$orientation}#{$direction}-n#{$i} {
|
||||||
|
@include get-styles($direction,$i,$space,false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
167
uni_modules/uni-scss/styles/setting/_styles.scss
Normal file
167
uni_modules/uni-scss/styles/setting/_styles.scss
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
|
||||||
|
$-color-white:#fff;
|
||||||
|
$-color-black:#000;
|
||||||
|
@mixin base-style($color) {
|
||||||
|
color: #fff;
|
||||||
|
background-color: $color;
|
||||||
|
border-color: mix($-color-black, $color, 8%);
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
background: mix($-color-black, $color, 10%);
|
||||||
|
border-color: mix($-color-black, $color, 20%);
|
||||||
|
color: $-color-white;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin is-color($color) {
|
||||||
|
@include base-style($color);
|
||||||
|
&[loading] {
|
||||||
|
@include base-style($color);
|
||||||
|
&::before {
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&[disabled] {
|
||||||
|
&,
|
||||||
|
&[loading],
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
color: $-color-white;
|
||||||
|
border-color: mix(darken($color,10%), $-color-white);
|
||||||
|
background-color: mix($color, $-color-white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@mixin base-plain-style($color) {
|
||||||
|
color:$color;
|
||||||
|
background-color: mix($-color-white, $color, 90%);
|
||||||
|
border-color: mix($-color-white, $color, 70%);
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
background: mix($-color-white, $color, 80%);
|
||||||
|
color: $color;
|
||||||
|
outline: none;
|
||||||
|
border-color: mix($-color-white, $color, 50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin is-plain($color){
|
||||||
|
&[plain] {
|
||||||
|
@include base-plain-style($color);
|
||||||
|
&[loading] {
|
||||||
|
@include base-plain-style($color);
|
||||||
|
&::before {
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&[disabled] {
|
||||||
|
&,
|
||||||
|
&:active {
|
||||||
|
color: mix($-color-white, $color, 40%);
|
||||||
|
background-color: mix($-color-white, $color, 90%);
|
||||||
|
border-color: mix($-color-white, $color, 80%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.uni-btn {
|
||||||
|
margin: 5px;
|
||||||
|
color: #393939;
|
||||||
|
border:1px solid #ccc;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 200;
|
||||||
|
background-color: #F9F9F9;
|
||||||
|
// TODO 暂时处理边框隐藏一边的问题
|
||||||
|
overflow: visible;
|
||||||
|
&::after{
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([type]),&[type=default] {
|
||||||
|
color: #999;
|
||||||
|
&[loading] {
|
||||||
|
background: none;
|
||||||
|
&::before {
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&[disabled]{
|
||||||
|
color: mix($-color-white, #999, 60%);
|
||||||
|
&,
|
||||||
|
&[loading],
|
||||||
|
&:active {
|
||||||
|
color: mix($-color-white, #999, 60%);
|
||||||
|
background-color: mix($-color-white,$-color-black , 98%);
|
||||||
|
border-color: mix($-color-white, #999, 85%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[plain] {
|
||||||
|
color: #999;
|
||||||
|
background: none;
|
||||||
|
border-color: $uni-border-1;
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
background: none;
|
||||||
|
color: mix($-color-white, $-color-black, 80%);
|
||||||
|
border-color: mix($-color-white, $-color-black, 90%);
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
&[disabled]{
|
||||||
|
&,
|
||||||
|
&[loading],
|
||||||
|
&:active {
|
||||||
|
background: none;
|
||||||
|
color: mix($-color-white, #999, 60%);
|
||||||
|
border-color: mix($-color-white, #999, 85%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([hover-class]):active {
|
||||||
|
color: mix($-color-white, $-color-black, 50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[size=mini] {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 200;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
&.uni-btn-small {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
&.uni-btn-mini {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.uni-btn-radius {
|
||||||
|
border-radius: 999px;
|
||||||
|
}
|
||||||
|
&[type=primary] {
|
||||||
|
@include is-color($uni-primary);
|
||||||
|
@include is-plain($uni-primary)
|
||||||
|
}
|
||||||
|
&[type=success] {
|
||||||
|
@include is-color($uni-success);
|
||||||
|
@include is-plain($uni-success)
|
||||||
|
}
|
||||||
|
&[type=error] {
|
||||||
|
@include is-color($uni-error);
|
||||||
|
@include is-plain($uni-error)
|
||||||
|
}
|
||||||
|
&[type=warning] {
|
||||||
|
@include is-color($uni-warning);
|
||||||
|
@include is-plain($uni-warning)
|
||||||
|
}
|
||||||
|
&[type=info] {
|
||||||
|
@include is-color($uni-info);
|
||||||
|
@include is-plain($uni-info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
24
uni_modules/uni-scss/styles/setting/_text.scss
Normal file
24
uni_modules/uni-scss/styles/setting/_text.scss
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
@mixin get-styles($k,$c) {
|
||||||
|
@if $k == size or $k == weight{
|
||||||
|
font-#{$k}:#{$c}
|
||||||
|
}@else{
|
||||||
|
#{$k}:#{$c}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@each $key, $child in $uni-headings {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
.uni-#{$key} {
|
||||||
|
@each $k, $c in $child {
|
||||||
|
@include get-styles($k,$c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
.container .uni-#{$key} {
|
||||||
|
@each $k, $c in $child {
|
||||||
|
@include get-styles($k,$c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
146
uni_modules/uni-scss/styles/setting/_variables.scss
Normal file
146
uni_modules/uni-scss/styles/setting/_variables.scss
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
// @use "sass:math";
|
||||||
|
@import '../tools/functions.scss';
|
||||||
|
// 间距基础倍数
|
||||||
|
$uni-space-root: 2 !default;
|
||||||
|
// 边框半径默认值
|
||||||
|
$uni-radius-root:5px !default;
|
||||||
|
$uni-radius: () !default;
|
||||||
|
// 边框半径断点
|
||||||
|
$uni-radius: map-deep-merge(
|
||||||
|
(
|
||||||
|
0: 0,
|
||||||
|
// TODO 当前版本暂时不支持 sm 属性
|
||||||
|
// 'sm': math.div($uni-radius-root, 2),
|
||||||
|
null: $uni-radius-root,
|
||||||
|
'lg': $uni-radius-root * 2,
|
||||||
|
'xl': $uni-radius-root * 6,
|
||||||
|
'pill': 9999px,
|
||||||
|
'circle': 50%
|
||||||
|
),
|
||||||
|
$uni-radius
|
||||||
|
);
|
||||||
|
// 字体家族
|
||||||
|
$body-font-family: 'Roboto', sans-serif !default;
|
||||||
|
// 文本
|
||||||
|
$heading-font-family: $body-font-family !default;
|
||||||
|
$uni-headings: () !default;
|
||||||
|
$letterSpacing: -0.01562em;
|
||||||
|
$uni-headings: map-deep-merge(
|
||||||
|
(
|
||||||
|
'h1': (
|
||||||
|
size: 32px,
|
||||||
|
weight: 300,
|
||||||
|
line-height: 50px,
|
||||||
|
// letter-spacing:-0.01562em
|
||||||
|
),
|
||||||
|
'h2': (
|
||||||
|
size: 28px,
|
||||||
|
weight: 300,
|
||||||
|
line-height: 40px,
|
||||||
|
// letter-spacing: -0.00833em
|
||||||
|
),
|
||||||
|
'h3': (
|
||||||
|
size: 24px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 32px,
|
||||||
|
// letter-spacing: normal
|
||||||
|
),
|
||||||
|
'h4': (
|
||||||
|
size: 20px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 30px,
|
||||||
|
// letter-spacing: 0.00735em
|
||||||
|
),
|
||||||
|
'h5': (
|
||||||
|
size: 16px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 24px,
|
||||||
|
// letter-spacing: normal
|
||||||
|
),
|
||||||
|
'h6': (
|
||||||
|
size: 14px,
|
||||||
|
weight: 500,
|
||||||
|
line-height: 18px,
|
||||||
|
// letter-spacing: 0.0125em
|
||||||
|
),
|
||||||
|
'subtitle': (
|
||||||
|
size: 12px,
|
||||||
|
weight: 400,
|
||||||
|
line-height: 20px,
|
||||||
|
// letter-spacing: 0.00937em
|
||||||
|
),
|
||||||
|
'body': (
|
||||||
|
font-size: 14px,
|
||||||
|
font-weight: 400,
|
||||||
|
line-height: 22px,
|
||||||
|
// letter-spacing: 0.03125em
|
||||||
|
),
|
||||||
|
'caption': (
|
||||||
|
'size': 12px,
|
||||||
|
'weight': 400,
|
||||||
|
'line-height': 20px,
|
||||||
|
// 'letter-spacing': 0.03333em,
|
||||||
|
// 'text-transform': false
|
||||||
|
)
|
||||||
|
),
|
||||||
|
$uni-headings
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 主色
|
||||||
|
$uni-primary: #2979ff !default;
|
||||||
|
$uni-primary-disable:lighten($uni-primary,20%) !default;
|
||||||
|
$uni-primary-light: lighten($uni-primary,25%) !default;
|
||||||
|
|
||||||
|
// 辅助色
|
||||||
|
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||||
|
$uni-success: #18bc37 !default;
|
||||||
|
$uni-success-disable:lighten($uni-success,20%) !default;
|
||||||
|
$uni-success-light: lighten($uni-success,25%) !default;
|
||||||
|
|
||||||
|
$uni-warning: #f3a73f !default;
|
||||||
|
$uni-warning-disable:lighten($uni-warning,20%) !default;
|
||||||
|
$uni-warning-light: lighten($uni-warning,25%) !default;
|
||||||
|
|
||||||
|
$uni-error: #e43d33 !default;
|
||||||
|
$uni-error-disable:lighten($uni-error,20%) !default;
|
||||||
|
$uni-error-light: lighten($uni-error,25%) !default;
|
||||||
|
|
||||||
|
$uni-info: #8f939c !default;
|
||||||
|
$uni-info-disable:lighten($uni-info,20%) !default;
|
||||||
|
$uni-info-light: lighten($uni-info,25%) !default;
|
||||||
|
|
||||||
|
// 中性色
|
||||||
|
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||||
|
$uni-main-color: #3a3a3a !default; // 主要文字
|
||||||
|
$uni-base-color: #6a6a6a !default; // 常规文字
|
||||||
|
$uni-secondary-color: #909399 !default; // 次要文字
|
||||||
|
$uni-extra-color: #c7c7c7 !default; // 辅助说明
|
||||||
|
|
||||||
|
// 边框颜色
|
||||||
|
$uni-border-1: #F0F0F0 !default;
|
||||||
|
$uni-border-2: #EDEDED !default;
|
||||||
|
$uni-border-3: #DCDCDC !default;
|
||||||
|
$uni-border-4: #B9B9B9 !default;
|
||||||
|
|
||||||
|
// 常规色
|
||||||
|
$uni-black: #000000 !default;
|
||||||
|
$uni-white: #ffffff !default;
|
||||||
|
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
|
||||||
|
|
||||||
|
// 背景色
|
||||||
|
$uni-bg-color: #f7f7f7 !default;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-sm: 8px !default;
|
||||||
|
$uni-spacing-base: 15px !default;
|
||||||
|
$uni-spacing-lg: 30px !default;
|
||||||
|
|
||||||
|
// 阴影
|
||||||
|
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
|
||||||
|
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
|
||||||
|
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
|
||||||
|
|
||||||
|
// 蒙版
|
||||||
|
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
|
19
uni_modules/uni-scss/styles/tools/functions.scss
Normal file
19
uni_modules/uni-scss/styles/tools/functions.scss
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// 合并 map
|
||||||
|
@function map-deep-merge($parent-map, $child-map){
|
||||||
|
$result: $parent-map;
|
||||||
|
@each $key, $child in $child-map {
|
||||||
|
$parent-has-key: map-has-key($result, $key);
|
||||||
|
$parent-value: map-get($result, $key);
|
||||||
|
$parent-type: type-of($parent-value);
|
||||||
|
$child-type: type-of($child);
|
||||||
|
$parent-is-map: $parent-type == map;
|
||||||
|
$child-is-map: $child-type == map;
|
||||||
|
|
||||||
|
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
|
||||||
|
$result: map-merge($result, ( $key: $child ));
|
||||||
|
}@else {
|
||||||
|
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@return $result;
|
||||||
|
};
|
31
uni_modules/uni-scss/theme.scss
Normal file
31
uni_modules/uni-scss/theme.scss
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// 间距基础倍数
|
||||||
|
$uni-space-root: 2;
|
||||||
|
// 边框半径默认值
|
||||||
|
$uni-radius-root:5px;
|
||||||
|
// 主色
|
||||||
|
$uni-primary: #2979ff;
|
||||||
|
// 辅助色
|
||||||
|
$uni-success: #4cd964;
|
||||||
|
// 警告色
|
||||||
|
$uni-warning: #f0ad4e;
|
||||||
|
// 错误色
|
||||||
|
$uni-error: #dd524d;
|
||||||
|
// 描述色
|
||||||
|
$uni-info: #909399;
|
||||||
|
// 中性色
|
||||||
|
$uni-main-color: #303133;
|
||||||
|
$uni-base-color: #606266;
|
||||||
|
$uni-secondary-color: #909399;
|
||||||
|
$uni-extra-color: #C0C4CC;
|
||||||
|
// 背景色
|
||||||
|
$uni-bg-color: #f5f5f5;
|
||||||
|
// 边框颜色
|
||||||
|
$uni-border-1: #DCDFE6;
|
||||||
|
$uni-border-2: #E4E7ED;
|
||||||
|
$uni-border-3: #EBEEF5;
|
||||||
|
$uni-border-4: #F2F6FC;
|
||||||
|
|
||||||
|
// 常规色
|
||||||
|
$uni-black: #000000;
|
||||||
|
$uni-white: #ffffff;
|
||||||
|
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
62
uni_modules/uni-scss/variables.scss
Normal file
62
uni_modules/uni-scss/variables.scss
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
@import './styles/setting/_variables.scss';
|
||||||
|
// 间距基础倍数
|
||||||
|
$uni-space-root: 2;
|
||||||
|
// 边框半径默认值
|
||||||
|
$uni-radius-root:5px;
|
||||||
|
|
||||||
|
// 主色
|
||||||
|
$uni-primary: #2979ff;
|
||||||
|
$uni-primary-disable:mix(#fff,$uni-primary,50%);
|
||||||
|
$uni-primary-light: mix(#fff,$uni-primary,80%);
|
||||||
|
|
||||||
|
// 辅助色
|
||||||
|
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||||
|
$uni-success: #18bc37;
|
||||||
|
$uni-success-disable:mix(#fff,$uni-success,50%);
|
||||||
|
$uni-success-light: mix(#fff,$uni-success,80%);
|
||||||
|
|
||||||
|
$uni-warning: #f3a73f;
|
||||||
|
$uni-warning-disable:mix(#fff,$uni-warning,50%);
|
||||||
|
$uni-warning-light: mix(#fff,$uni-warning,80%);
|
||||||
|
|
||||||
|
$uni-error: #e43d33;
|
||||||
|
$uni-error-disable:mix(#fff,$uni-error,50%);
|
||||||
|
$uni-error-light: mix(#fff,$uni-error,80%);
|
||||||
|
|
||||||
|
$uni-info: #8f939c;
|
||||||
|
$uni-info-disable:mix(#fff,$uni-info,50%);
|
||||||
|
$uni-info-light: mix(#fff,$uni-info,80%);
|
||||||
|
|
||||||
|
// 中性色
|
||||||
|
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||||
|
$uni-main-color: #3a3a3a; // 主要文字
|
||||||
|
$uni-base-color: #6a6a6a; // 常规文字
|
||||||
|
$uni-secondary-color: #909399; // 次要文字
|
||||||
|
$uni-extra-color: #c7c7c7; // 辅助说明
|
||||||
|
|
||||||
|
// 边框颜色
|
||||||
|
$uni-border-1: #F0F0F0;
|
||||||
|
$uni-border-2: #EDEDED;
|
||||||
|
$uni-border-3: #DCDCDC;
|
||||||
|
$uni-border-4: #B9B9B9;
|
||||||
|
|
||||||
|
// 常规色
|
||||||
|
$uni-black: #000000;
|
||||||
|
$uni-white: #ffffff;
|
||||||
|
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||||
|
|
||||||
|
// 背景色
|
||||||
|
$uni-bg-color: #f7f7f7;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-sm: 8px;
|
||||||
|
$uni-spacing-base: 15px;
|
||||||
|
$uni-spacing-lg: 30px;
|
||||||
|
|
||||||
|
// 阴影
|
||||||
|
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
|
||||||
|
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
|
||||||
|
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
|
||||||
|
|
||||||
|
// 蒙版
|
||||||
|
$uni-mask: rgba($color: #000000, $alpha: 0.4);
|
23
uni_modules/uni-table/changelog.md
Normal file
23
uni_modules/uni-table/changelog.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
## 1.2.1(2022-06-06)
|
||||||
|
- 修复 微信小程序存在无使用组件的问题
|
||||||
|
## 1.2.0(2021-11-19)
|
||||||
|
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||||
|
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-table](https://uniapp.dcloud.io/component/uniui/uni-table)
|
||||||
|
## 1.1.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.0.7(2021-07-08)
|
||||||
|
- 新增 uni-th 支持 date 日期筛选范围
|
||||||
|
## 1.0.6(2021-07-05)
|
||||||
|
- 新增 uni-th 支持 range 筛选范围
|
||||||
|
## 1.0.5(2021-06-28)
|
||||||
|
- 新增 uni-th 筛选功能
|
||||||
|
## 1.0.4(2021-05-12)
|
||||||
|
- 新增 示例地址
|
||||||
|
- 修复 示例项目缺少组件的Bug
|
||||||
|
## 1.0.3(2021-04-16)
|
||||||
|
- 新增 sortable 属性,是否开启单列排序
|
||||||
|
- 优化 表格多选逻辑
|
||||||
|
## 1.0.2(2021-03-22)
|
||||||
|
- uni-tr 添加 disabled 属性,用于 type=selection 时,设置某行是否可由全选按钮控制
|
||||||
|
## 1.0.1(2021-02-05)
|
||||||
|
- 调整为uni_modules目录规范
|
455
uni_modules/uni-table/components/uni-table/uni-table.vue
Normal file
455
uni_modules/uni-table/components/uni-table/uni-table.vue
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-table-scroll" :class="{ 'table--border': border, 'border-none': !noData }">
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<table class="uni-table" border="0" cellpadding="0" cellspacing="0" :class="{ 'table--stripe': stripe }" :style="{ 'min-width': minWidth + 'px' }">
|
||||||
|
<slot></slot>
|
||||||
|
<view v-if="noData" class="uni-table-loading">
|
||||||
|
<view class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="loading" class="uni-table-mask" :class="{ 'empty-border': border }"><div class="uni-table--loader"></div></view>
|
||||||
|
</table>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef H5 -->
|
||||||
|
<view class="uni-table" :style="{ 'min-width': minWidth + 'px' }" :class="{ 'table--stripe': stripe }">
|
||||||
|
<slot></slot>
|
||||||
|
<view v-if="noData" class="uni-table-loading">
|
||||||
|
<view class="uni-table-text" :class="{ 'empty-border': border }">{{ emptyText }}</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="loading" class="uni-table-mask" :class="{ 'empty-border': border }"><div class="uni-table--loader"></div></view>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Table 表格
|
||||||
|
* @description 用于展示多条结构类似的数据
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=3270
|
||||||
|
* @property {Boolean} border 是否带有纵向边框
|
||||||
|
* @property {Boolean} stripe 是否显示斑马线
|
||||||
|
* @property {Boolean} type 是否开启多选
|
||||||
|
* @property {String} emptyText 空数据时显示的文本内容
|
||||||
|
* @property {Boolean} loading 显示加载中
|
||||||
|
* @event {Function} selection-change 开启多选时,当选择项发生变化时会触发该事件
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniTable',
|
||||||
|
options: {
|
||||||
|
virtualHost: true
|
||||||
|
},
|
||||||
|
emits:['selection-change'],
|
||||||
|
props: {
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 是否有竖线
|
||||||
|
border: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 是否显示斑马线
|
||||||
|
stripe: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 多选
|
||||||
|
type: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
// 没有更多数据
|
||||||
|
emptyText: {
|
||||||
|
type: String,
|
||||||
|
default: '没有更多数据'
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
rowKey: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
noData: true,
|
||||||
|
minWidth: 0,
|
||||||
|
multiTableHeads: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
loading(val) {},
|
||||||
|
data(newVal) {
|
||||||
|
let theadChildren = this.theadChildren
|
||||||
|
let rowspan = 1
|
||||||
|
if (this.theadChildren) {
|
||||||
|
rowspan = this.theadChildren.rowspan
|
||||||
|
}
|
||||||
|
|
||||||
|
// this.trChildren.length - rowspan
|
||||||
|
this.noData = false
|
||||||
|
// this.noData = newVal.length === 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 定义tr的实例数组
|
||||||
|
this.trChildren = []
|
||||||
|
this.thChildren = []
|
||||||
|
this.theadChildren = null
|
||||||
|
this.backData = []
|
||||||
|
this.backIndexData = []
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
isNodata() {
|
||||||
|
let theadChildren = this.theadChildren
|
||||||
|
let rowspan = 1
|
||||||
|
if (this.theadChildren) {
|
||||||
|
rowspan = this.theadChildren.rowspan
|
||||||
|
}
|
||||||
|
this.noData = this.trChildren.length - rowspan <= 0
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 选中所有
|
||||||
|
*/
|
||||||
|
selectionAll() {
|
||||||
|
let startIndex = 1
|
||||||
|
let theadChildren = this.theadChildren
|
||||||
|
if (!this.theadChildren) {
|
||||||
|
theadChildren = this.trChildren[0]
|
||||||
|
} else {
|
||||||
|
startIndex = theadChildren.rowspan - 1
|
||||||
|
}
|
||||||
|
let isHaveData = this.data && this.data.length.length > 0
|
||||||
|
theadChildren.checked = true
|
||||||
|
theadChildren.indeterminate = false
|
||||||
|
this.trChildren.forEach((item, index) => {
|
||||||
|
if (!item.disabled) {
|
||||||
|
item.checked = true
|
||||||
|
if (isHaveData && item.keyValue) {
|
||||||
|
const row = this.data.find(v => v[this.rowKey] === item.keyValue)
|
||||||
|
if (!this.backData.find(v => v[this.rowKey] === row[this.rowKey])) {
|
||||||
|
this.backData.push(row)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (index > (startIndex - 1) && this.backIndexData.indexOf(index - startIndex) === -1) {
|
||||||
|
this.backIndexData.push(index - startIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// this.backData = JSON.parse(JSON.stringify(this.data))
|
||||||
|
this.$emit('selection-change', {
|
||||||
|
detail: {
|
||||||
|
value: this.backData,
|
||||||
|
index: this.backIndexData
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中)
|
||||||
|
*/
|
||||||
|
toggleRowSelection(row, selected) {
|
||||||
|
// if (!this.theadChildren) return
|
||||||
|
row = [].concat(row)
|
||||||
|
|
||||||
|
this.trChildren.forEach((item, index) => {
|
||||||
|
// if (item.keyValue) {
|
||||||
|
|
||||||
|
const select = row.findIndex(v => {
|
||||||
|
//
|
||||||
|
if (typeof v === 'number') {
|
||||||
|
return v === index - 1
|
||||||
|
} else {
|
||||||
|
return v[this.rowKey] === item.keyValue
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let ischeck = item.checked
|
||||||
|
if (select !== -1) {
|
||||||
|
if (typeof selected === 'boolean') {
|
||||||
|
item.checked = selected
|
||||||
|
} else {
|
||||||
|
item.checked = !item.checked
|
||||||
|
}
|
||||||
|
if (ischeck !== item.checked) {
|
||||||
|
this.check(item.rowData||item, item.checked, item.rowData?item.keyValue:null, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
this.$emit('selection-change', {
|
||||||
|
detail: {
|
||||||
|
value: this.backData,
|
||||||
|
index:this.backIndexData
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于多选表格,清空用户的选择
|
||||||
|
*/
|
||||||
|
clearSelection() {
|
||||||
|
let theadChildren = this.theadChildren
|
||||||
|
if (!this.theadChildren) {
|
||||||
|
theadChildren = this.trChildren[0]
|
||||||
|
}
|
||||||
|
// if (!this.theadChildren) return
|
||||||
|
theadChildren.checked = false
|
||||||
|
theadChildren.indeterminate = false
|
||||||
|
this.trChildren.forEach(item => {
|
||||||
|
// if (item.keyValue) {
|
||||||
|
item.checked = false
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
this.backData = []
|
||||||
|
this.backIndexData = []
|
||||||
|
this.$emit('selection-change', {
|
||||||
|
detail: {
|
||||||
|
value: [],
|
||||||
|
index: []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 用于多选表格,切换所有行的选中状态
|
||||||
|
*/
|
||||||
|
toggleAllSelection() {
|
||||||
|
let list = []
|
||||||
|
let startIndex = 1
|
||||||
|
let theadChildren = this.theadChildren
|
||||||
|
if (!this.theadChildren) {
|
||||||
|
theadChildren = this.trChildren[0]
|
||||||
|
} else {
|
||||||
|
startIndex = theadChildren.rowspan - 1
|
||||||
|
}
|
||||||
|
this.trChildren.forEach((item, index) => {
|
||||||
|
if (!item.disabled) {
|
||||||
|
if (index > (startIndex - 1) ) {
|
||||||
|
list.push(index-startIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.toggleRowSelection(list)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 选中\取消选中
|
||||||
|
* @param {Object} child
|
||||||
|
* @param {Object} check
|
||||||
|
* @param {Object} rowValue
|
||||||
|
*/
|
||||||
|
check(child, check, keyValue, emit) {
|
||||||
|
let theadChildren = this.theadChildren
|
||||||
|
if (!this.theadChildren) {
|
||||||
|
theadChildren = this.trChildren[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
let childDomIndex = this.trChildren.findIndex((item, index) => child === item)
|
||||||
|
if(childDomIndex < 0){
|
||||||
|
childDomIndex = this.data.findIndex(v=>v[this.rowKey] === keyValue) + 1
|
||||||
|
}
|
||||||
|
const dataLen = this.trChildren.filter(v => !v.disabled && v.keyValue).length
|
||||||
|
if (childDomIndex === 0) {
|
||||||
|
check ? this.selectionAll() : this.clearSelection()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check) {
|
||||||
|
if (keyValue) {
|
||||||
|
this.backData.push(child)
|
||||||
|
}
|
||||||
|
this.backIndexData.push(childDomIndex - 1)
|
||||||
|
} else {
|
||||||
|
const index = this.backData.findIndex(v => v[this.rowKey] === keyValue)
|
||||||
|
const idx = this.backIndexData.findIndex(item => item === childDomIndex - 1)
|
||||||
|
if (keyValue) {
|
||||||
|
this.backData.splice(index, 1)
|
||||||
|
}
|
||||||
|
this.backIndexData.splice(idx, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
const domCheckAll = this.trChildren.find((item, index) => index > 0 && !item.checked && !item.disabled)
|
||||||
|
if (!domCheckAll) {
|
||||||
|
theadChildren.indeterminate = false
|
||||||
|
theadChildren.checked = true
|
||||||
|
} else {
|
||||||
|
theadChildren.indeterminate = true
|
||||||
|
theadChildren.checked = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.backIndexData.length === 0) {
|
||||||
|
theadChildren.indeterminate = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!emit) {
|
||||||
|
this.$emit('selection-change', {
|
||||||
|
detail: {
|
||||||
|
value: this.backData,
|
||||||
|
index: this.backIndexData
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$border-color: #ebeef5;
|
||||||
|
|
||||||
|
.uni-table-scroll {
|
||||||
|
width: 100%;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
overflow-x: auto;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-table {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 5px;
|
||||||
|
// box-shadow: 0px 0px 3px 1px rgba(0, 0, 0, 0.1);
|
||||||
|
background-color: #fff;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: table;
|
||||||
|
overflow-x: auto;
|
||||||
|
::v-deep .uni-table-tr:nth-child(n + 2) {
|
||||||
|
&:hover {
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep .uni-table-thead {
|
||||||
|
.uni-table-tr {
|
||||||
|
// background-color: #f5f7fa;
|
||||||
|
&:hover {
|
||||||
|
background-color:#fafafa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table--border {
|
||||||
|
border: 1px $border-color solid;
|
||||||
|
border-right: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-none {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
border-bottom: none;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.table--stripe {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
::v-deep .uni-table-tr:nth-child(2n + 3) {
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格加载、无数据样式 */
|
||||||
|
.uni-table-loading {
|
||||||
|
position: relative;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: table-row;
|
||||||
|
/* #endif */
|
||||||
|
height: 50px;
|
||||||
|
line-height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.empty-border {
|
||||||
|
border-right: 1px $border-color solid;
|
||||||
|
}
|
||||||
|
.uni-table-text {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
left: 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-table-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: rgba(255, 255, 255, 0.8);
|
||||||
|
z-index: 99;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
margin: auto;
|
||||||
|
transition: all 0.5s;
|
||||||
|
/* #endif */
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-table--loader {
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border: 2px solid #aaa;
|
||||||
|
// border-bottom-color: transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
animation: 2s uni-table--loader linear infinite;
|
||||||
|
/* #endif */
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes uni-table--loader {
|
||||||
|
0% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
10% {
|
||||||
|
border-left-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
20% {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
30% {
|
||||||
|
border-right-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
40% {
|
||||||
|
border-top-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
border-top-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
70% {
|
||||||
|
border-left-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
80% {
|
||||||
|
border-bottom-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
90% {
|
||||||
|
border-right-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: rotate(-360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
29
uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
Normal file
29
uni_modules/uni-table/components/uni-tbody/uni-tbody.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<tbody>
|
||||||
|
<slot></slot>
|
||||||
|
</tbody>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef H5 -->
|
||||||
|
<view><slot></slot></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'uniBody',
|
||||||
|
options: {
|
||||||
|
virtualHost: true
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {},
|
||||||
|
methods: {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
90
uni_modules/uni-table/components/uni-td/uni-td.vue
Normal file
90
uni_modules/uni-table/components/uni-td/uni-td.vue
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<template>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<td class="uni-table-td" :rowspan="rowspan" :colspan="colspan" :class="{'table--border':border}" :style="{width:width + 'px','text-align':align}">
|
||||||
|
<slot></slot>
|
||||||
|
</td>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef H5 -->
|
||||||
|
<!-- :class="{'table--border':border}" -->
|
||||||
|
<view class="uni-table-td" :class="{'table--border':border}" :style="{width:width + 'px','text-align':align}">
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* Td 单元格
|
||||||
|
* @description 表格中的标准单元格组件
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=3270
|
||||||
|
* @property {Number} align = [left|center|right] 单元格对齐方式
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniTd',
|
||||||
|
options: {
|
||||||
|
virtualHost: true
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
width: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
align: {
|
||||||
|
type: String,
|
||||||
|
default: 'left'
|
||||||
|
},
|
||||||
|
rowspan: {
|
||||||
|
type: [Number,String],
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
colspan: {
|
||||||
|
type: [Number,String],
|
||||||
|
default: 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
border: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.root = this.getTable()
|
||||||
|
this.border = this.root.border
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* 获取父元素实例
|
||||||
|
*/
|
||||||
|
getTable() {
|
||||||
|
let parent = this.$parent;
|
||||||
|
let parentName = parent.$options.name;
|
||||||
|
while (parentName !== 'uniTable') {
|
||||||
|
parent = parent.$parent;
|
||||||
|
if (!parent) return false;
|
||||||
|
parentName = parent.$options.name;
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$border-color:#EBEEF5;
|
||||||
|
|
||||||
|
.uni-table-td {
|
||||||
|
display: table-cell;
|
||||||
|
padding: 8px 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
border-bottom: 1px $border-color solid;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #606266;
|
||||||
|
line-height: 23px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table--border {
|
||||||
|
border-right: 1px $border-color solid;
|
||||||
|
}
|
||||||
|
</style>
|
503
uni_modules/uni-table/components/uni-th/filter-dropdown.vue
Normal file
503
uni_modules/uni-table/components/uni-th/filter-dropdown.vue
Normal file
@ -0,0 +1,503 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-filter-dropdown">
|
||||||
|
<view class="dropdown-btn" @click="onDropdown">
|
||||||
|
<view class="icon-select" :class="{active: canReset}" v-if="isSelect || isRange"></view>
|
||||||
|
<view class="icon-search" :class="{active: canReset}" v-if="isSearch">
|
||||||
|
<view class="icon-search-0"></view>
|
||||||
|
<view class="icon-search-1"></view>
|
||||||
|
</view>
|
||||||
|
<view class="icon-calendar" :class="{active: canReset}" v-if="isDate">
|
||||||
|
<view class="icon-calendar-0"></view>
|
||||||
|
<view class="icon-calendar-1"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="uni-dropdown-cover" v-if="isOpened" @click="handleClose"></view>
|
||||||
|
<view class="dropdown-popup dropdown-popup-right" v-if="isOpened" @click.stop>
|
||||||
|
<!-- select-->
|
||||||
|
<view v-if="isSelect" class="list">
|
||||||
|
<label class="flex-r a-i-c list-item" v-for="(item,index) in dataList" :key="index"
|
||||||
|
@click="onItemClick($event, index)">
|
||||||
|
<check-box class="check" :checked="item.checked" />
|
||||||
|
<view class="checklist-content">
|
||||||
|
<text class="checklist-text" :style="item.styleIconText">{{item[map.text]}}</text>
|
||||||
|
</view>
|
||||||
|
</label>
|
||||||
|
</view>
|
||||||
|
<view v-if="isSelect" class="flex-r opera-area">
|
||||||
|
<view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSelectReset">
|
||||||
|
{{resource.reset}}</view>
|
||||||
|
<view class="flex-f btn btn-submit" @click="handleSelectSubmit">{{resource.submit}}</view>
|
||||||
|
</view>
|
||||||
|
<!-- search -->
|
||||||
|
<view v-if="isSearch" class="search-area">
|
||||||
|
<input class="search-input" v-model="filterValue" />
|
||||||
|
</view>
|
||||||
|
<view v-if="isSearch" class="flex-r opera-area">
|
||||||
|
<view class="flex-f btn btn-submit" @click="handleSearchSubmit">{{resource.search}}</view>
|
||||||
|
<view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleSearchReset">
|
||||||
|
{{resource.reset}}</view>
|
||||||
|
</view>
|
||||||
|
<!-- range -->
|
||||||
|
<view v-if="isRange">
|
||||||
|
<view class="input-label">{{resource.gt}}</view>
|
||||||
|
<input class="input" v-model="gtValue" />
|
||||||
|
<view class="input-label">{{resource.lt}}</view>
|
||||||
|
<input class="input" v-model="ltValue" />
|
||||||
|
</view>
|
||||||
|
<view v-if="isRange" class="flex-r opera-area">
|
||||||
|
<view class="flex-f btn btn-default" :class="{disable: !canReset}" @click="handleRangeReset">
|
||||||
|
{{resource.reset}}</view>
|
||||||
|
<view class="flex-f btn btn-submit" @click="handleRangeSubmit">{{resource.submit}}</view>
|
||||||
|
</view>
|
||||||
|
<!-- date -->
|
||||||
|
<view v-if="isDate">
|
||||||
|
<uni-datetime-picker ref="datetimepicker" :value="dateRange" type="datetimerange" return-type="timestamp" @change="datetimechange" @maskClick="timepickerclose">
|
||||||
|
<view></view>
|
||||||
|
</uni-datetime-picker>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import checkBox from '../uni-tr/table-checkbox.vue'
|
||||||
|
|
||||||
|
const resource = {
|
||||||
|
"reset": "重置",
|
||||||
|
"search": "搜索",
|
||||||
|
"submit": "确定",
|
||||||
|
"filter": "筛选",
|
||||||
|
"gt": "大于等于",
|
||||||
|
"lt": "小于等于",
|
||||||
|
"date": "日期范围"
|
||||||
|
}
|
||||||
|
|
||||||
|
const DropdownType = {
|
||||||
|
Select: "select",
|
||||||
|
Search: "search",
|
||||||
|
Range: "range",
|
||||||
|
Date: "date",
|
||||||
|
Timestamp: "timestamp"
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'FilterDropdown',
|
||||||
|
emits:['change'],
|
||||||
|
components: {
|
||||||
|
checkBox
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
virtualHost: true
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
filterType: {
|
||||||
|
type: String,
|
||||||
|
default: DropdownType.Select
|
||||||
|
},
|
||||||
|
filterData: {
|
||||||
|
type: Array,
|
||||||
|
default () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: 'default'
|
||||||
|
},
|
||||||
|
map: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {
|
||||||
|
text: 'text',
|
||||||
|
value: 'value'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
canReset() {
|
||||||
|
if (this.isSearch) {
|
||||||
|
return this.filterValue.length > 0
|
||||||
|
}
|
||||||
|
if (this.isSelect) {
|
||||||
|
return this.checkedValues.length > 0
|
||||||
|
}
|
||||||
|
if (this.isRange) {
|
||||||
|
return (this.gtValue.length > 0 && this.ltValue.length > 0)
|
||||||
|
}
|
||||||
|
if (this.isDate) {
|
||||||
|
return this.dateSelect.length > 0
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
},
|
||||||
|
isSelect() {
|
||||||
|
return this.filterType === DropdownType.Select
|
||||||
|
},
|
||||||
|
isSearch() {
|
||||||
|
return this.filterType === DropdownType.Search
|
||||||
|
},
|
||||||
|
isRange() {
|
||||||
|
return this.filterType === DropdownType.Range
|
||||||
|
},
|
||||||
|
isDate() {
|
||||||
|
return (this.filterType === DropdownType.Date || this.filterType === DropdownType.Timestamp)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
filterData(newVal) {
|
||||||
|
this._copyFilters()
|
||||||
|
},
|
||||||
|
indeterminate(newVal) {
|
||||||
|
this.isIndeterminate = newVal
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
resource,
|
||||||
|
enabled: true,
|
||||||
|
isOpened: false,
|
||||||
|
dataList: [],
|
||||||
|
filterValue: '',
|
||||||
|
checkedValues: [],
|
||||||
|
gtValue: '',
|
||||||
|
ltValue: '',
|
||||||
|
dateRange: [],
|
||||||
|
dateSelect: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this._copyFilters()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
_copyFilters() {
|
||||||
|
let dl = JSON.parse(JSON.stringify(this.filterData))
|
||||||
|
for (let i = 0; i < dl.length; i++) {
|
||||||
|
if (dl[i].checked === undefined) {
|
||||||
|
dl[i].checked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.dataList = dl
|
||||||
|
},
|
||||||
|
openPopup() {
|
||||||
|
this.isOpened = true
|
||||||
|
if (this.isDate) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (!this.dateRange.length) {
|
||||||
|
this.resetDate()
|
||||||
|
}
|
||||||
|
this.$refs.datetimepicker.show()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
closePopup() {
|
||||||
|
this.isOpened = false
|
||||||
|
},
|
||||||
|
handleClose(e) {
|
||||||
|
this.closePopup()
|
||||||
|
},
|
||||||
|
resetDate() {
|
||||||
|
let date = new Date()
|
||||||
|
let dateText = date.toISOString().split('T')[0]
|
||||||
|
this.dateRange = [dateText + ' 0:00:00', dateText + ' 23:59:59']
|
||||||
|
},
|
||||||
|
onDropdown(e) {
|
||||||
|
this.openPopup()
|
||||||
|
},
|
||||||
|
onItemClick(e, index) {
|
||||||
|
let items = this.dataList
|
||||||
|
let listItem = items[index]
|
||||||
|
if (listItem.checked === undefined) {
|
||||||
|
items[index].checked = true
|
||||||
|
} else {
|
||||||
|
items[index].checked = !listItem.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
let checkvalues = []
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
const item = items[i]
|
||||||
|
if (item.checked) {
|
||||||
|
checkvalues.push(item.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.checkedValues = checkvalues
|
||||||
|
},
|
||||||
|
datetimechange(e) {
|
||||||
|
this.closePopup()
|
||||||
|
this.dateRange = e
|
||||||
|
this.dateSelect = e
|
||||||
|
this.$emit('change', {
|
||||||
|
filterType: this.filterType,
|
||||||
|
filter: e
|
||||||
|
})
|
||||||
|
},
|
||||||
|
timepickerclose(e) {
|
||||||
|
this.closePopup()
|
||||||
|
},
|
||||||
|
handleSelectSubmit() {
|
||||||
|
this.closePopup()
|
||||||
|
this.$emit('change', {
|
||||||
|
filterType: this.filterType,
|
||||||
|
filter: this.checkedValues
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSelectReset() {
|
||||||
|
if (!this.canReset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var items = this.dataList
|
||||||
|
for (let i = 0; i < items.length; i++) {
|
||||||
|
let item = items[i]
|
||||||
|
this.$set(item, 'checked', false)
|
||||||
|
}
|
||||||
|
this.checkedValues = []
|
||||||
|
this.handleSelectSubmit()
|
||||||
|
},
|
||||||
|
handleSearchSubmit() {
|
||||||
|
this.closePopup()
|
||||||
|
this.$emit('change', {
|
||||||
|
filterType: this.filterType,
|
||||||
|
filter: this.filterValue
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSearchReset() {
|
||||||
|
if (!this.canReset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.filterValue = ''
|
||||||
|
this.handleSearchSubmit()
|
||||||
|
},
|
||||||
|
handleRangeSubmit(isReset) {
|
||||||
|
this.closePopup()
|
||||||
|
this.$emit('change', {
|
||||||
|
filterType: this.filterType,
|
||||||
|
filter: isReset === true ? [] : [parseInt(this.gtValue), parseInt(this.ltValue)]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleRangeReset() {
|
||||||
|
if (!this.canReset) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.gtValue = ''
|
||||||
|
this.ltValue = ''
|
||||||
|
this.handleRangeSubmit(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.flex-r {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-f {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.a-i-c {
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.j-c-c {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-select {
|
||||||
|
width: 14px;
|
||||||
|
height: 16px;
|
||||||
|
border: solid 6px transparent;
|
||||||
|
border-top: solid 6px #ddd;
|
||||||
|
border-bottom: none;
|
||||||
|
background-color: #ddd;
|
||||||
|
background-clip: content-box;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-select.active {
|
||||||
|
background-color: #1890ff;
|
||||||
|
border-top-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search {
|
||||||
|
width: 12px;
|
||||||
|
height: 16px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search-0 {
|
||||||
|
border: 2px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
width: 7px;
|
||||||
|
height: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search-1 {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 0;
|
||||||
|
width: 1px;
|
||||||
|
height: 7px;
|
||||||
|
background-color: #ddd;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search.active .icon-search-0 {
|
||||||
|
border-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-search.active .icon-search-1 {
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-calendar {
|
||||||
|
color: #ddd;
|
||||||
|
width: 14px;
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-calendar-0 {
|
||||||
|
height: 4px;
|
||||||
|
margin-top: 3px;
|
||||||
|
margin-bottom: 1px;
|
||||||
|
background-color: #ddd;
|
||||||
|
border-radius: 2px 2px 1px 1px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.icon-calendar-0:before, .icon-calendar-0:after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: -3px;
|
||||||
|
width: 4px;
|
||||||
|
height: 3px;
|
||||||
|
border-radius: 1px;
|
||||||
|
background-color: #ddd;
|
||||||
|
}
|
||||||
|
.icon-calendar-0:before {
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
.icon-calendar-0:after {
|
||||||
|
right: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-calendar-1 {
|
||||||
|
height: 9px;
|
||||||
|
background-color: #ddd;
|
||||||
|
border-radius: 1px 1px 2px 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-calendar.active {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-calendar.active .icon-calendar-0,
|
||||||
|
.icon-calendar.active .icon-calendar-1,
|
||||||
|
.icon-calendar.active .icon-calendar-0:before,
|
||||||
|
.icon-calendar.active .icon-calendar-0:after {
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-filter-dropdown {
|
||||||
|
position: relative;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-popup {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 3px 6px -4px #0000001f, 0 6px 16px #00000014, 0 9px 28px 8px #0000000d;
|
||||||
|
min-width: 150px;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-popup-left {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-popup-right {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-dropdown-cover {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: transparent;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
margin-top: 5px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item {
|
||||||
|
padding: 5px 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-item:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.check {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-area {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
font-size: 12px;
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
min-width: 150px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-label {
|
||||||
|
margin: 10px 10px 5px 10px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
font-size: 12px;
|
||||||
|
border: 1px solid #f0f0f0;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
min-width: 150px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opera-area {
|
||||||
|
cursor: default;
|
||||||
|
border-top: 1px solid #ddd;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.opera-area .btn {
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 5px;
|
||||||
|
padding: 4px 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default.disable {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-submit {
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
278
uni_modules/uni-table/components/uni-th/uni-th.vue
Normal file
278
uni_modules/uni-table/components/uni-th/uni-th.vue
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
<template>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<th :rowspan="rowspan" :colspan="colspan" class="uni-table-th" :class="{ 'table--border': border }" :style="{ width: customWidth + 'px', 'text-align': align }">
|
||||||
|
<view class="uni-table-th-row">
|
||||||
|
<view class="uni-table-th-content" :style="{ 'justify-content': contentAlign }" @click="sort">
|
||||||
|
<slot></slot>
|
||||||
|
<view v-if="sortable" class="arrow-box">
|
||||||
|
<text class="arrow up" :class="{ active: ascending }" @click.stop="ascendingFn"></text>
|
||||||
|
<text class="arrow down" :class="{ active: descending }" @click.stop="descendingFn"></text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<dropdown v-if="filterType || filterData.length" :filterData="filterData" :filterType="filterType" @change="ondropdown"></dropdown>
|
||||||
|
</view>
|
||||||
|
</th>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef H5 -->
|
||||||
|
<view class="uni-table-th" :class="{ 'table--border': border }" :style="{ width: customWidth + 'px', 'text-align': align }"><slot></slot></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifdef H5
|
||||||
|
import dropdown from './filter-dropdown.vue'
|
||||||
|
// #endif
|
||||||
|
/**
|
||||||
|
* Th 表头
|
||||||
|
* @description 表格内的表头单元格组件
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=3270
|
||||||
|
* @property {Number | String} width 单元格宽度(支持纯数字、携带单位px或rpx)
|
||||||
|
* @property {Boolean} sortable 是否启用排序
|
||||||
|
* @property {Number} align = [left|center|right] 单元格对齐方式
|
||||||
|
* @value left 单元格文字左侧对齐
|
||||||
|
* @value center 单元格文字居中
|
||||||
|
* @value right 单元格文字右侧对齐
|
||||||
|
* @property {Array} filterData 筛选数据
|
||||||
|
* @property {String} filterType [search|select] 筛选类型
|
||||||
|
* @value search 关键字搜素
|
||||||
|
* @value select 条件选择
|
||||||
|
* @event {Function} sort-change 排序触发事件
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniTh',
|
||||||
|
options: {
|
||||||
|
virtualHost: true
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
// #ifdef H5
|
||||||
|
dropdown
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
emits:['sort-change','filter-change'],
|
||||||
|
props: {
|
||||||
|
width: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
align: {
|
||||||
|
type: String,
|
||||||
|
default: 'left'
|
||||||
|
},
|
||||||
|
rowspan: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
colspan: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
sortable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
filterType: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
filterData: {
|
||||||
|
type: Array,
|
||||||
|
default () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
border: false,
|
||||||
|
ascending: false,
|
||||||
|
descending: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
// 根据props中的width属性 自动匹配当前th的宽度(px)
|
||||||
|
customWidth(){
|
||||||
|
if(typeof this.width === 'number'){
|
||||||
|
return this.width
|
||||||
|
} else if(typeof this.width === 'string') {
|
||||||
|
let regexHaveUnitPx = new RegExp(/^[1-9][0-9]*px$/g)
|
||||||
|
let regexHaveUnitRpx = new RegExp(/^[1-9][0-9]*rpx$/g)
|
||||||
|
let regexHaveNotUnit = new RegExp(/^[1-9][0-9]*$/g)
|
||||||
|
if (this.width.match(regexHaveUnitPx) !== null) { // 携带了 px
|
||||||
|
return this.width.replace('px', '')
|
||||||
|
} else if (this.width.match(regexHaveUnitRpx) !== null) { // 携带了 rpx
|
||||||
|
let numberRpx = Number(this.width.replace('rpx', ''))
|
||||||
|
let widthCoe = uni.getSystemInfoSync().screenWidth / 750
|
||||||
|
return Math.round(numberRpx * widthCoe)
|
||||||
|
} else if (this.width.match(regexHaveNotUnit) !== null) { // 未携带 rpx或px 的纯数字 String
|
||||||
|
return this.width
|
||||||
|
} else { // 不符合格式
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentAlign() {
|
||||||
|
let align = 'left'
|
||||||
|
switch (this.align) {
|
||||||
|
case 'left':
|
||||||
|
align = 'flex-start'
|
||||||
|
break
|
||||||
|
case 'center':
|
||||||
|
align = 'center'
|
||||||
|
break
|
||||||
|
case 'right':
|
||||||
|
align = 'flex-end'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return align
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.root = this.getTable('uniTable')
|
||||||
|
this.rootTr = this.getTable('uniTr')
|
||||||
|
this.rootTr.minWidthUpdate(this.customWidth ? this.customWidth : 140)
|
||||||
|
this.border = this.root.border
|
||||||
|
this.root.thChildren.push(this)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
sort() {
|
||||||
|
if (!this.sortable) return
|
||||||
|
this.clearOther()
|
||||||
|
if (!this.ascending && !this.descending) {
|
||||||
|
this.ascending = true
|
||||||
|
this.$emit('sort-change', { order: 'ascending' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.ascending && !this.descending) {
|
||||||
|
this.ascending = false
|
||||||
|
this.descending = true
|
||||||
|
this.$emit('sort-change', { order: 'descending' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.ascending && this.descending) {
|
||||||
|
this.ascending = false
|
||||||
|
this.descending = false
|
||||||
|
this.$emit('sort-change', { order: null })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ascendingFn() {
|
||||||
|
this.clearOther()
|
||||||
|
this.ascending = !this.ascending
|
||||||
|
this.descending = false
|
||||||
|
this.$emit('sort-change', { order: this.ascending ? 'ascending' : null })
|
||||||
|
},
|
||||||
|
descendingFn() {
|
||||||
|
this.clearOther()
|
||||||
|
this.descending = !this.descending
|
||||||
|
this.ascending = false
|
||||||
|
this.$emit('sort-change', { order: this.descending ? 'descending' : null })
|
||||||
|
},
|
||||||
|
clearOther() {
|
||||||
|
this.root.thChildren.map(item => {
|
||||||
|
if (item !== this) {
|
||||||
|
item.ascending = false
|
||||||
|
item.descending = false
|
||||||
|
}
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ondropdown(e) {
|
||||||
|
this.$emit("filter-change", e)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取父元素实例
|
||||||
|
*/
|
||||||
|
getTable(name) {
|
||||||
|
let parent = this.$parent
|
||||||
|
let parentName = parent.$options.name
|
||||||
|
while (parentName !== name) {
|
||||||
|
parent = parent.$parent
|
||||||
|
if (!parent) return false
|
||||||
|
parentName = parent.$options.name
|
||||||
|
}
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$border-color: #ebeef5;
|
||||||
|
|
||||||
|
.uni-table-th {
|
||||||
|
padding: 12px 10px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: table-cell;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #909399;
|
||||||
|
border-bottom: 1px $border-color solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-table-th-row {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: flex;
|
||||||
|
/* #endif */
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table--border {
|
||||||
|
border-right: 1px $border-color solid;
|
||||||
|
}
|
||||||
|
.uni-table-th-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.arrow-box {
|
||||||
|
}
|
||||||
|
.arrow {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 10px;
|
||||||
|
height: 8px;
|
||||||
|
// border: 1px red solid;
|
||||||
|
left: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.down {
|
||||||
|
top: 3px;
|
||||||
|
::after {
|
||||||
|
content: '';
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
top: -5px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
::after {
|
||||||
|
background-color: #007aff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.up {
|
||||||
|
::after {
|
||||||
|
content: '';
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
position: absolute;
|
||||||
|
left: 2px;
|
||||||
|
top: 5px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
background-color: #ccc;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
::after {
|
||||||
|
background-color: #007aff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
129
uni_modules/uni-table/components/uni-thead/uni-thead.vue
Normal file
129
uni_modules/uni-table/components/uni-thead/uni-thead.vue
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<template>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<thead class="uni-table-thead">
|
||||||
|
<tr class="uni-table-tr">
|
||||||
|
<th :rowspan="rowspan" colspan="1" class="checkbox" :class="{ 'tr-table--border': border }">
|
||||||
|
<table-checkbox :indeterminate="indeterminate" :checked="checked" @checkboxSelected="checkboxSelected"></table-checkbox>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<slot></slot>
|
||||||
|
</thead>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef H5 -->
|
||||||
|
<view class="uni-table-thead"><slot></slot></view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import tableCheckbox from '../uni-tr/table-checkbox.vue'
|
||||||
|
export default {
|
||||||
|
name: 'uniThead',
|
||||||
|
components: {
|
||||||
|
tableCheckbox
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
virtualHost: true
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
border: false,
|
||||||
|
selection: false,
|
||||||
|
rowspan: 1,
|
||||||
|
indeterminate: false,
|
||||||
|
checked: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.root = this.getTable()
|
||||||
|
// #ifdef H5
|
||||||
|
this.root.theadChildren = this
|
||||||
|
// #endif
|
||||||
|
this.border = this.root.border
|
||||||
|
this.selection = this.root.type
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
init(self) {
|
||||||
|
this.rowspan++
|
||||||
|
},
|
||||||
|
checkboxSelected(e) {
|
||||||
|
this.indeterminate = false
|
||||||
|
const backIndexData = this.root.backIndexData
|
||||||
|
const data = this.root.trChildren.filter(v => !v.disabled && v.keyValue)
|
||||||
|
if (backIndexData.length === data.length) {
|
||||||
|
this.checked = false
|
||||||
|
this.root.clearSelection()
|
||||||
|
} else {
|
||||||
|
this.checked = true
|
||||||
|
this.root.selectionAll()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取父元素实例
|
||||||
|
*/
|
||||||
|
getTable(name = 'uniTable') {
|
||||||
|
let parent = this.$parent
|
||||||
|
let parentName = parent.$options.name
|
||||||
|
while (parentName !== name) {
|
||||||
|
parent = parent.$parent
|
||||||
|
if (!parent) return false
|
||||||
|
parentName = parent.$options.name
|
||||||
|
}
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$border-color: #ebeef5;
|
||||||
|
|
||||||
|
.uni-table-thead {
|
||||||
|
display: table-header-group;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uni-table-tr {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: table-row;
|
||||||
|
transition: all 0.3s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
border: 1px red solid;
|
||||||
|
background-color: #fafafa;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
padding: 0 8px;
|
||||||
|
width: 26px;
|
||||||
|
padding-left: 12px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
/* #endif */
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
border-bottom: 1px $border-color solid;
|
||||||
|
font-size: 14px;
|
||||||
|
// text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tr-table--border {
|
||||||
|
border-right: 1px $border-color solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
.uni-table-tr {
|
||||||
|
::v-deep .uni-table-th {
|
||||||
|
&.table--border:last-child {
|
||||||
|
// border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-table-td {
|
||||||
|
&.table--border:last-child {
|
||||||
|
// border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
</style>
|
179
uni_modules/uni-table/components/uni-tr/table-checkbox.vue
Normal file
179
uni_modules/uni-table/components/uni-tr/table-checkbox.vue
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
<template>
|
||||||
|
<view class="uni-table-checkbox" @click="selected">
|
||||||
|
<view v-if="!indeterminate" class="checkbox__inner" :class="{'is-checked':isChecked,'is-disable':isDisabled}">
|
||||||
|
<view class="checkbox__inner-icon"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="checkbox__inner checkbox--indeterminate">
|
||||||
|
<view class="checkbox__inner-icon"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'TableCheckbox',
|
||||||
|
emits:['checkboxSelected'],
|
||||||
|
props: {
|
||||||
|
indeterminate: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
checked: {
|
||||||
|
type: [Boolean,String],
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
index: {
|
||||||
|
type: Number,
|
||||||
|
default: -1
|
||||||
|
},
|
||||||
|
cellData: {
|
||||||
|
type: Object,
|
||||||
|
default () {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch:{
|
||||||
|
checked(newVal){
|
||||||
|
if(typeof this.checked === 'boolean'){
|
||||||
|
this.isChecked = newVal
|
||||||
|
}else{
|
||||||
|
this.isChecked = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
indeterminate(newVal){
|
||||||
|
this.isIndeterminate = newVal
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isChecked: false,
|
||||||
|
isDisabled: false,
|
||||||
|
isIndeterminate:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if(typeof this.checked === 'boolean'){
|
||||||
|
this.isChecked = this.checked
|
||||||
|
}
|
||||||
|
this.isDisabled = this.disabled
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
selected() {
|
||||||
|
if (this.isDisabled) return
|
||||||
|
this.isIndeterminate = false
|
||||||
|
this.isChecked = !this.isChecked
|
||||||
|
this.$emit('checkboxSelected', {
|
||||||
|
checked: this.isChecked,
|
||||||
|
data: this.cellData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$checked-color: #007aff;
|
||||||
|
$border-color: #DCDFE6;
|
||||||
|
$disable:0.4;
|
||||||
|
|
||||||
|
.uni-table-checkbox {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
margin: 5px 0;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
// 多选样式
|
||||||
|
.checkbox__inner {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
flex-shrink: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
position: relative;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border: 1px solid $border-color;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: #fff;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
.checkbox__inner-icon {
|
||||||
|
position: absolute;
|
||||||
|
/* #ifdef APP-NVUE */
|
||||||
|
top: 2px;
|
||||||
|
/* #endif */
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
top: 2px;
|
||||||
|
/* #endif */
|
||||||
|
left: 5px;
|
||||||
|
height: 7px;
|
||||||
|
width: 3px;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
border-left: 0;
|
||||||
|
border-top: 0;
|
||||||
|
opacity: 0;
|
||||||
|
transform-origin: center;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.checkbox--indeterminate {
|
||||||
|
border-color: $checked-color;
|
||||||
|
background-color: $checked-color;
|
||||||
|
|
||||||
|
.checkbox__inner-icon {
|
||||||
|
position: absolute;
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotate(0deg);
|
||||||
|
height: 2px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0;
|
||||||
|
width: auto;
|
||||||
|
border: none;
|
||||||
|
border-radius: 2px;
|
||||||
|
transform: scale(0.5);
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover{
|
||||||
|
border-color: $checked-color;
|
||||||
|
}
|
||||||
|
// 禁用
|
||||||
|
&.is-disable {
|
||||||
|
/* #ifdef H5 */
|
||||||
|
cursor: not-allowed;
|
||||||
|
/* #endif */
|
||||||
|
background-color: #F2F6FC;
|
||||||
|
border-color: $border-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中
|
||||||
|
&.is-checked {
|
||||||
|
border-color: $checked-color;
|
||||||
|
background-color: $checked-color;
|
||||||
|
|
||||||
|
.checkbox__inner-icon {
|
||||||
|
opacity: 1;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 选中禁用
|
||||||
|
&.is-disable {
|
||||||
|
opacity: $disable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
171
uni_modules/uni-table/components/uni-tr/uni-tr.vue
Normal file
171
uni_modules/uni-table/components/uni-tr/uni-tr.vue
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
<template>
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<tr class="uni-table-tr">
|
||||||
|
<th v-if="selection === 'selection' && ishead" class="checkbox" :class="{ 'tr-table--border': border }">
|
||||||
|
<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled" @checkboxSelected="checkboxSelected"></table-checkbox>
|
||||||
|
</th>
|
||||||
|
<slot></slot>
|
||||||
|
<!-- <uni-th class="th-fixed">123</uni-th> -->
|
||||||
|
</tr>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef H5 -->
|
||||||
|
<view class="uni-table-tr">
|
||||||
|
<view v-if="selection === 'selection' " class="checkbox" :class="{ 'tr-table--border': border }">
|
||||||
|
<table-checkbox :checked="checked" :indeterminate="indeterminate" :disabled="disabled" @checkboxSelected="checkboxSelected"></table-checkbox>
|
||||||
|
</view>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import tableCheckbox from './table-checkbox.vue'
|
||||||
|
/**
|
||||||
|
* Tr 表格行组件
|
||||||
|
* @description 表格行组件 仅包含 th,td 组件
|
||||||
|
* @tutorial https://ext.dcloud.net.cn/plugin?id=
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'uniTr',
|
||||||
|
components: { tableCheckbox },
|
||||||
|
props: {
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
keyValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
virtualHost: true
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: false,
|
||||||
|
border: false,
|
||||||
|
selection: false,
|
||||||
|
widthThArr: [],
|
||||||
|
ishead: true,
|
||||||
|
checked: false,
|
||||||
|
indeterminate:false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.root = this.getTable()
|
||||||
|
this.head = this.getTable('uniThead')
|
||||||
|
if (this.head) {
|
||||||
|
this.ishead = false
|
||||||
|
this.head.init(this)
|
||||||
|
}
|
||||||
|
this.border = this.root.border
|
||||||
|
this.selection = this.root.type
|
||||||
|
this.root.trChildren.push(this)
|
||||||
|
const rowData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
|
||||||
|
if(rowData){
|
||||||
|
this.rowData = rowData
|
||||||
|
}
|
||||||
|
this.root.isNodata()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.widthThArr.length > 0) {
|
||||||
|
const selectionWidth = this.selection === 'selection' ? 50 : 0
|
||||||
|
this.root.minWidth = this.widthThArr.reduce((a, b) => Number(a) + Number(b)) + selectionWidth
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// #ifndef VUE3
|
||||||
|
destroyed() {
|
||||||
|
const index = this.root.trChildren.findIndex(i => i === this)
|
||||||
|
this.root.trChildren.splice(index, 1)
|
||||||
|
this.root.isNodata()
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
// #ifdef VUE3
|
||||||
|
unmounted() {
|
||||||
|
const index = this.root.trChildren.findIndex(i => i === this)
|
||||||
|
this.root.trChildren.splice(index, 1)
|
||||||
|
this.root.isNodata()
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
methods: {
|
||||||
|
minWidthUpdate(width) {
|
||||||
|
this.widthThArr.push(width)
|
||||||
|
},
|
||||||
|
// 选中
|
||||||
|
checkboxSelected(e) {
|
||||||
|
let rootData = this.root.data.find(v => v[this.root.rowKey] === this.keyValue)
|
||||||
|
this.checked = e.checked
|
||||||
|
this.root.check(rootData||this, e.checked,rootData? this.keyValue:null)
|
||||||
|
},
|
||||||
|
change(e) {
|
||||||
|
this.root.trChildren.forEach(item => {
|
||||||
|
if (item === this) {
|
||||||
|
this.root.check(this, e.detail.value.length > 0 ? true : false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取父元素实例
|
||||||
|
*/
|
||||||
|
getTable(name = 'uniTable') {
|
||||||
|
let parent = this.$parent
|
||||||
|
let parentName = parent.$options.name
|
||||||
|
while (parentName !== name) {
|
||||||
|
parent = parent.$parent
|
||||||
|
if (!parent) return false
|
||||||
|
parentName = parent.$options.name
|
||||||
|
}
|
||||||
|
return parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
$border-color: #ebeef5;
|
||||||
|
|
||||||
|
.uni-table-tr {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: table-row;
|
||||||
|
transition: all 0.3s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
/* #endif */
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
padding: 0 8px;
|
||||||
|
width: 26px;
|
||||||
|
padding-left: 12px;
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
/* #endif */
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
border-bottom: 1px $border-color solid;
|
||||||
|
font-size: 14px;
|
||||||
|
// text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tr-table--border {
|
||||||
|
border-right: 1px $border-color solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
.uni-table-tr {
|
||||||
|
::v-deep .uni-table-th {
|
||||||
|
&.table--border:last-child {
|
||||||
|
// border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-table-td {
|
||||||
|
&.table--border:last-child {
|
||||||
|
// border-right: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* #endif */
|
||||||
|
</style>
|
9
uni_modules/uni-table/i18n/en.json
Normal file
9
uni_modules/uni-table/i18n/en.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"filter-dropdown.reset": "Reset",
|
||||||
|
"filter-dropdown.search": "Search",
|
||||||
|
"filter-dropdown.submit": "Submit",
|
||||||
|
"filter-dropdown.filter": "Filter",
|
||||||
|
"filter-dropdown.gt": "Greater or equal to",
|
||||||
|
"filter-dropdown.lt": "Less than or equal to",
|
||||||
|
"filter-dropdown.date": "Date"
|
||||||
|
}
|
9
uni_modules/uni-table/i18n/es.json
Normal file
9
uni_modules/uni-table/i18n/es.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"filter-dropdown.reset": "Reiniciar",
|
||||||
|
"filter-dropdown.search": "Búsqueda",
|
||||||
|
"filter-dropdown.submit": "Entregar",
|
||||||
|
"filter-dropdown.filter": "Filtrar",
|
||||||
|
"filter-dropdown.gt": "Mayor o igual a",
|
||||||
|
"filter-dropdown.lt": "Menos que o igual a",
|
||||||
|
"filter-dropdown.date": "Fecha"
|
||||||
|
}
|
9
uni_modules/uni-table/i18n/fr.json
Normal file
9
uni_modules/uni-table/i18n/fr.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"filter-dropdown.reset": "Réinitialiser",
|
||||||
|
"filter-dropdown.search": "Chercher",
|
||||||
|
"filter-dropdown.submit": "Soumettre",
|
||||||
|
"filter-dropdown.filter": "Filtre",
|
||||||
|
"filter-dropdown.gt": "Supérieur ou égal à",
|
||||||
|
"filter-dropdown.lt": "Inférieur ou égal à",
|
||||||
|
"filter-dropdown.date": "Date"
|
||||||
|
}
|
12
uni_modules/uni-table/i18n/index.js
Normal file
12
uni_modules/uni-table/i18n/index.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import en from './en.json'
|
||||||
|
import es from './es.json'
|
||||||
|
import fr from './fr.json'
|
||||||
|
import zhHans from './zh-Hans.json'
|
||||||
|
import zhHant from './zh-Hant.json'
|
||||||
|
export default {
|
||||||
|
en,
|
||||||
|
es,
|
||||||
|
fr,
|
||||||
|
'zh-Hans': zhHans,
|
||||||
|
'zh-Hant': zhHant
|
||||||
|
}
|
9
uni_modules/uni-table/i18n/zh-Hans.json
Normal file
9
uni_modules/uni-table/i18n/zh-Hans.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"filter-dropdown.reset": "重置",
|
||||||
|
"filter-dropdown.search": "搜索",
|
||||||
|
"filter-dropdown.submit": "确定",
|
||||||
|
"filter-dropdown.filter": "筛选",
|
||||||
|
"filter-dropdown.gt": "大于等于",
|
||||||
|
"filter-dropdown.lt": "小于等于",
|
||||||
|
"filter-dropdown.date": "日期范围"
|
||||||
|
}
|
9
uni_modules/uni-table/i18n/zh-Hant.json
Normal file
9
uni_modules/uni-table/i18n/zh-Hant.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"filter-dropdown.reset": "重置",
|
||||||
|
"filter-dropdown.search": "搜索",
|
||||||
|
"filter-dropdown.submit": "確定",
|
||||||
|
"filter-dropdown.filter": "篩選",
|
||||||
|
"filter-dropdown.gt": "大於等於",
|
||||||
|
"filter-dropdown.lt": "小於等於",
|
||||||
|
"filter-dropdown.date": "日期範圍"
|
||||||
|
}
|
86
uni_modules/uni-table/package.json
Normal file
86
uni_modules/uni-table/package.json
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-table",
|
||||||
|
"displayName": "uni-table 表格",
|
||||||
|
"version": "1.2.1",
|
||||||
|
"description": "表格组件,多用于展示多条结构类似的数据,如",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"table",
|
||||||
|
"表格"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"前端组件",
|
||||||
|
"通用组件"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": ["uni-scss","uni-datetime-picker"],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "n"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "n",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "n",
|
||||||
|
"联盟": "n"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
13
uni_modules/uni-table/readme.md
Normal file
13
uni_modules/uni-table/readme.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## Table 表单
|
||||||
|
> 组件名:``uni-table``,代码块: `uTable`。
|
||||||
|
|
||||||
|
用于展示多条结构类似的数据
|
||||||
|
|
||||||
|
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-table)
|
||||||
|
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
14
utils/openAiConfig.js
Normal file
14
utils/openAiConfig.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
// OpenAI API Key
|
||||||
|
export const OPENAI_API_KEY = "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";
|
||||||
|
// 对话模型 目前只有高于3.5以上才支持上下文对话
|
||||||
|
export const GPT_MODEL = "gpt-3.5-turbo";
|
||||||
|
// 指定降低重复单词出现概率的程度,范围是0到1,越高表示越避免重复。
|
||||||
|
export const FREQUENCY_PENALTY = 0;
|
||||||
|
// 指定要生成的最大单词数,不能超过2048
|
||||||
|
export const MAX_TOKENS = 1000;
|
||||||
|
// 指定降低重复话题出现概率的程度,范围是0到1,越高表示越避免重复。
|
||||||
|
export const PRESENCE_PENALTY = 0;
|
||||||
|
// 指定生成文本的随机性,范围是0到2,越高表示越多样化和创造性,越低表示越保守和确定性。
|
||||||
|
export const TEMPERATURE = 1;
|
||||||
|
// 指定在每个步骤中保留概率最高的单词的比例,范围是0到1,与temperature类似,但更加灵活和稳健。
|
||||||
|
export const TOP_P = 1;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user